1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 /* 28 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved 29 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved 30 * 31 * The original version of this source code and documentation is copyrighted 32 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These 33 * materials are provided under terms of a License Agreement between Taligent 34 * and Sun. This technology is protected by multiple US and International 35 * patents. This notice and attribution to Taligent may not be removed. 36 * Taligent is a registered trademark of Taligent, Inc. 37 * 38 */ 39 40 package java.text; 41 42 import java.io.IOException; 43 import java.io.ObjectInputStream; 44 import java.io.ObjectOutputStream; 45 import java.io.ObjectStreamField; 46 import java.math.BigDecimal; 47 import java.math.BigInteger; 48 import java.math.RoundingMode; 49 import java.util.Currency; 50 import java.util.Locale; 51 import java.util.concurrent.ConcurrentHashMap; 52 import java.util.concurrent.ConcurrentMap; 53 import java.util.concurrent.atomic.AtomicInteger; 54 import java.util.concurrent.atomic.AtomicLong; 55 import libcore.icu.LocaleData; 56 57 import android.icu.math.MathContext; 58 59 /** 60 * <code>DecimalFormat</code> is a concrete subclass of 61 * <code>NumberFormat</code> that formats decimal numbers. It has a variety of 62 * features designed to make it possible to parse and format numbers in any 63 * locale, including support for Western, Arabic, and Indic digits. It also 64 * supports different kinds of numbers, including integers (123), fixed-point 65 * numbers (123.4), scientific notation (1.23E4), percentages (12%), and 66 * currency amounts ($123). All of these can be localized. 67 * 68 * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the 69 * default locale, call one of <code>NumberFormat</code>'s factory methods, such 70 * as <code>getInstance()</code>. In general, do not call the 71 * <code>DecimalFormat</code> constructors directly, since the 72 * <code>NumberFormat</code> factory methods may return subclasses other than 73 * <code>DecimalFormat</code>. If you need to customize the format object, do 74 * something like this: 75 * 76 * <blockquote><pre> 77 * NumberFormat f = NumberFormat.getInstance(loc); 78 * if (f instanceof DecimalFormat) { 79 * ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true); 80 * } 81 * </pre></blockquote> 82 * 83 * <p>A <code>DecimalFormat</code> comprises a <em>pattern</em> and a set of 84 * <em>symbols</em>. The pattern may be set directly using 85 * <code>applyPattern()</code>, or indirectly using the API methods. The 86 * symbols are stored in a <code>DecimalFormatSymbols</code> object. When using 87 * the <code>NumberFormat</code> factory methods, the pattern and symbols are 88 * read from localized <code>ResourceBundle</code>s. 89 * 90 * <h3>Patterns</h3> 91 * 92 * <code>DecimalFormat</code> patterns have the following syntax: 93 * <blockquote><pre> 94 * <i>Pattern:</i> 95 * <i>PositivePattern</i> 96 * <i>PositivePattern</i> ; <i>NegativePattern</i> 97 * <i>PositivePattern:</i> 98 * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i> 99 * <i>NegativePattern:</i> 100 * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i> 101 * <i>Prefix:</i> 102 * any Unicode characters except \uFFFE, \uFFFF, and special characters 103 * <i>Suffix:</i> 104 * any Unicode characters except \uFFFE, \uFFFF, and special characters 105 * <i>Number:</i> 106 * <i>Integer</i> <i>Exponent<sub>opt</sub></i> 107 * <i>Integer</i> . <i>Fraction</i> <i>Exponent<sub>opt</sub></i> 108 * <i>Integer:</i> 109 * <i>MinimumInteger</i> 110 * # 111 * # <i>Integer</i> 112 * # , <i>Integer</i> 113 * <i>MinimumInteger:</i> 114 * 0 115 * 0 <i>MinimumInteger</i> 116 * 0 , <i>MinimumInteger</i> 117 * <i>Fraction:</i> 118 * <i>MinimumFraction<sub>opt</sub></i> <i>OptionalFraction<sub>opt</sub></i> 119 * <i>MinimumFraction:</i> 120 * 0 <i>MinimumFraction<sub>opt</sub></i> 121 * <i>OptionalFraction:</i> 122 * # <i>OptionalFraction<sub>opt</sub></i> 123 * <i>Exponent:</i> 124 * E <i>MinimumExponent</i> 125 * <i>MinimumExponent:</i> 126 * 0 <i>MinimumExponent<sub>opt</sub></i> 127 * </pre></blockquote> 128 * 129 * <p>A <code>DecimalFormat</code> pattern contains a positive and negative 130 * subpattern, for example, <code>"#,##0.00;(#,##0.00)"</code>. Each 131 * subpattern has a prefix, numeric part, and suffix. The negative subpattern 132 * is optional; if absent, then the positive subpattern prefixed with the 133 * localized minus sign (<code>'-'</code> in most locales) is used as the 134 * negative subpattern. That is, <code>"0.00"</code> alone is equivalent to 135 * <code>"0.00;-0.00"</code>. If there is an explicit negative subpattern, it 136 * serves only to specify the negative prefix and suffix; the number of digits, 137 * minimal digits, and other characteristics are all the same as the positive 138 * pattern. That means that <code>"#,##0.0#;(#)"</code> produces precisely 139 * the same behavior as <code>"#,##0.0#;(#,##0.0#)"</code>. 140 * 141 * <p>The prefixes, suffixes, and various symbols used for infinity, digits, 142 * thousands separators, decimal separators, etc. may be set to arbitrary 143 * values, and they will appear properly during formatting. However, care must 144 * be taken that the symbols and strings do not conflict, or parsing will be 145 * unreliable. For example, either the positive and negative prefixes or the 146 * suffixes must be distinct for <code>DecimalFormat.parse()</code> to be able 147 * to distinguish positive from negative values. (If they are identical, then 148 * <code>DecimalFormat</code> will behave as if no negative subpattern was 149 * specified.) Another example is that the decimal separator and thousands 150 * separator should be distinct characters, or parsing will be impossible. 151 * 152 * <p>The grouping separator is commonly used for thousands, but in some 153 * countries it separates ten-thousands. The grouping size is a constant number 154 * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for 155 * 1,0000,0000. If you supply a pattern with multiple grouping characters, the 156 * interval between the last one and the end of the integer is the one that is 157 * used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> == 158 * <code>"##,####,####"</code>. 159 * 160 * <h4>Special Pattern Characters</h4> 161 * 162 * <p>Many characters in a pattern are taken literally; they are matched during 163 * parsing and output unchanged during formatting. Special characters, on the 164 * other hand, stand for other characters, strings, or classes of characters. 165 * They must be quoted, unless noted otherwise, if they are to appear in the 166 * prefix or suffix as literals. 167 * 168 * <p>The characters listed here are used in non-localized patterns. Localized 169 * patterns use the corresponding characters taken from this formatter's 170 * <code>DecimalFormatSymbols</code> object instead, and these characters lose 171 * their special status. Two exceptions are the currency sign and quote, which 172 * are not localized. 173 * 174 * <blockquote> 175 * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol, 176 * location, localized, and meaning."> 177 * <tr style="background-color: rgb(204, 204, 255);"> 178 * <th align=left>Symbol 179 * <th align=left>Location 180 * <th align=left>Localized? 181 * <th align=left>Meaning 182 * <tr valign=top> 183 * <td><code>0</code> 184 * <td>Number 185 * <td>Yes 186 * <td>Digit 187 * <tr style="vertical-align: top; background-color: rgb(238, 238, 255);"> 188 * <td><code>#</code> 189 * <td>Number 190 * <td>Yes 191 * <td>Digit, zero shows as absent 192 * <tr valign=top> 193 * <td><code>.</code> 194 * <td>Number 195 * <td>Yes 196 * <td>Decimal separator or monetary decimal separator 197 * <tr style="vertical-align: top; background-color: rgb(238, 238, 255);"> 198 * <td><code>-</code> 199 * <td>Number 200 * <td>Yes 201 * <td>Minus sign 202 * <tr valign=top> 203 * <td><code>,</code> 204 * <td>Number 205 * <td>Yes 206 * <td>Grouping separator 207 * <tr style="vertical-align: top; background-color: rgb(238, 238, 255);"> 208 * <td><code>E</code> 209 * <td>Number 210 * <td>Yes 211 * <td>Separates mantissa and exponent in scientific notation. 212 * <em>Need not be quoted in prefix or suffix.</em> 213 * <tr valign=top> 214 * <td><code>;</code> 215 * <td>Subpattern boundary 216 * <td>Yes 217 * <td>Separates positive and negative subpatterns 218 * <tr style="vertical-align: top; background-color: rgb(238, 238, 255);"> 219 * <td><code>%</code> 220 * <td>Prefix or suffix 221 * <td>Yes 222 * <td>Multiply by 100 and show as percentage 223 * <tr valign=top> 224 * <td><code>\u2030</code> 225 * <td>Prefix or suffix 226 * <td>Yes 227 * <td>Multiply by 1000 and show as per mille value 228 * <tr style="vertical-align: top; background-color: rgb(238, 238, 255);"> 229 * <td><code>¤</code> (<code>\u00A4</code>) 230 * <td>Prefix or suffix 231 * <td>No 232 * <td>Currency sign, replaced by currency symbol. If 233 * doubled, replaced by international currency symbol. 234 * If present in a pattern, the monetary decimal separator 235 * is used instead of the decimal separator. 236 * <tr valign=top> 237 * <td><code>'</code> 238 * <td>Prefix or suffix 239 * <td>No 240 * <td>Used to quote special characters in a prefix or suffix, 241 * for example, <code>"'#'#"</code> formats 123 to 242 * <code>"#123"</code>. To create a single quote 243 * itself, use two in a row: <code>"# o''clock"</code>. 244 * </table> 245 * </blockquote> 246 * 247 * <h4>Scientific Notation</h4> 248 * 249 * <p>Numbers in scientific notation are expressed as the product of a mantissa 250 * and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3. The 251 * mantissa is often in the range 1.0 ≤ x {@literal <} 10.0, but it need not 252 * be. 253 * <code>DecimalFormat</code> can be instructed to format and parse scientific 254 * notation <em>only via a pattern</em>; there is currently no factory method 255 * that creates a scientific notation format. In a pattern, the exponent 256 * character immediately followed by one or more digit characters indicates 257 * scientific notation. Example: <code>"0.###E0"</code> formats the number 258 * 1234 as <code>"1.234E3"</code>. 259 * 260 * <ul> 261 * <li>The number of digit characters after the exponent character gives the 262 * minimum exponent digit count. There is no maximum. Negative exponents are 263 * formatted using the localized minus sign, <em>not</em> the prefix and suffix 264 * from the pattern. This allows patterns such as <code>"0.###E0 m/s"</code>. 265 * 266 * <li>The minimum and maximum number of integer digits are interpreted 267 * together: 268 * 269 * <ul> 270 * <li>If the maximum number of integer digits is greater than their minimum number 271 * and greater than 1, it forces the exponent to be a multiple of the maximum 272 * number of integer digits, and the minimum number of integer digits to be 273 * interpreted as 1. The most common use of this is to generate 274 * <em>engineering notation</em>, in which the exponent is a multiple of three, 275 * e.g., <code>"##0.#####E0"</code>. Using this pattern, the number 12345 276 * formats to <code>"12.345E3"</code>, and 123456 formats to 277 * <code>"123.456E3"</code>. 278 * 279 * <li>Otherwise, the minimum number of integer digits is achieved by adjusting the 280 * exponent. Example: 0.00123 formatted with <code>"00.###E0"</code> yields 281 * <code>"12.3E-4"</code>. 282 * </ul> 283 * 284 * <li>The number of significant digits in the mantissa is the sum of the 285 * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is 286 * unaffected by the maximum integer digits. For example, 12345 formatted with 287 * <code>"##0.##E0"</code> is <code>"12.3E3"</code>. To show all digits, set 288 * the significant digits count to zero. The number of significant digits 289 * does not affect parsing. 290 * 291 * <li>Exponential patterns may not contain grouping separators. 292 * </ul> 293 * 294 * <h4>Rounding</h4> 295 * 296 * <code>DecimalFormat</code> provides rounding modes defined in 297 * {@link java.math.RoundingMode} for formatting. By default, it uses 298 * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}. 299 * 300 * <h4>Digits</h4> 301 * 302 * For formatting, <code>DecimalFormat</code> uses the ten consecutive 303 * characters starting with the localized zero digit defined in the 304 * <code>DecimalFormatSymbols</code> object as digits. For parsing, these 305 * digits as well as all Unicode decimal digits, as defined by 306 * {@link Character#digit Character.digit}, are recognized. 307 * 308 * <h4>Special Values</h4> 309 * 310 * <p><code>NaN</code> is formatted as a string, which typically has a single character 311 * <code>\uFFFD</code>. This string is determined by the 312 * <code>DecimalFormatSymbols</code> object. This is the only value for which 313 * the prefixes and suffixes are not used. 314 * 315 * <p>Infinity is formatted as a string, which typically has a single character 316 * <code>\u221E</code>, with the positive or negative prefixes and suffixes 317 * applied. The infinity string is determined by the 318 * <code>DecimalFormatSymbols</code> object. 319 * 320 * <p>Negative zero (<code>"-0"</code>) parses to 321 * <ul> 322 * <li><code>BigDecimal(0)</code> if <code>isParseBigDecimal()</code> is 323 * true, 324 * <li><code>Long(0)</code> if <code>isParseBigDecimal()</code> is false 325 * and <code>isParseIntegerOnly()</code> is true, 326 * <li><code>Double(-0.0)</code> if both <code>isParseBigDecimal()</code> 327 * and <code>isParseIntegerOnly()</code> are false. 328 * </ul> 329 * 330 * <h4><a name="synchronization">Synchronization</a></h4> 331 * 332 * <p> 333 * Decimal formats are generally not synchronized. 334 * It is recommended to create separate format instances for each thread. 335 * If multiple threads access a format concurrently, it must be synchronized 336 * externally. 337 * 338 * <h4>Example</h4> 339 * 340 * <blockquote><pre>{@code 341 * <strong>// Print out a number using the localized number, integer, currency, 342 * // and percent format for each locale</strong> 343 * Locale[] locales = NumberFormat.getAvailableLocales(); 344 * double myNumber = -1234.56; 345 * NumberFormat form; 346 * for (int j = 0; j < 4; ++j) { 347 * System.out.println("FORMAT"); 348 * for (int i = 0; i < locales.length; ++i) { 349 * if (locales[i].getCountry().length() == 0) { 350 * continue; // Skip language-only locales 351 * } 352 * System.out.print(locales[i].getDisplayName()); 353 * switch (j) { 354 * case 0: 355 * form = NumberFormat.getInstance(locales[i]); break; 356 * case 1: 357 * form = NumberFormat.getIntegerInstance(locales[i]); break; 358 * case 2: 359 * form = NumberFormat.getCurrencyInstance(locales[i]); break; 360 * default: 361 * form = NumberFormat.getPercentInstance(locales[i]); break; 362 * } 363 * if (form instanceof DecimalFormat) { 364 * System.out.print(": " + ((DecimalFormat) form).toPattern()); 365 * } 366 * System.out.print(" -> " + form.format(myNumber)); 367 * try { 368 * System.out.println(" -> " + form.parse(form.format(myNumber))); 369 * } catch (ParseException e) {} 370 * } 371 * } 372 * }</pre></blockquote> 373 * 374 * @see <a href="https://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a> 375 * @see NumberFormat 376 * @see DecimalFormatSymbols 377 * @see ParsePosition 378 * @author Mark Davis 379 * @author Alan Liu 380 */ 381 public class DecimalFormat extends NumberFormat { 382 383 private transient android.icu.text.DecimalFormat icuDecimalFormat; 384 385 /** 386 * Creates a DecimalFormat using the default pattern and symbols 387 * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale. 388 * This is a convenient way to obtain a 389 * DecimalFormat when internationalization is not the main concern. 390 * <p> 391 * To obtain standard formats for a given locale, use the factory methods 392 * on NumberFormat such as getNumberInstance. These factories will 393 * return the most appropriate sub-class of NumberFormat for a given 394 * locale. 395 * 396 * @see java.text.NumberFormat#getInstance 397 * @see java.text.NumberFormat#getNumberInstance 398 * @see java.text.NumberFormat#getCurrencyInstance 399 * @see java.text.NumberFormat#getPercentInstance 400 */ DecimalFormat()401 public DecimalFormat() { 402 // Get the pattern for the default locale. 403 Locale def = Locale.getDefault(Locale.Category.FORMAT); 404 // try to get the pattern from the cache 405 String pattern = cachedLocaleData.get(def); 406 if (pattern == null) { /* cache miss */ 407 // Get the pattern for the default locale. 408 pattern = LocaleData.get(def).numberPattern; 409 /* update cache */ 410 cachedLocaleData.putIfAbsent(def, pattern); 411 } 412 this.symbols = new DecimalFormatSymbols(def); 413 init(pattern); 414 } 415 416 417 /** 418 * Creates a DecimalFormat using the given pattern and the symbols 419 * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale. 420 * This is a convenient way to obtain a 421 * DecimalFormat when internationalization is not the main concern. 422 * <p> 423 * To obtain standard formats for a given locale, use the factory methods 424 * on NumberFormat such as getNumberInstance. These factories will 425 * return the most appropriate sub-class of NumberFormat for a given 426 * locale. 427 * 428 * @param pattern a non-localized pattern string. 429 * @exception NullPointerException if <code>pattern</code> is null 430 * @exception IllegalArgumentException if the given pattern is invalid. 431 * @see java.text.NumberFormat#getInstance 432 * @see java.text.NumberFormat#getNumberInstance 433 * @see java.text.NumberFormat#getCurrencyInstance 434 * @see java.text.NumberFormat#getPercentInstance 435 */ DecimalFormat(String pattern)436 public DecimalFormat(String pattern) { 437 this.symbols = new DecimalFormatSymbols(Locale.getDefault(Locale.Category.FORMAT)); 438 init(pattern); 439 } 440 441 442 /** 443 * Creates a DecimalFormat using the given pattern and symbols. 444 * Use this constructor when you need to completely customize the 445 * behavior of the format. 446 * <p> 447 * To obtain standard formats for a given 448 * locale, use the factory methods on NumberFormat such as 449 * getInstance or getCurrencyInstance. If you need only minor adjustments 450 * to a standard format, you can modify the format returned by 451 * a NumberFormat factory method. 452 * 453 * @param pattern a non-localized pattern string 454 * @param symbols the set of symbols to be used 455 * @exception NullPointerException if any of the given arguments is null 456 * @exception IllegalArgumentException if the given pattern is invalid 457 * @see java.text.NumberFormat#getInstance 458 * @see java.text.NumberFormat#getNumberInstance 459 * @see java.text.NumberFormat#getCurrencyInstance 460 * @see java.text.NumberFormat#getPercentInstance 461 * @see java.text.DecimalFormatSymbols 462 */ DecimalFormat(String pattern, DecimalFormatSymbols symbols)463 public DecimalFormat (String pattern, DecimalFormatSymbols symbols) { 464 // Always applyPattern after the symbols are set 465 this.symbols = (DecimalFormatSymbols)symbols.clone(); 466 init(pattern); 467 } 468 init(String pattern)469 private void init(String pattern) { 470 this.icuDecimalFormat = new android.icu.text.DecimalFormat(pattern, 471 symbols.getIcuDecimalFormatSymbols()); 472 updateFieldsFromIcu(); 473 } 474 475 /** 476 * Converts between field positions used by Java/ICU. 477 * @param fp The java.text.NumberFormat.Field field position 478 * @return The android.icu.text.NumberFormat.Field field position 479 */ getIcuFieldPosition(FieldPosition fp)480 private static FieldPosition getIcuFieldPosition(FieldPosition fp) { 481 if (fp.getFieldAttribute() == null) return fp; 482 483 android.icu.text.NumberFormat.Field attribute; 484 if (fp.getFieldAttribute() == Field.INTEGER) { 485 attribute = android.icu.text.NumberFormat.Field.INTEGER; 486 } else if (fp.getFieldAttribute() == Field.FRACTION) { 487 attribute = android.icu.text.NumberFormat.Field.FRACTION; 488 } else if (fp.getFieldAttribute() == Field.DECIMAL_SEPARATOR) { 489 attribute = android.icu.text.NumberFormat.Field.DECIMAL_SEPARATOR; 490 } else if (fp.getFieldAttribute() == Field.EXPONENT_SYMBOL) { 491 attribute = android.icu.text.NumberFormat.Field.EXPONENT_SYMBOL; 492 } else if (fp.getFieldAttribute() == Field.EXPONENT_SIGN) { 493 attribute = android.icu.text.NumberFormat.Field.EXPONENT_SIGN; 494 } else if (fp.getFieldAttribute() == Field.EXPONENT) { 495 attribute = android.icu.text.NumberFormat.Field.EXPONENT; 496 } else if (fp.getFieldAttribute() == Field.GROUPING_SEPARATOR) { 497 attribute = android.icu.text.NumberFormat.Field.GROUPING_SEPARATOR; 498 } else if (fp.getFieldAttribute() == Field.CURRENCY) { 499 attribute = android.icu.text.NumberFormat.Field.CURRENCY; 500 } else if (fp.getFieldAttribute() == Field.PERCENT) { 501 attribute = android.icu.text.NumberFormat.Field.PERCENT; 502 } else if (fp.getFieldAttribute() == Field.PERMILLE) { 503 attribute = android.icu.text.NumberFormat.Field.PERMILLE; 504 } else if (fp.getFieldAttribute() == Field.SIGN) { 505 attribute = android.icu.text.NumberFormat.Field.SIGN; 506 } else { 507 throw new IllegalArgumentException("Unexpected field position attribute type."); 508 } 509 510 FieldPosition icuFieldPosition = new FieldPosition(attribute); 511 icuFieldPosition.setBeginIndex(fp.getBeginIndex()); 512 icuFieldPosition.setEndIndex(fp.getEndIndex()); 513 return icuFieldPosition; 514 } 515 516 /** 517 * Converts the Attribute that ICU returns in its AttributedCharacterIterator 518 * responses to the type that java uses. 519 * @param icuAttribute The AttributedCharacterIterator.Attribute field. 520 * @return Field converted to a java.text.NumberFormat.Field field. 521 */ toJavaFieldAttribute(AttributedCharacterIterator.Attribute icuAttribute)522 private static Field toJavaFieldAttribute(AttributedCharacterIterator.Attribute icuAttribute) { 523 if (icuAttribute.getName().equals(Field.INTEGER.getName())) { 524 return Field.INTEGER; 525 } 526 if (icuAttribute.getName().equals(Field.CURRENCY.getName())) { 527 return Field.CURRENCY; 528 } 529 if (icuAttribute.getName().equals(Field.DECIMAL_SEPARATOR.getName())) { 530 return Field.DECIMAL_SEPARATOR; 531 } 532 if (icuAttribute.getName().equals(Field.EXPONENT.getName())) { 533 return Field.EXPONENT; 534 } 535 if (icuAttribute.getName().equals(Field.EXPONENT_SIGN.getName())) { 536 return Field.EXPONENT_SIGN; 537 } 538 if (icuAttribute.getName().equals(Field.EXPONENT_SYMBOL.getName())) { 539 return Field.EXPONENT_SYMBOL; 540 } 541 if (icuAttribute.getName().equals(Field.FRACTION.getName())) { 542 return Field.FRACTION; 543 } 544 if (icuAttribute.getName().equals(Field.GROUPING_SEPARATOR.getName())) { 545 return Field.GROUPING_SEPARATOR; 546 } 547 if (icuAttribute.getName().equals(Field.SIGN.getName())) { 548 return Field.SIGN; 549 } 550 if (icuAttribute.getName().equals(Field.PERCENT.getName())) { 551 return Field.PERCENT; 552 } 553 if (icuAttribute.getName().equals(Field.PERMILLE.getName())) { 554 return Field.PERMILLE; 555 } 556 throw new IllegalArgumentException("Unrecognized attribute: " + icuAttribute.getName()); 557 } 558 559 // Overrides 560 /** 561 * Formats a number and appends the resulting text to the given string 562 * buffer. 563 * The number can be of any subclass of {@link java.lang.Number}. 564 * <p> 565 * This implementation uses the maximum precision permitted. 566 * @param number the number to format 567 * @param toAppendTo the <code>StringBuffer</code> to which the formatted 568 * text is to be appended 569 * @param pos On input: an alignment field, if desired. 570 * On output: the offsets of the alignment field. 571 * @return the value passed in as <code>toAppendTo</code> 572 * @exception IllegalArgumentException if <code>number</code> is 573 * null or not an instance of <code>Number</code>. 574 * @exception NullPointerException if <code>toAppendTo</code> or 575 * <code>pos</code> is null 576 * @exception ArithmeticException if rounding is needed with rounding 577 * mode being set to RoundingMode.UNNECESSARY 578 * @see java.text.FieldPosition 579 */ 580 @Override format(Object number, StringBuffer toAppendTo, FieldPosition pos)581 public final StringBuffer format(Object number, 582 StringBuffer toAppendTo, 583 FieldPosition pos) { 584 if (number instanceof Long || number instanceof Integer || 585 number instanceof Short || number instanceof Byte || 586 number instanceof AtomicInteger || 587 number instanceof AtomicLong || 588 (number instanceof BigInteger && 589 ((BigInteger)number).bitLength () < 64)) { 590 return format(((Number)number).longValue(), toAppendTo, pos); 591 } else if (number instanceof BigDecimal) { 592 return format((BigDecimal)number, toAppendTo, pos); 593 } else if (number instanceof BigInteger) { 594 return format((BigInteger)number, toAppendTo, pos); 595 } else if (number instanceof Number) { 596 return format(((Number)number).doubleValue(), toAppendTo, pos); 597 } else { 598 throw new IllegalArgumentException("Cannot format given Object as a Number"); 599 } 600 } 601 602 /** 603 * Formats a double to produce a string. 604 * @param number The double to format 605 * @param result where the text is to be appended 606 * @param fieldPosition On input: an alignment field, if desired. 607 * On output: the offsets of the alignment field. 608 * @exception ArithmeticException if rounding is needed with rounding 609 * mode being set to RoundingMode.UNNECESSARY 610 * @return The formatted number string 611 * @see java.text.FieldPosition 612 */ 613 @Override format(double number, StringBuffer result, FieldPosition fieldPosition)614 public StringBuffer format(double number, StringBuffer result, 615 FieldPosition fieldPosition) { 616 FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition); 617 icuDecimalFormat.format(number, result, icuFieldPosition); 618 fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex()); 619 fieldPosition.setEndIndex(icuFieldPosition.getEndIndex()); 620 return result; 621 } 622 623 /** 624 * Format a long to produce a string. 625 * @param number The long to format 626 * @param result where the text is to be appended 627 * @param fieldPosition On input: an alignment field, if desired. 628 * On output: the offsets of the alignment field. 629 * @exception ArithmeticException if rounding is needed with rounding 630 * mode being set to RoundingMode.UNNECESSARY 631 * @return The formatted number string 632 * @see java.text.FieldPosition 633 */ 634 @Override format(long number, StringBuffer result, FieldPosition fieldPosition)635 public StringBuffer format(long number, StringBuffer result, 636 FieldPosition fieldPosition) { 637 FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition); 638 icuDecimalFormat.format(number, result, icuFieldPosition); 639 fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex()); 640 fieldPosition.setEndIndex(icuFieldPosition.getEndIndex()); 641 return result; 642 } 643 644 /** 645 * Formats a BigDecimal to produce a string. 646 * @param number The BigDecimal to format 647 * @param result where the text is to be appended 648 * @param fieldPosition On input: an alignment field, if desired. 649 * On output: the offsets of the alignment field. 650 * @return The formatted number string 651 * @exception ArithmeticException if rounding is needed with rounding 652 * mode being set to RoundingMode.UNNECESSARY 653 * @see java.text.FieldPosition 654 */ format(BigDecimal number, StringBuffer result, FieldPosition fieldPosition)655 private StringBuffer format(BigDecimal number, StringBuffer result, 656 FieldPosition fieldPosition) { 657 FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition); 658 icuDecimalFormat.format(number, result, fieldPosition); 659 fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex()); 660 fieldPosition.setEndIndex(icuFieldPosition.getEndIndex()); 661 return result; 662 } 663 664 /** 665 * Format a BigInteger to produce a string. 666 * @param number The BigInteger to format 667 * @param result where the text is to be appended 668 * @param fieldPosition On input: an alignment field, if desired. 669 * On output: the offsets of the alignment field. 670 * @return The formatted number string 671 * @exception ArithmeticException if rounding is needed with rounding 672 * mode being set to RoundingMode.UNNECESSARY 673 * @see java.text.FieldPosition 674 */ format(BigInteger number, StringBuffer result, FieldPosition fieldPosition)675 private StringBuffer format(BigInteger number, StringBuffer result, 676 FieldPosition fieldPosition) { 677 FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition); 678 icuDecimalFormat.format(number, result, fieldPosition); 679 fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex()); 680 fieldPosition.setEndIndex(icuFieldPosition.getEndIndex()); 681 return result; 682 } 683 684 /** 685 * Formats an Object producing an <code>AttributedCharacterIterator</code>. 686 * You can use the returned <code>AttributedCharacterIterator</code> 687 * to build the resulting String, as well as to determine information 688 * about the resulting String. 689 * <p> 690 * Each attribute key of the AttributedCharacterIterator will be of type 691 * <code>NumberFormat.Field</code>, with the attribute value being the 692 * same as the attribute key. 693 * 694 * @exception NullPointerException if obj is null. 695 * @exception IllegalArgumentException when the Format cannot format the 696 * given object. 697 * @exception ArithmeticException if rounding is needed with rounding 698 * mode being set to RoundingMode.UNNECESSARY 699 * @param obj The object to format 700 * @return AttributedCharacterIterator describing the formatted value. 701 * @since 1.4 702 */ 703 @Override formatToCharacterIterator(Object obj)704 public AttributedCharacterIterator formatToCharacterIterator(Object obj) { 705 if (obj == null) { 706 throw new NullPointerException("object == null"); 707 } 708 // Note: formatToCharacterIterator cannot be used directly because it returns attributes 709 // in terms of its own class: icu.text.NumberFormat instead of java.text.NumberFormat. 710 // http://bugs.icu-project.org/trac/ticket/11931 Proposes to use the NumberFormat constants. 711 712 AttributedCharacterIterator original = icuDecimalFormat.formatToCharacterIterator(obj); 713 714 // Extract the text out of the ICU iterator. 715 StringBuilder textBuilder = new StringBuilder( 716 original.getEndIndex() - original.getBeginIndex()); 717 718 for (int i = original.getBeginIndex(); i < original.getEndIndex(); i++) { 719 textBuilder.append(original.current()); 720 original.next(); 721 } 722 723 AttributedString result = new AttributedString(textBuilder.toString()); 724 725 for (int i = original.getBeginIndex(); i < original.getEndIndex(); i++) { 726 original.setIndex(i); 727 728 for (AttributedCharacterIterator.Attribute attribute 729 : original.getAttributes().keySet()) { 730 int start = original.getRunStart(); 731 int end = original.getRunLimit(); 732 Field javaAttr = toJavaFieldAttribute(attribute); 733 result.addAttribute(javaAttr, javaAttr, start, end); 734 } 735 } 736 737 return result.getIterator(); 738 } 739 740 /** 741 * Parses text from a string to produce a <code>Number</code>. 742 * <p> 743 * The method attempts to parse text starting at the index given by 744 * <code>pos</code>. 745 * If parsing succeeds, then the index of <code>pos</code> is updated 746 * to the index after the last character used (parsing does not necessarily 747 * use all characters up to the end of the string), and the parsed 748 * number is returned. The updated <code>pos</code> can be used to 749 * indicate the starting point for the next call to this method. 750 * If an error occurs, then the index of <code>pos</code> is not 751 * changed, the error index of <code>pos</code> is set to the index of 752 * the character where the error occurred, and null is returned. 753 * <p> 754 * The subclass returned depends on the value of {@link #isParseBigDecimal} 755 * as well as on the string being parsed. 756 * <ul> 757 * <li>If <code>isParseBigDecimal()</code> is false (the default), 758 * most integer values are returned as <code>Long</code> 759 * objects, no matter how they are written: <code>"17"</code> and 760 * <code>"17.000"</code> both parse to <code>Long(17)</code>. 761 * Values that cannot fit into a <code>Long</code> are returned as 762 * <code>Double</code>s. This includes values with a fractional part, 763 * infinite values, <code>NaN</code>, and the value -0.0. 764 * <code>DecimalFormat</code> does <em>not</em> decide whether to 765 * return a <code>Double</code> or a <code>Long</code> based on the 766 * presence of a decimal separator in the source string. Doing so 767 * would prevent integers that overflow the mantissa of a double, 768 * such as <code>"-9,223,372,036,854,775,808.00"</code>, from being 769 * parsed accurately. 770 * <p> 771 * Callers may use the <code>Number</code> methods 772 * <code>doubleValue</code>, <code>longValue</code>, etc., to obtain 773 * the type they want. 774 * <li>If <code>isParseBigDecimal()</code> is true, values are returned 775 * as <code>BigDecimal</code> objects. The values are the ones 776 * constructed by {@link java.math.BigDecimal#BigDecimal(String)} 777 * for corresponding strings in locale-independent format. The 778 * special cases negative and positive infinity and NaN are returned 779 * as <code>Double</code> instances holding the values of the 780 * corresponding <code>Double</code> constants. 781 * </ul> 782 * <p> 783 * <code>DecimalFormat</code> parses all Unicode characters that represent 784 * decimal digits, as defined by <code>Character.digit()</code>. In 785 * addition, <code>DecimalFormat</code> also recognizes as digits the ten 786 * consecutive characters starting with the localized zero digit defined in 787 * the <code>DecimalFormatSymbols</code> object. 788 * 789 * @param text the string to be parsed 790 * @param pos A <code>ParsePosition</code> object with index and error 791 * index information as described above. 792 * @return the parsed value, or <code>null</code> if the parse fails 793 * @exception NullPointerException if <code>text</code> or 794 * <code>pos</code> is null. 795 */ 796 @Override parse(String text, ParsePosition pos)797 public Number parse(String text, ParsePosition pos) { 798 // Return early if the parse position is bogus. 799 if (pos.index < 0 || pos.index >= text.length()) { 800 return null; 801 } 802 803 // This might return android.icu.math.BigDecimal, java.math.BigInteger or a primitive type. 804 Number number = icuDecimalFormat.parse(text, pos); 805 if (number == null) { 806 return null; 807 } 808 if (isParseBigDecimal()) { 809 if (number instanceof Long) { 810 return new BigDecimal(number.longValue()); 811 } 812 if ((number instanceof Double) && !((Double) number).isInfinite() 813 && !((Double) number).isNaN()) { 814 return new BigDecimal(number.toString()); 815 } 816 if ((number instanceof Double) && 817 (((Double) number).isNaN() || ((Double) number).isInfinite())) { 818 return number; 819 } 820 if (number instanceof android.icu.math.BigDecimal) { 821 return ((android.icu.math.BigDecimal) number).toBigDecimal(); 822 } 823 } 824 if ((number instanceof android.icu.math.BigDecimal) || (number instanceof BigInteger)) { 825 return number.doubleValue(); 826 } 827 if (isParseIntegerOnly() && number.equals(new Double(-0.0))) { 828 return 0L; 829 } 830 return number; 831 } 832 833 /** 834 * Returns a copy of the decimal format symbols, which is generally not 835 * changed by the programmer or user. 836 * @return a copy of the desired DecimalFormatSymbols 837 * @see java.text.DecimalFormatSymbols 838 */ getDecimalFormatSymbols()839 public DecimalFormatSymbols getDecimalFormatSymbols() { 840 return DecimalFormatSymbols.fromIcuInstance(icuDecimalFormat.getDecimalFormatSymbols()); 841 } 842 843 844 /** 845 * Sets the decimal format symbols, which is generally not changed 846 * by the programmer or user. 847 * @param newSymbols desired DecimalFormatSymbols 848 * @see java.text.DecimalFormatSymbols 849 */ setDecimalFormatSymbols(DecimalFormatSymbols newSymbols)850 public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) { 851 try { 852 // don't allow multiple references 853 symbols = (DecimalFormatSymbols) newSymbols.clone(); 854 icuDecimalFormat.setDecimalFormatSymbols(symbols.getIcuDecimalFormatSymbols()); 855 } catch (Exception foo) { 856 // should never happen 857 } 858 } 859 860 /** 861 * Get the positive prefix. 862 * <P>Examples: +123, $123, sFr123 863 * 864 * @return the positive prefix 865 */ getPositivePrefix()866 public String getPositivePrefix () { 867 return icuDecimalFormat.getPositivePrefix(); 868 } 869 870 /** 871 * Set the positive prefix. 872 * <P>Examples: +123, $123, sFr123 873 * 874 * @param newValue the new positive prefix 875 */ setPositivePrefix(String newValue)876 public void setPositivePrefix (String newValue) { 877 icuDecimalFormat.setPositivePrefix(newValue); 878 } 879 880 /** 881 * Get the prefix. 882 * <P>Examples: -123, ($123) (with negative suffix), sFr-123 883 * 884 * @return the negative prefix 885 */ getNegativePrefix()886 public String getNegativePrefix () { 887 return icuDecimalFormat.getNegativePrefix(); 888 } 889 890 /** 891 * Set the negative prefix. 892 * <P>Examples: -123, ($123) (with negative suffix), sFr-123 893 * 894 * @param newValue the new negative prefix 895 */ setNegativePrefix(String newValue)896 public void setNegativePrefix (String newValue) { 897 icuDecimalFormat.setNegativePrefix(newValue); 898 } 899 900 /** 901 * Get the positive suffix. 902 * <P>Example: 123% 903 * 904 * @return the positive suffix 905 */ getPositiveSuffix()906 public String getPositiveSuffix () { 907 return icuDecimalFormat.getPositiveSuffix(); 908 } 909 910 /** 911 * Set the positive suffix. 912 * <P>Example: 123% 913 * 914 * @param newValue the new positive suffix 915 */ setPositiveSuffix(String newValue)916 public void setPositiveSuffix (String newValue) { 917 icuDecimalFormat.setPositiveSuffix(newValue); 918 } 919 920 /** 921 * Get the negative suffix. 922 * <P>Examples: -123%, ($123) (with positive suffixes) 923 * 924 * @return the negative suffix 925 */ getNegativeSuffix()926 public String getNegativeSuffix () { 927 return icuDecimalFormat.getNegativeSuffix(); 928 } 929 930 /** 931 * Set the negative suffix. 932 * <P>Examples: 123% 933 * 934 * @param newValue the new negative suffix 935 */ setNegativeSuffix(String newValue)936 public void setNegativeSuffix (String newValue) { 937 icuDecimalFormat.setNegativeSuffix(newValue); 938 } 939 940 /** 941 * Gets the multiplier for use in percent, per mille, and similar 942 * formats. 943 * 944 * @return the multiplier 945 * @see #setMultiplier(int) 946 */ getMultiplier()947 public int getMultiplier () { 948 return icuDecimalFormat.getMultiplier(); 949 } 950 951 /** 952 * Sets the multiplier for use in percent, per mille, and similar 953 * formats. 954 * For a percent format, set the multiplier to 100 and the suffixes to 955 * have '%' (for Arabic, use the Arabic percent sign). 956 * For a per mille format, set the multiplier to 1000 and the suffixes to 957 * have '\u2030'. 958 * 959 * <P>Example: with multiplier 100, 1.23 is formatted as "123", and 960 * "123" is parsed into 1.23. 961 * 962 * @param newValue the new multiplier 963 * @see #getMultiplier 964 */ setMultiplier(int newValue)965 public void setMultiplier (int newValue) { 966 icuDecimalFormat.setMultiplier(newValue); 967 } 968 969 /** 970 * Return the grouping size. Grouping size is the number of digits between 971 * grouping separators in the integer portion of a number. For example, 972 * in the number "123,456.78", the grouping size is 3. 973 * 974 * @return the grouping size 975 * @see #setGroupingSize 976 * @see java.text.NumberFormat#isGroupingUsed 977 * @see java.text.DecimalFormatSymbols#getGroupingSeparator 978 */ getGroupingSize()979 public int getGroupingSize () { 980 return icuDecimalFormat.getGroupingSize(); 981 } 982 983 /** 984 * Set the grouping size. Grouping size is the number of digits between 985 * grouping separators in the integer portion of a number. For example, 986 * in the number "123,456.78", the grouping size is 3. 987 * <br> 988 * The value passed in is converted to a byte, which may lose information. 989 * 990 * @param newValue the new grouping size 991 * @see #getGroupingSize 992 * @see java.text.NumberFormat#setGroupingUsed 993 * @see java.text.DecimalFormatSymbols#setGroupingSeparator 994 */ setGroupingSize(int newValue)995 public void setGroupingSize (int newValue) { 996 icuDecimalFormat.setGroupingSize(newValue); 997 } 998 999 /** 1000 * Returns true if grouping is used in this format. For example, in the 1001 * English locale, with grouping on, the number 1234567 might be formatted 1002 * as "1,234,567". The grouping separator as well as the size of each group 1003 * is locale dependant and is determined by sub-classes of NumberFormat. 1004 * @see #setGroupingUsed 1005 */ isGroupingUsed()1006 public boolean isGroupingUsed() { 1007 return icuDecimalFormat.isGroupingUsed(); 1008 } 1009 1010 /** 1011 * Set whether or not grouping will be used in this format. 1012 * @see #isGroupingUsed 1013 */ setGroupingUsed(boolean newValue)1014 public void setGroupingUsed(boolean newValue) { 1015 icuDecimalFormat.setGroupingUsed(newValue); 1016 } 1017 1018 /** 1019 * Allows you to get the behavior of the decimal separator with integers. 1020 * (The decimal separator will always appear with decimals.) 1021 * <P>Example: Decimal ON: 12345 → 12345.; OFF: 12345 → 12345 1022 * 1023 * @return {@code true} if the decimal separator is always shown; 1024 * {@code false} otherwise 1025 */ isDecimalSeparatorAlwaysShown()1026 public boolean isDecimalSeparatorAlwaysShown() { 1027 return icuDecimalFormat.isDecimalSeparatorAlwaysShown(); 1028 } 1029 1030 /** 1031 * Allows you to set the behavior of the decimal separator with integers. 1032 * (The decimal separator will always appear with decimals.) 1033 * <P>Example: Decimal ON: 12345 → 12345.; OFF: 12345 → 12345 1034 * 1035 * @param newValue {@code true} if the decimal separator is always shown; 1036 * {@code false} otherwise 1037 */ setDecimalSeparatorAlwaysShown(boolean newValue)1038 public void setDecimalSeparatorAlwaysShown(boolean newValue) { 1039 icuDecimalFormat.setDecimalSeparatorAlwaysShown(newValue); 1040 } 1041 1042 /** 1043 * Returns whether the {@link #parse(java.lang.String, java.text.ParsePosition)} 1044 * method returns <code>BigDecimal</code>. The default value is false. 1045 * 1046 * @return {@code true} if the parse method returns BigDecimal; 1047 * {@code false} otherwise 1048 * @see #setParseBigDecimal 1049 * @since 1.5 1050 */ isParseBigDecimal()1051 public boolean isParseBigDecimal() { 1052 return icuDecimalFormat.isParseBigDecimal(); 1053 } 1054 1055 /** 1056 * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)} 1057 * method returns <code>BigDecimal</code>. 1058 * 1059 * @param newValue {@code true} if the parse method returns BigDecimal; 1060 * {@code false} otherwise 1061 * @see #isParseBigDecimal 1062 * @since 1.5 1063 */ setParseBigDecimal(boolean newValue)1064 public void setParseBigDecimal(boolean newValue) { 1065 icuDecimalFormat.setParseBigDecimal(newValue); 1066 } 1067 1068 /** 1069 * Sets whether or not numbers should be parsed as integers only. 1070 * @see #isParseIntegerOnly 1071 */ setParseIntegerOnly(boolean value)1072 public void setParseIntegerOnly(boolean value) { 1073 super.setParseIntegerOnly(value); 1074 icuDecimalFormat.setParseIntegerOnly(value); 1075 } 1076 1077 /** 1078 * Returns true if this format will parse numbers as integers only. 1079 * For example in the English locale, with ParseIntegerOnly true, the 1080 * string "1234." would be parsed as the integer value 1234 and parsing 1081 * would stop at the "." character. Of course, the exact format accepted 1082 * by the parse operation is locale dependant and determined by sub-classes 1083 * of NumberFormat. 1084 */ isParseIntegerOnly()1085 public boolean isParseIntegerOnly() { 1086 return icuDecimalFormat.isParseIntegerOnly(); 1087 } 1088 1089 /** 1090 * Standard override; no change in semantics. 1091 */ 1092 @Override clone()1093 public Object clone() { 1094 try { 1095 DecimalFormat other = (DecimalFormat) super.clone(); 1096 other.icuDecimalFormat = (android.icu.text.DecimalFormat) icuDecimalFormat.clone(); 1097 other.symbols = (DecimalFormatSymbols) symbols.clone(); 1098 return other; 1099 } catch (Exception e) { 1100 throw new InternalError(); 1101 } 1102 } 1103 1104 /** 1105 * Overrides equals 1106 */ 1107 @Override equals(Object obj)1108 public boolean equals(Object obj) 1109 { 1110 if (obj == null) { 1111 return false; 1112 } 1113 if (this == obj) { 1114 return true; 1115 } 1116 if (!(obj instanceof DecimalFormat)) { 1117 return false; 1118 } 1119 DecimalFormat other = (DecimalFormat) obj; 1120 return icuDecimalFormat.equals(other.icuDecimalFormat) 1121 && compareIcuRoundingIncrement(other.icuDecimalFormat); 1122 } 1123 compareIcuRoundingIncrement(android.icu.text.DecimalFormat other)1124 private boolean compareIcuRoundingIncrement(android.icu.text.DecimalFormat other) { 1125 BigDecimal increment = this.icuDecimalFormat.getRoundingIncrement(); 1126 if (increment != null) { 1127 return (other.getRoundingIncrement() != null) 1128 && increment.equals(other.getRoundingIncrement()); 1129 } 1130 return other.getRoundingIncrement() == null; 1131 } 1132 1133 /** 1134 * Overrides hashCode 1135 */ 1136 @Override hashCode()1137 public int hashCode() { 1138 return super.hashCode() * 37 + getPositivePrefix().hashCode(); 1139 // just enough fields for a reasonable distribution 1140 } 1141 1142 /** 1143 * Synthesizes a pattern string that represents the current state 1144 * of this Format object. 1145 * 1146 * @return a pattern string 1147 * @see #applyPattern 1148 */ toPattern()1149 public String toPattern() { 1150 return icuDecimalFormat.toPattern(); 1151 } 1152 1153 /** 1154 * Synthesizes a localized pattern string that represents the current 1155 * state of this Format object. 1156 * 1157 * @return a localized pattern string 1158 * @see #applyPattern 1159 */ toLocalizedPattern()1160 public String toLocalizedPattern() { 1161 return icuDecimalFormat.toLocalizedPattern(); 1162 } 1163 1164 /** 1165 * Apply the given pattern to this Format object. A pattern is a 1166 * short-hand specification for the various formatting properties. 1167 * These properties can also be changed individually through the 1168 * various setter methods. 1169 * <p> 1170 * There is no limit to integer digits set 1171 * by this routine, since that is the typical end-user desire; 1172 * use setMaximumInteger if you want to set a real value. 1173 * For negative numbers, use a second pattern, separated by a semicolon 1174 * <P>Example <code>"#,#00.0#"</code> → 1,234.56 1175 * <P>This means a minimum of 2 integer digits, 1 fraction digit, and 1176 * a maximum of 2 fraction digits. 1177 * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in 1178 * parentheses. 1179 * <p>In negative patterns, the minimum and maximum counts are ignored; 1180 * these are presumed to be set in the positive pattern. 1181 * 1182 * @param pattern a new pattern 1183 * @exception NullPointerException if <code>pattern</code> is null 1184 * @exception IllegalArgumentException if the given pattern is invalid. 1185 */ applyPattern(String pattern)1186 public void applyPattern(String pattern) { 1187 icuDecimalFormat.applyPattern(pattern); 1188 updateFieldsFromIcu(); 1189 } 1190 1191 1192 /** 1193 * Apply the given pattern to this Format object. The pattern 1194 * is assumed to be in a localized notation. A pattern is a 1195 * short-hand specification for the various formatting properties. 1196 * These properties can also be changed individually through the 1197 * various setter methods. 1198 * <p> 1199 * There is no limit to integer digits set 1200 * by this routine, since that is the typical end-user desire; 1201 * use setMaximumInteger if you want to set a real value. 1202 * For negative numbers, use a second pattern, separated by a semicolon 1203 * <P>Example <code>"#,#00.0#"</code> → 1,234.56 1204 * <P>This means a minimum of 2 integer digits, 1 fraction digit, and 1205 * a maximum of 2 fraction digits. 1206 * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in 1207 * parentheses. 1208 * <p>In negative patterns, the minimum and maximum counts are ignored; 1209 * these are presumed to be set in the positive pattern. 1210 * 1211 * @param pattern a new pattern 1212 * @exception NullPointerException if <code>pattern</code> is null 1213 * @exception IllegalArgumentException if the given pattern is invalid. 1214 */ applyLocalizedPattern(String pattern)1215 public void applyLocalizedPattern(String pattern) { 1216 icuDecimalFormat.applyLocalizedPattern(pattern); 1217 updateFieldsFromIcu(); 1218 } 1219 updateFieldsFromIcu()1220 private void updateFieldsFromIcu() { 1221 // Imitate behaviour of ICU4C NumberFormat that Android used up to M. 1222 // If the pattern doesn't enforce a different value (some exponential 1223 // patterns do), then set the maximum integer digits to 2 billion. 1224 if (icuDecimalFormat.getMaximumIntegerDigits() == DOUBLE_INTEGER_DIGITS) { 1225 icuDecimalFormat.setMaximumIntegerDigits(2000000000); 1226 } 1227 maximumIntegerDigits = icuDecimalFormat.getMaximumIntegerDigits(); 1228 minimumIntegerDigits = icuDecimalFormat.getMinimumIntegerDigits(); 1229 maximumFractionDigits = icuDecimalFormat.getMaximumFractionDigits(); 1230 minimumFractionDigits = icuDecimalFormat.getMinimumFractionDigits(); 1231 } 1232 1233 /** 1234 * Sets the maximum number of digits allowed in the integer portion of a 1235 * number. 1236 * For formatting numbers other than <code>BigInteger</code> and 1237 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and 1238 * 309 is used. Negative input values are replaced with 0. 1239 * @see NumberFormat#setMaximumIntegerDigits 1240 */ 1241 @Override setMaximumIntegerDigits(int newValue)1242 public void setMaximumIntegerDigits(int newValue) { 1243 maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS); 1244 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? 1245 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits); 1246 if (minimumIntegerDigits > maximumIntegerDigits) { 1247 minimumIntegerDigits = maximumIntegerDigits; 1248 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? 1249 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits); 1250 } 1251 icuDecimalFormat.setMaximumIntegerDigits(getMaximumIntegerDigits()); 1252 } 1253 1254 /** 1255 * Sets the minimum number of digits allowed in the integer portion of a 1256 * number. 1257 * For formatting numbers other than <code>BigInteger</code> and 1258 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and 1259 * 309 is used. Negative input values are replaced with 0. 1260 * @see NumberFormat#setMinimumIntegerDigits 1261 */ 1262 @Override setMinimumIntegerDigits(int newValue)1263 public void setMinimumIntegerDigits(int newValue) { 1264 minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS); 1265 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? 1266 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits); 1267 if (minimumIntegerDigits > maximumIntegerDigits) { 1268 maximumIntegerDigits = minimumIntegerDigits; 1269 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? 1270 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits); 1271 } 1272 icuDecimalFormat.setMinimumIntegerDigits(getMinimumIntegerDigits()); 1273 } 1274 1275 /** 1276 * Sets the maximum number of digits allowed in the fraction portion of a 1277 * number. 1278 * For formatting numbers other than <code>BigInteger</code> and 1279 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and 1280 * 340 is used. Negative input values are replaced with 0. 1281 * @see NumberFormat#setMaximumFractionDigits 1282 */ 1283 @Override setMaximumFractionDigits(int newValue)1284 public void setMaximumFractionDigits(int newValue) { 1285 maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS); 1286 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ? 1287 DOUBLE_FRACTION_DIGITS : maximumFractionDigits); 1288 if (minimumFractionDigits > maximumFractionDigits) { 1289 minimumFractionDigits = maximumFractionDigits; 1290 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ? 1291 DOUBLE_FRACTION_DIGITS : minimumFractionDigits); 1292 } 1293 icuDecimalFormat.setMaximumFractionDigits(getMaximumFractionDigits()); 1294 } 1295 1296 /** 1297 * Sets the minimum number of digits allowed in the fraction portion of a 1298 * number. 1299 * For formatting numbers other than <code>BigInteger</code> and 1300 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and 1301 * 340 is used. Negative input values are replaced with 0. 1302 * @see NumberFormat#setMinimumFractionDigits 1303 */ 1304 @Override setMinimumFractionDigits(int newValue)1305 public void setMinimumFractionDigits(int newValue) { 1306 minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS); 1307 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ? 1308 DOUBLE_FRACTION_DIGITS : minimumFractionDigits); 1309 if (minimumFractionDigits > maximumFractionDigits) { 1310 maximumFractionDigits = minimumFractionDigits; 1311 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ? 1312 DOUBLE_FRACTION_DIGITS : maximumFractionDigits); 1313 } 1314 icuDecimalFormat.setMinimumFractionDigits(getMinimumFractionDigits()); 1315 } 1316 1317 /** 1318 * Gets the maximum number of digits allowed in the integer portion of a 1319 * number. 1320 * For formatting numbers other than <code>BigInteger</code> and 1321 * <code>BigDecimal</code> objects, the lower of the return value and 1322 * 309 is used. 1323 * @see #setMaximumIntegerDigits 1324 */ 1325 @Override getMaximumIntegerDigits()1326 public int getMaximumIntegerDigits() { 1327 return maximumIntegerDigits; 1328 } 1329 1330 /** 1331 * Gets the minimum number of digits allowed in the integer portion of a 1332 * number. 1333 * For formatting numbers other than <code>BigInteger</code> and 1334 * <code>BigDecimal</code> objects, the lower of the return value and 1335 * 309 is used. 1336 * @see #setMinimumIntegerDigits 1337 */ 1338 @Override getMinimumIntegerDigits()1339 public int getMinimumIntegerDigits() { 1340 return minimumIntegerDigits; 1341 } 1342 1343 /** 1344 * Gets the maximum number of digits allowed in the fraction portion of a 1345 * number. 1346 * For formatting numbers other than <code>BigInteger</code> and 1347 * <code>BigDecimal</code> objects, the lower of the return value and 1348 * 340 is used. 1349 * @see #setMaximumFractionDigits 1350 */ 1351 @Override getMaximumFractionDigits()1352 public int getMaximumFractionDigits() { 1353 return maximumFractionDigits; 1354 } 1355 1356 /** 1357 * Gets the minimum number of digits allowed in the fraction portion of a 1358 * number. 1359 * For formatting numbers other than <code>BigInteger</code> and 1360 * <code>BigDecimal</code> objects, the lower of the return value and 1361 * 340 is used. 1362 * @see #setMinimumFractionDigits 1363 */ 1364 @Override getMinimumFractionDigits()1365 public int getMinimumFractionDigits() { 1366 return minimumFractionDigits; 1367 } 1368 1369 /** 1370 * Gets the currency used by this decimal format when formatting 1371 * currency values. 1372 * The currency is obtained by calling 1373 * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency} 1374 * on this number format's symbols. 1375 * 1376 * @return the currency used by this decimal format, or <code>null</code> 1377 * @since 1.4 1378 */ 1379 @Override getCurrency()1380 public Currency getCurrency() { 1381 return symbols.getCurrency(); 1382 } 1383 1384 /** 1385 * Sets the currency used by this number format when formatting 1386 * currency values. This does not update the minimum or maximum 1387 * number of fraction digits used by the number format. 1388 * The currency is set by calling 1389 * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency} 1390 * on this number format's symbols. 1391 * 1392 * @param currency the new currency to be used by this decimal format 1393 * @exception NullPointerException if <code>currency</code> is null 1394 * @since 1.4 1395 */ 1396 @Override setCurrency(Currency currency)1397 public void setCurrency(Currency currency) { 1398 // Set the international currency symbol, and currency symbol on the DecimalFormatSymbols 1399 // object and tell ICU to use that. 1400 if (currency != symbols.getCurrency() 1401 || !currency.getSymbol().equals(symbols.getCurrencySymbol())) { 1402 symbols.setCurrency(currency); 1403 icuDecimalFormat.setDecimalFormatSymbols(symbols.getIcuDecimalFormatSymbols()); 1404 // Giving the icuDecimalFormat a new currency will cause the fractional digits to be 1405 // updated. This class is specified to not touch the fraction digits, so we re-set them. 1406 icuDecimalFormat.setMinimumFractionDigits(minimumFractionDigits); 1407 icuDecimalFormat.setMaximumFractionDigits(maximumFractionDigits); 1408 } 1409 } 1410 1411 /** 1412 * Gets the {@link java.math.RoundingMode} used in this DecimalFormat. 1413 * 1414 * @return The <code>RoundingMode</code> used for this DecimalFormat. 1415 * @see #setRoundingMode(RoundingMode) 1416 * @since 1.6 1417 */ 1418 @Override getRoundingMode()1419 public RoundingMode getRoundingMode() { 1420 return roundingMode; 1421 } 1422 convertRoundingMode(RoundingMode rm)1423 private static int convertRoundingMode(RoundingMode rm) { 1424 switch (rm) { 1425 case UP: 1426 return MathContext.ROUND_UP; 1427 case DOWN: 1428 return MathContext.ROUND_DOWN; 1429 case CEILING: 1430 return MathContext.ROUND_CEILING; 1431 case FLOOR: 1432 return MathContext.ROUND_FLOOR; 1433 case HALF_UP: 1434 return MathContext.ROUND_HALF_UP; 1435 case HALF_DOWN: 1436 return MathContext.ROUND_HALF_DOWN; 1437 case HALF_EVEN: 1438 return MathContext.ROUND_HALF_EVEN; 1439 case UNNECESSARY: 1440 return MathContext.ROUND_UNNECESSARY; 1441 } 1442 throw new IllegalArgumentException("Invalid rounding mode specified"); 1443 } 1444 1445 /** 1446 * Sets the {@link java.math.RoundingMode} used in this DecimalFormat. 1447 * 1448 * @param roundingMode The <code>RoundingMode</code> to be used 1449 * @see #getRoundingMode() 1450 * @exception NullPointerException if <code>roundingMode</code> is null. 1451 * @since 1.6 1452 */ 1453 @Override setRoundingMode(RoundingMode roundingMode)1454 public void setRoundingMode(RoundingMode roundingMode) { 1455 if (roundingMode == null) { 1456 throw new NullPointerException(); 1457 } 1458 1459 this.roundingMode = roundingMode; 1460 1461 icuDecimalFormat.setRoundingMode(convertRoundingMode(roundingMode)); 1462 } 1463 1464 /** 1465 * Adjusts the minimum and maximum fraction digits to values that 1466 * are reasonable for the currency's default fraction digits. 1467 */ adjustForCurrencyDefaultFractionDigits()1468 void adjustForCurrencyDefaultFractionDigits() { 1469 Currency currency = symbols.getCurrency(); 1470 if (currency == null) { 1471 try { 1472 currency = Currency.getInstance(symbols.getInternationalCurrencySymbol()); 1473 } catch (IllegalArgumentException e) { 1474 } 1475 } 1476 if (currency != null) { 1477 int digits = currency.getDefaultFractionDigits(); 1478 if (digits != -1) { 1479 int oldMinDigits = getMinimumFractionDigits(); 1480 // Common patterns are "#.##", "#.00", "#". 1481 // Try to adjust all of them in a reasonable way. 1482 if (oldMinDigits == getMaximumFractionDigits()) { 1483 setMinimumFractionDigits(digits); 1484 setMaximumFractionDigits(digits); 1485 } else { 1486 setMinimumFractionDigits(Math.min(digits, oldMinDigits)); 1487 setMaximumFractionDigits(digits); 1488 } 1489 } 1490 } 1491 } 1492 1493 private static final int currentSerialVersion = 4; 1494 1495 // the fields list to be serialized 1496 private static final ObjectStreamField[] serialPersistentFields = { 1497 new ObjectStreamField("positivePrefix", String.class), 1498 new ObjectStreamField("positiveSuffix", String.class), 1499 new ObjectStreamField("negativePrefix", String.class), 1500 new ObjectStreamField("negativeSuffix", String.class), 1501 new ObjectStreamField("posPrefixPattern", String.class), 1502 new ObjectStreamField("posSuffixPattern", String.class), 1503 new ObjectStreamField("negPrefixPattern", String.class), 1504 new ObjectStreamField("negSuffixPattern", String.class), 1505 new ObjectStreamField("multiplier", int.class), 1506 new ObjectStreamField("groupingSize", byte.class), 1507 new ObjectStreamField("groupingUsed", boolean.class), 1508 new ObjectStreamField("decimalSeparatorAlwaysShown", boolean.class), 1509 new ObjectStreamField("parseBigDecimal", boolean.class), 1510 new ObjectStreamField("roundingMode", RoundingMode.class), 1511 new ObjectStreamField("symbols", DecimalFormatSymbols.class), 1512 new ObjectStreamField("useExponentialNotation", boolean.class), 1513 new ObjectStreamField("minExponentDigits", byte.class), 1514 new ObjectStreamField("maximumIntegerDigits", int.class), 1515 new ObjectStreamField("minimumIntegerDigits", int.class), 1516 new ObjectStreamField("maximumFractionDigits", int.class), 1517 new ObjectStreamField("minimumFractionDigits", int.class), 1518 new ObjectStreamField("serialVersionOnStream", int.class), 1519 }; 1520 writeObject(ObjectOutputStream stream)1521 private void writeObject(ObjectOutputStream stream) throws IOException, ClassNotFoundException { 1522 ObjectOutputStream.PutField fields = stream.putFields(); 1523 fields.put("positivePrefix", icuDecimalFormat.getPositivePrefix()); 1524 fields.put("positiveSuffix", icuDecimalFormat.getPositiveSuffix()); 1525 fields.put("negativePrefix", icuDecimalFormat.getNegativePrefix()); 1526 fields.put("negativeSuffix", icuDecimalFormat.getNegativeSuffix()); 1527 fields.put("posPrefixPattern", (String) null); 1528 fields.put("posSuffixPattern", (String) null); 1529 fields.put("negPrefixPattern", (String) null); 1530 fields.put("negSuffixPattern", (String) null); 1531 fields.put("multiplier", icuDecimalFormat.getMultiplier()); 1532 fields.put("groupingSize", (byte) icuDecimalFormat.getGroupingSize()); 1533 fields.put("groupingUsed", icuDecimalFormat.isGroupingUsed()); 1534 fields.put("decimalSeparatorAlwaysShown", icuDecimalFormat.isDecimalSeparatorAlwaysShown()); 1535 fields.put("parseBigDecimal", icuDecimalFormat.isParseBigDecimal()); 1536 fields.put("roundingMode", roundingMode); 1537 fields.put("symbols", symbols); 1538 fields.put("useExponentialNotation", false); 1539 fields.put("minExponentDigits", (byte) 0); 1540 fields.put("maximumIntegerDigits", icuDecimalFormat.getMaximumIntegerDigits()); 1541 fields.put("minimumIntegerDigits", icuDecimalFormat.getMinimumIntegerDigits()); 1542 fields.put("maximumFractionDigits", icuDecimalFormat.getMaximumFractionDigits()); 1543 fields.put("minimumFractionDigits", icuDecimalFormat.getMinimumFractionDigits()); 1544 fields.put("serialVersionOnStream", currentSerialVersion); 1545 stream.writeFields(); 1546 } 1547 1548 /** 1549 * Reads the default serializable fields from the stream and performs 1550 * validations and adjustments for older serialized versions. The 1551 * validations and adjustments are: 1552 * <ol> 1553 * <li> 1554 * Verify that the superclass's digit count fields correctly reflect 1555 * the limits imposed on formatting numbers other than 1556 * <code>BigInteger</code> and <code>BigDecimal</code> objects. These 1557 * limits are stored in the superclass for serialization compatibility 1558 * with older versions, while the limits for <code>BigInteger</code> and 1559 * <code>BigDecimal</code> objects are kept in this class. 1560 * If, in the superclass, the minimum or maximum integer digit count is 1561 * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or 1562 * maximum fraction digit count is larger than 1563 * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid 1564 * and this method throws an <code>InvalidObjectException</code>. 1565 * <li> 1566 * If <code>serialVersionOnStream</code> is less than 4, initialize 1567 * <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN 1568 * RoundingMode.HALF_EVEN}. This field is new with version 4. 1569 * <li> 1570 * If <code>serialVersionOnStream</code> is less than 3, then call 1571 * the setters for the minimum and maximum integer and fraction digits with 1572 * the values of the corresponding superclass getters to initialize the 1573 * fields in this class. The fields in this class are new with version 3. 1574 * <li> 1575 * If <code>serialVersionOnStream</code> is less than 1, indicating that 1576 * the stream was written by JDK 1.1, initialize 1577 * <code>useExponentialNotation</code> 1578 * to false, since it was not present in JDK 1.1. 1579 * <li> 1580 * Set <code>serialVersionOnStream</code> to the maximum allowed value so 1581 * that default serialization will work properly if this object is streamed 1582 * out again. 1583 * </ol> 1584 * 1585 * <p>Stream versions older than 2 will not have the affix pattern variables 1586 * <code>posPrefixPattern</code> etc. As a result, they will be initialized 1587 * to <code>null</code>, which means the affix strings will be taken as 1588 * literal values. This is exactly what we want, since that corresponds to 1589 * the pre-version-2 behavior. 1590 */ readObject(ObjectInputStream stream)1591 private void readObject(ObjectInputStream stream) 1592 throws IOException, ClassNotFoundException { 1593 ObjectInputStream.GetField fields = stream.readFields(); 1594 this.symbols = (DecimalFormatSymbols) fields.get("symbols", null); 1595 1596 init(""); 1597 1598 icuDecimalFormat.setPositivePrefix((String) fields.get("positivePrefix", "")); 1599 icuDecimalFormat.setPositiveSuffix((String) fields.get("positiveSuffix", "")); 1600 icuDecimalFormat.setNegativePrefix((String) fields.get("negativePrefix", "-")); 1601 icuDecimalFormat.setNegativeSuffix((String) fields.get("negativeSuffix", "")); 1602 icuDecimalFormat.setMultiplier(fields.get("multiplier", 1)); 1603 icuDecimalFormat.setGroupingSize(fields.get("groupingSize", (byte) 3)); 1604 icuDecimalFormat.setGroupingUsed(fields.get("groupingUsed", true)); 1605 icuDecimalFormat.setDecimalSeparatorAlwaysShown(fields.get("decimalSeparatorAlwaysShown", 1606 false)); 1607 1608 setRoundingMode((RoundingMode) fields.get("roundingMode", RoundingMode.HALF_EVEN)); 1609 1610 final int maximumIntegerDigits = fields.get("maximumIntegerDigits", 309); 1611 final int minimumIntegerDigits = fields.get("minimumIntegerDigits", 309); 1612 final int maximumFractionDigits = fields.get("maximumFractionDigits", 340); 1613 final int minimumFractionDigits = fields.get("minimumFractionDigits", 340); 1614 // Tell ICU what we want, then ask it what we can have, and then 1615 // set that in our Java object. This isn't RI-compatible, but then very little of our 1616 // behavior in this area is, and it's not obvious how we can second-guess ICU (or tell 1617 // it to just do exactly what we ask). We only need to do this with maximumIntegerDigits 1618 // because ICU doesn't seem to have its own ideas about the other options. 1619 icuDecimalFormat.setMaximumIntegerDigits(maximumIntegerDigits); 1620 super.setMaximumIntegerDigits(icuDecimalFormat.getMaximumIntegerDigits()); 1621 1622 setMinimumIntegerDigits(minimumIntegerDigits); 1623 setMinimumFractionDigits(minimumFractionDigits); 1624 setMaximumFractionDigits(maximumFractionDigits); 1625 setParseBigDecimal(fields.get("parseBigDecimal", false)); 1626 1627 if (fields.get("serialVersionOnStream", 0) < 3) { 1628 setMaximumIntegerDigits(super.getMaximumIntegerDigits()); 1629 setMinimumIntegerDigits(super.getMinimumIntegerDigits()); 1630 setMaximumFractionDigits(super.getMaximumFractionDigits()); 1631 setMinimumFractionDigits(super.getMinimumFractionDigits()); 1632 } 1633 } 1634 1635 //---------------------------------------------------------------------- 1636 // INSTANCE VARIABLES 1637 //---------------------------------------------------------------------- 1638 1639 /** 1640 * The <code>DecimalFormatSymbols</code> object used by this format. 1641 * It contains the symbols used to format numbers, e.g. the grouping separator, 1642 * decimal separator, and so on. 1643 * 1644 * @serial 1645 * @see #setDecimalFormatSymbols 1646 * @see java.text.DecimalFormatSymbols 1647 */ 1648 private DecimalFormatSymbols symbols; 1649 1650 /** 1651 * The maximum number of digits allowed in the integer portion of a 1652 * <code>BigInteger</code> or <code>BigDecimal</code> number. 1653 * <code>maximumIntegerDigits</code> must be greater than or equal to 1654 * <code>minimumIntegerDigits</code>. 1655 * 1656 * @serial 1657 * @see #getMaximumIntegerDigits 1658 * @since 1.5 1659 */ 1660 private int maximumIntegerDigits; 1661 1662 /** 1663 * The minimum number of digits allowed in the integer portion of a 1664 * <code>BigInteger</code> or <code>BigDecimal</code> number. 1665 * <code>minimumIntegerDigits</code> must be less than or equal to 1666 * <code>maximumIntegerDigits</code>. 1667 * 1668 * @serial 1669 * @see #getMinimumIntegerDigits 1670 * @since 1.5 1671 */ 1672 private int minimumIntegerDigits; 1673 1674 /** 1675 * The maximum number of digits allowed in the fractional portion of a 1676 * <code>BigInteger</code> or <code>BigDecimal</code> number. 1677 * <code>maximumFractionDigits</code> must be greater than or equal to 1678 * <code>minimumFractionDigits</code>. 1679 * 1680 * @serial 1681 * @see #getMaximumFractionDigits 1682 * @since 1.5 1683 */ 1684 private int maximumFractionDigits; 1685 1686 /** 1687 * The minimum number of digits allowed in the fractional portion of a 1688 * <code>BigInteger</code> or <code>BigDecimal</code> number. 1689 * <code>minimumFractionDigits</code> must be less than or equal to 1690 * <code>maximumFractionDigits</code>. 1691 * 1692 * @serial 1693 * @see #getMinimumFractionDigits 1694 * @since 1.5 1695 */ 1696 private int minimumFractionDigits; 1697 1698 /** 1699 * The {@link java.math.RoundingMode} used in this DecimalFormat. 1700 * 1701 * @serial 1702 * @since 1.6 1703 */ 1704 private RoundingMode roundingMode = RoundingMode.HALF_EVEN; 1705 1706 1707 1708 //---------------------------------------------------------------------- 1709 // CONSTANTS 1710 //---------------------------------------------------------------------- 1711 1712 // Upper limit on integer and fraction digits for a Java double 1713 static final int DOUBLE_INTEGER_DIGITS = 309; 1714 static final int DOUBLE_FRACTION_DIGITS = 340; 1715 1716 // Upper limit on integer and fraction digits for BigDecimal and BigInteger 1717 static final int MAXIMUM_INTEGER_DIGITS = Integer.MAX_VALUE; 1718 static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE; 1719 1720 // Proclaim JDK 1.1 serial compatibility. 1721 static final long serialVersionUID = 864413376551465018L; 1722 1723 /** 1724 * Cache to hold the NumberPattern of a Locale. 1725 */ 1726 private static final ConcurrentMap<Locale, String> cachedLocaleData 1727 = new ConcurrentHashMap<Locale, String>(3); 1728 } 1729