1 /* 2 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved 28 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved 29 * 30 * The original version of this source code and documentation is copyrighted 31 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These 32 * materials are provided under terms of a License Agreement between Taligent 33 * and Sun. This technology is protected by multiple US and International 34 * patents. This notice and attribution to Taligent may not be removed. 35 * Taligent is a registered trademark of Taligent, Inc. 36 * 37 */ 38 39 package java.text; 40 41 import java.io.InvalidObjectException; 42 import java.io.IOException; 43 import java.io.ObjectInputStream; 44 import java.math.BigDecimal; 45 import java.math.BigInteger; 46 import java.math.RoundingMode; 47 import java.util.ArrayList; 48 import java.util.Currency; 49 import java.util.Locale; 50 import java.util.ResourceBundle; 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 sun.util.resources.LocaleData; 56 57 /** 58 * <code>DecimalFormat</code> is a concrete subclass of 59 * <code>NumberFormat</code> that formats decimal numbers. It has a variety of 60 * features designed to make it possible to parse and format numbers in any 61 * locale, including support for Western, Arabic, and Indic digits. It also 62 * supports different kinds of numbers, including integers (123), fixed-point 63 * numbers (123.4), scientific notation (1.23E4), percentages (12%), and 64 * currency amounts ($123). All of these can be localized. 65 * 66 * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the 67 * default locale, call one of <code>NumberFormat</code>'s factory methods, such 68 * as <code>getInstance()</code>. In general, do not call the 69 * <code>DecimalFormat</code> constructors directly, since the 70 * <code>NumberFormat</code> factory methods may return subclasses other than 71 * <code>DecimalFormat</code>. If you need to customize the format object, do 72 * something like this: 73 * 74 * <blockquote><pre> 75 * NumberFormat f = NumberFormat.getInstance(loc); 76 * if (f instanceof DecimalFormat) { 77 * ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true); 78 * } 79 * </pre></blockquote> 80 * 81 * <p>A <code>DecimalFormat</code> comprises a <em>pattern</em> and a set of 82 * <em>symbols</em>. The pattern may be set directly using 83 * <code>applyPattern()</code>, or indirectly using the API methods. The 84 * symbols are stored in a <code>DecimalFormatSymbols</code> object. When using 85 * the <code>NumberFormat</code> factory methods, the pattern and symbols are 86 * read from localized <code>ResourceBundle</code>s. 87 * 88 * <h4>Patterns</h4> 89 * 90 * <code>DecimalFormat</code> patterns have the following syntax: 91 * <blockquote><pre> 92 * <i>Pattern:</i> 93 * <i>PositivePattern</i> 94 * <i>PositivePattern</i> ; <i>NegativePattern</i> 95 * <i>PositivePattern:</i> 96 * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i> 97 * <i>NegativePattern:</i> 98 * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i> 99 * <i>Prefix:</i> 100 * any Unicode characters except \uFFFE, \uFFFF, and special characters 101 * <i>Suffix:</i> 102 * any Unicode characters except \uFFFE, \uFFFF, and special characters 103 * <i>Number:</i> 104 * <i>Integer</i> <i>Exponent<sub>opt</sub></i> 105 * <i>Integer</i> . <i>Fraction</i> <i>Exponent<sub>opt</sub></i> 106 * <i>Integer:</i> 107 * <i>MinimumInteger</i> 108 * # 109 * # <i>Integer</i> 110 * # , <i>Integer</i> 111 * <i>MinimumInteger:</i> 112 * 0 113 * 0 <i>MinimumInteger</i> 114 * 0 , <i>MinimumInteger</i> 115 * <i>Fraction:</i> 116 * <i>MinimumFraction<sub>opt</sub></i> <i>OptionalFraction<sub>opt</sub></i> 117 * <i>MinimumFraction:</i> 118 * 0 <i>MinimumFraction<sub>opt</sub></i> 119 * <i>OptionalFraction:</i> 120 * # <i>OptionalFraction<sub>opt</sub></i> 121 * <i>Exponent:</i> 122 * E <i>MinimumExponent</i> 123 * <i>MinimumExponent:</i> 124 * 0 <i>MinimumExponent<sub>opt</sub></i> 125 * </pre></blockquote> 126 * 127 * <p>A <code>DecimalFormat</code> pattern contains a positive and negative 128 * subpattern, for example, <code>"#,##0.00;(#,##0.00)"</code>. Each 129 * subpattern has a prefix, numeric part, and suffix. The negative subpattern 130 * is optional; if absent, then the positive subpattern prefixed with the 131 * localized minus sign (<code>'-'</code> in most locales) is used as the 132 * negative subpattern. That is, <code>"0.00"</code> alone is equivalent to 133 * <code>"0.00;-0.00"</code>. If there is an explicit negative subpattern, it 134 * serves only to specify the negative prefix and suffix; the number of digits, 135 * minimal digits, and other characteristics are all the same as the positive 136 * pattern. That means that <code>"#,##0.0#;(#)"</code> produces precisely 137 * the same behavior as <code>"#,##0.0#;(#,##0.0#)"</code>. 138 * 139 * <p>The prefixes, suffixes, and various symbols used for infinity, digits, 140 * thousands separators, decimal separators, etc. may be set to arbitrary 141 * values, and they will appear properly during formatting. However, care must 142 * be taken that the symbols and strings do not conflict, or parsing will be 143 * unreliable. For example, either the positive and negative prefixes or the 144 * suffixes must be distinct for <code>DecimalFormat.parse()</code> to be able 145 * to distinguish positive from negative values. (If they are identical, then 146 * <code>DecimalFormat</code> will behave as if no negative subpattern was 147 * specified.) Another example is that the decimal separator and thousands 148 * separator should be distinct characters, or parsing will be impossible. 149 * 150 * <p>The grouping separator is commonly used for thousands, but in some 151 * countries it separates ten-thousands. The grouping size is a constant number 152 * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for 153 * 1,0000,0000. If you supply a pattern with multiple grouping characters, the 154 * interval between the last one and the end of the integer is the one that is 155 * used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> == 156 * <code>"##,####,####"</code>. 157 * 158 * <h4>Special Pattern Characters</h4> 159 * 160 * <p>Many characters in a pattern are taken literally; they are matched during 161 * parsing and output unchanged during formatting. Special characters, on the 162 * other hand, stand for other characters, strings, or classes of characters. 163 * They must be quoted, unless noted otherwise, if they are to appear in the 164 * prefix or suffix as literals. 165 * 166 * <p>The characters listed here are used in non-localized patterns. Localized 167 * patterns use the corresponding characters taken from this formatter's 168 * <code>DecimalFormatSymbols</code> object instead, and these characters lose 169 * their special status. Two exceptions are the currency sign and quote, which 170 * are not localized. 171 * 172 * <blockquote> 173 * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol, 174 * location, localized, and meaning."> 175 * <tr bgcolor="#ccccff"> 176 * <th align=left>Symbol 177 * <th align=left>Location 178 * <th align=left>Localized? 179 * <th align=left>Meaning 180 * <tr valign=top> 181 * <td><code>0</code> 182 * <td>Number 183 * <td>Yes 184 * <td>Digit 185 * <tr valign=top bgcolor="#eeeeff"> 186 * <td><code>#</code> 187 * <td>Number 188 * <td>Yes 189 * <td>Digit, zero shows as absent 190 * <tr valign=top> 191 * <td><code>.</code> 192 * <td>Number 193 * <td>Yes 194 * <td>Decimal separator or monetary decimal separator 195 * <tr valign=top bgcolor="#eeeeff"> 196 * <td><code>-</code> 197 * <td>Number 198 * <td>Yes 199 * <td>Minus sign 200 * <tr valign=top> 201 * <td><code>,</code> 202 * <td>Number 203 * <td>Yes 204 * <td>Grouping separator 205 * <tr valign=top bgcolor="#eeeeff"> 206 * <td><code>E</code> 207 * <td>Number 208 * <td>Yes 209 * <td>Separates mantissa and exponent in scientific notation. 210 * <em>Need not be quoted in prefix or suffix.</em> 211 * <tr valign=top> 212 * <td><code>;</code> 213 * <td>Subpattern boundary 214 * <td>Yes 215 * <td>Separates positive and negative subpatterns 216 * <tr valign=top bgcolor="#eeeeff"> 217 * <td><code>%</code> 218 * <td>Prefix or suffix 219 * <td>Yes 220 * <td>Multiply by 100 and show as percentage 221 * <tr valign=top> 222 * <td><code>\u2030</code> 223 * <td>Prefix or suffix 224 * <td>Yes 225 * <td>Multiply by 1000 and show as per mille value 226 * <tr valign=top bgcolor="#eeeeff"> 227 * <td><code>¤</code> (<code>\u00A4</code>) 228 * <td>Prefix or suffix 229 * <td>No 230 * <td>Currency sign, replaced by currency symbol. If 231 * doubled, replaced by international currency symbol. 232 * If present in a pattern, the monetary decimal separator 233 * is used instead of the decimal separator. 234 * <tr valign=top> 235 * <td><code>'</code> 236 * <td>Prefix or suffix 237 * <td>No 238 * <td>Used to quote special characters in a prefix or suffix, 239 * for example, <code>"'#'#"</code> formats 123 to 240 * <code>"#123"</code>. To create a single quote 241 * itself, use two in a row: <code>"# o''clock"</code>. 242 * </table> 243 * </blockquote> 244 * 245 * <h4>Scientific Notation</h4> 246 * 247 * <p>Numbers in scientific notation are expressed as the product of a mantissa 248 * and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3. The 249 * mantissa is often in the range 1.0 <= x < 10.0, but it need not be. 250 * <code>DecimalFormat</code> can be instructed to format and parse scientific 251 * notation <em>only via a pattern</em>; there is currently no factory method 252 * that creates a scientific notation format. In a pattern, the exponent 253 * character immediately followed by one or more digit characters indicates 254 * scientific notation. Example: <code>"0.###E0"</code> formats the number 255 * 1234 as <code>"1.234E3"</code>. 256 * 257 * <ul> 258 * <li>The number of digit characters after the exponent character gives the 259 * minimum exponent digit count. There is no maximum. Negative exponents are 260 * formatted using the localized minus sign, <em>not</em> the prefix and suffix 261 * from the pattern. This allows patterns such as <code>"0.###E0 m/s"</code>. 262 * 263 * <li>The minimum and maximum number of integer digits are interpreted 264 * together: 265 * 266 * <ul> 267 * <li>If the maximum number of integer digits is greater than their minimum number 268 * and greater than 1, it forces the exponent to be a multiple of the maximum 269 * number of integer digits, and the minimum number of integer digits to be 270 * interpreted as 1. The most common use of this is to generate 271 * <em>engineering notation</em>, in which the exponent is a multiple of three, 272 * e.g., <code>"##0.#####E0"</code>. Using this pattern, the number 12345 273 * formats to <code>"12.345E3"</code>, and 123456 formats to 274 * <code>"123.456E3"</code>. 275 * 276 * <li>Otherwise, the minimum number of integer digits is achieved by adjusting the 277 * exponent. Example: 0.00123 formatted with <code>"00.###E0"</code> yields 278 * <code>"12.3E-4"</code>. 279 * </ul> 280 * 281 * <li>The number of significant digits in the mantissa is the sum of the 282 * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is 283 * unaffected by the maximum integer digits. For example, 12345 formatted with 284 * <code>"##0.##E0"</code> is <code>"12.3E3"</code>. To show all digits, set 285 * the significant digits count to zero. The number of significant digits 286 * does not affect parsing. 287 * 288 * <li>Exponential patterns may not contain grouping separators. 289 * </ul> 290 * 291 * <h4>Rounding</h4> 292 * 293 * <code>DecimalFormat</code> provides rounding modes defined in 294 * {@link java.math.RoundingMode} for formatting. By default, it uses 295 * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}. 296 * 297 * <h4>Digits</h4> 298 * 299 * For formatting, <code>DecimalFormat</code> uses the ten consecutive 300 * characters starting with the localized zero digit defined in the 301 * <code>DecimalFormatSymbols</code> object as digits. For parsing, these 302 * digits as well as all Unicode decimal digits, as defined by 303 * {@link Character#digit Character.digit}, are recognized. 304 * 305 * <h4>Special Values</h4> 306 * 307 * <p><code>NaN</code> is formatted as a string, which typically has a single character 308 * <code>\uFFFD</code>. This string is determined by the 309 * <code>DecimalFormatSymbols</code> object. This is the only value for which 310 * the prefixes and suffixes are not used. 311 * 312 * <p>Infinity is formatted as a string, which typically has a single character 313 * <code>\u221E</code>, with the positive or negative prefixes and suffixes 314 * applied. The infinity string is determined by the 315 * <code>DecimalFormatSymbols</code> object. 316 * 317 * <p>Negative zero (<code>"-0"</code>) parses to 318 * <ul> 319 * <li><code>BigDecimal(0)</code> if <code>isParseBigDecimal()</code> is 320 * true, 321 * <li><code>Long(0)</code> if <code>isParseBigDecimal()</code> is false 322 * and <code>isParseIntegerOnly()</code> is true, 323 * <li><code>Double(-0.0)</code> if both <code>isParseBigDecimal()</code> 324 * and <code>isParseIntegerOnly()</code> are false. 325 * </ul> 326 * 327 * <h4><a name="synchronization">Synchronization</a></h4> 328 * 329 * <p> 330 * Decimal formats are generally not synchronized. 331 * It is recommended to create separate format instances for each thread. 332 * If multiple threads access a format concurrently, it must be synchronized 333 * externally. 334 * 335 * <h4>Example</h4> 336 * 337 * <blockquote><pre> 338 * <strong>// Print out a number using the localized number, integer, currency, 339 * // and percent format for each locale</strong> 340 * Locale[] locales = NumberFormat.getAvailableLocales(); 341 * double myNumber = -1234.56; 342 * NumberFormat form; 343 * for (int j=0; j<4; ++j) { 344 * System.out.println("FORMAT"); 345 * for (int i = 0; i < locales.length; ++i) { 346 * if (locales[i].getCountry().length() == 0) { 347 * continue; // Skip language-only locales 348 * } 349 * System.out.print(locales[i].getDisplayName()); 350 * switch (j) { 351 * case 0: 352 * form = NumberFormat.getInstance(locales[i]); break; 353 * case 1: 354 * form = NumberFormat.getIntegerInstance(locales[i]); break; 355 * case 2: 356 * form = NumberFormat.getCurrencyInstance(locales[i]); break; 357 * default: 358 * form = NumberFormat.getPercentInstance(locales[i]); break; 359 * } 360 * if (form instanceof DecimalFormat) { 361 * System.out.print(": " + ((DecimalFormat) form).toPattern()); 362 * } 363 * System.out.print(" -> " + form.format(myNumber)); 364 * try { 365 * System.out.println(" -> " + form.parse(form.format(myNumber))); 366 * } catch (ParseException e) {} 367 * } 368 * } 369 * </pre></blockquote> 370 * 371 * @see <a href="http://java.sun.com/docs/books/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a> 372 * @see NumberFormat 373 * @see DecimalFormatSymbols 374 * @see ParsePosition 375 * @author Mark Davis 376 * @author Alan Liu 377 */ 378 public class DecimalFormat extends NumberFormat { 379 380 /** 381 * Creates a DecimalFormat using the default pattern and symbols 382 * for the default locale. This is a convenient way to obtain a 383 * DecimalFormat when internationalization is not the main concern. 384 * <p> 385 * To obtain standard formats for a given locale, use the factory methods 386 * on NumberFormat such as getNumberInstance. These factories will 387 * return the most appropriate sub-class of NumberFormat for a given 388 * locale. 389 * 390 * @see java.text.NumberFormat#getInstance 391 * @see java.text.NumberFormat#getNumberInstance 392 * @see java.text.NumberFormat#getCurrencyInstance 393 * @see java.text.NumberFormat#getPercentInstance 394 */ 395 public DecimalFormat() { 396 Locale def = Locale.getDefault(Locale.Category.FORMAT); 397 // try to get the pattern from the cache 398 String pattern = cachedLocaleData.get(def); 399 if (pattern == null) { /* cache miss */ 400 // Get the pattern for the default locale. 401 ResourceBundle rb = LocaleData.getNumberFormatData(def); 402 String[] all = rb.getStringArray("NumberPatterns"); 403 pattern = all[0]; 404 /* update cache */ 405 cachedLocaleData.putIfAbsent(def, pattern); 406 } 407 408 // Always applyPattern after the symbols are set 409 this.symbols = new DecimalFormatSymbols(def); 410 applyPattern(pattern, false); 411 } 412 413 414 /** 415 * Creates a DecimalFormat using the given pattern and the symbols 416 * for the default locale. This is a convenient way to obtain a 417 * DecimalFormat when internationalization is not the main concern. 418 * <p> 419 * To obtain standard formats for a given locale, use the factory methods 420 * on NumberFormat such as getNumberInstance. These factories will 421 * return the most appropriate sub-class of NumberFormat for a given 422 * locale. 423 * 424 * @param pattern A non-localized pattern string. 425 * @exception NullPointerException if <code>pattern</code> is null 426 * @exception IllegalArgumentException if the given pattern is invalid. 427 * @see java.text.NumberFormat#getInstance 428 * @see java.text.NumberFormat#getNumberInstance 429 * @see java.text.NumberFormat#getCurrencyInstance 430 * @see java.text.NumberFormat#getPercentInstance 431 */ 432 public DecimalFormat(String pattern) { 433 // Always applyPattern after the symbols are set 434 this.symbols = new DecimalFormatSymbols(Locale.getDefault(Locale.Category.FORMAT)); 435 applyPattern(pattern, false); 436 } 437 438 439 /** 440 * Creates a DecimalFormat using the given pattern and symbols. 441 * Use this constructor when you need to completely customize the 442 * behavior of the format. 443 * <p> 444 * To obtain standard formats for a given 445 * locale, use the factory methods on NumberFormat such as 446 * getInstance or getCurrencyInstance. If you need only minor adjustments 447 * to a standard format, you can modify the format returned by 448 * a NumberFormat factory method. 449 * 450 * @param pattern a non-localized pattern string 451 * @param symbols the set of symbols to be used 452 * @exception NullPointerException if any of the given arguments is null 453 * @exception IllegalArgumentException if the given pattern is invalid 454 * @see java.text.NumberFormat#getInstance 455 * @see java.text.NumberFormat#getNumberInstance 456 * @see java.text.NumberFormat#getCurrencyInstance 457 * @see java.text.NumberFormat#getPercentInstance 458 * @see java.text.DecimalFormatSymbols 459 */ 460 public DecimalFormat (String pattern, DecimalFormatSymbols symbols) { 461 // Always applyPattern after the symbols are set 462 this.symbols = (DecimalFormatSymbols)symbols.clone(); 463 applyPattern(pattern, false); 464 } 465 466 467 // Overrides 468 /** 469 * Formats a number and appends the resulting text to the given string 470 * buffer. 471 * The number can be of any subclass of {@link java.lang.Number}. 472 * <p> 473 * This implementation uses the maximum precision permitted. 474 * @param number the number to format 475 * @param toAppendTo the <code>StringBuffer</code> to which the formatted 476 * text is to be appended 477 * @param pos On input: an alignment field, if desired. 478 * On output: the offsets of the alignment field. 479 * @return the value passed in as <code>toAppendTo</code> 480 * @exception IllegalArgumentException if <code>number</code> is 481 * null or not an instance of <code>Number</code>. 482 * @exception NullPointerException if <code>toAppendTo</code> or 483 * <code>pos</code> is null 484 * @exception ArithmeticException if rounding is needed with rounding 485 * mode being set to RoundingMode.UNNECESSARY 486 * @see java.text.FieldPosition 487 */ 488 public final StringBuffer format(Object number, 489 StringBuffer toAppendTo, 490 FieldPosition pos) { 491 if (number instanceof Long || number instanceof Integer || 492 number instanceof Short || number instanceof Byte || 493 number instanceof AtomicInteger || 494 number instanceof AtomicLong || 495 (number instanceof BigInteger && 496 ((BigInteger)number).bitLength () < 64)) { 497 return format(((Number)number).longValue(), toAppendTo, pos); 498 } else if (number instanceof BigDecimal) { 499 return format((BigDecimal)number, toAppendTo, pos); 500 } else if (number instanceof BigInteger) { 501 return format((BigInteger)number, toAppendTo, pos); 502 } else if (number instanceof Number) { 503 return format(((Number)number).doubleValue(), toAppendTo, pos); 504 } else { 505 throw new IllegalArgumentException("Cannot format given Object as a Number"); 506 } 507 } 508 509 /** 510 * Formats a double to produce a string. 511 * @param number The double to format 512 * @param result where the text is to be appended 513 * @param fieldPosition On input: an alignment field, if desired. 514 * On output: the offsets of the alignment field. 515 * @exception ArithmeticException if rounding is needed with rounding 516 * mode being set to RoundingMode.UNNECESSARY 517 * @return The formatted number string 518 * @see java.text.FieldPosition 519 */ 520 public StringBuffer format(double number, StringBuffer result, 521 FieldPosition fieldPosition) { 522 fieldPosition.setBeginIndex(0); 523 fieldPosition.setEndIndex(0); 524 525 return format(number, result, fieldPosition.getFieldDelegate()); 526 } 527 528 /** 529 * Formats a double to produce a string. 530 * @param number The double to format 531 * @param result where the text is to be appended 532 * @param delegate notified of locations of sub fields 533 * @exception ArithmeticException if rounding is needed with rounding 534 * mode being set to RoundingMode.UNNECESSARY 535 * @return The formatted number string 536 */ 537 private StringBuffer format(double number, StringBuffer result, 538 FieldDelegate delegate) { 539 if (Double.isNaN(number) || 540 (Double.isInfinite(number) && multiplier == 0)) { 541 int iFieldStart = result.length(); 542 result.append(symbols.getNaN()); 543 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER, 544 iFieldStart, result.length(), result); 545 return result; 546 } 547 548 /* Detecting whether a double is negative is easy with the exception of 549 * the value -0.0. This is a double which has a zero mantissa (and 550 * exponent), but a negative sign bit. It is semantically distinct from 551 * a zero with a positive sign bit, and this distinction is important 552 * to certain kinds of computations. However, it's a little tricky to 553 * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0). How then, you may 554 * ask, does it behave distinctly from +0.0? Well, 1/(-0.0) == 555 * -Infinity. Proper detection of -0.0 is needed to deal with the 556 * issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98. 557 */ 558 boolean isNegative = ((number < 0.0) || (number == 0.0 && 1/number < 0.0)) ^ (multiplier < 0); 559 560 if (multiplier != 1) { 561 number *= multiplier; 562 } 563 564 if (Double.isInfinite(number)) { 565 if (isNegative) { 566 append(result, negativePrefix, delegate, 567 getNegativePrefixFieldPositions(), Field.SIGN); 568 } else { 569 append(result, positivePrefix, delegate, 570 getPositivePrefixFieldPositions(), Field.SIGN); 571 } 572 573 int iFieldStart = result.length(); 574 result.append(symbols.getInfinity()); 575 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER, 576 iFieldStart, result.length(), result); 577 578 if (isNegative) { 579 append(result, negativeSuffix, delegate, 580 getNegativeSuffixFieldPositions(), Field.SIGN); 581 } else { 582 append(result, positiveSuffix, delegate, 583 getPositiveSuffixFieldPositions(), Field.SIGN); 584 } 585 586 return result; 587 } 588 589 if (isNegative) { 590 number = -number; 591 } 592 593 // at this point we are guaranteed a nonnegative finite number. 594 assert(number >= 0 && !Double.isInfinite(number)); 595 596 synchronized(digitList) { 597 int maxIntDigits = super.getMaximumIntegerDigits(); 598 int minIntDigits = super.getMinimumIntegerDigits(); 599 int maxFraDigits = super.getMaximumFractionDigits(); 600 int minFraDigits = super.getMinimumFractionDigits(); 601 602 digitList.set(isNegative, number, useExponentialNotation ? 603 maxIntDigits + maxFraDigits : maxFraDigits, 604 !useExponentialNotation); 605 return subformat(result, delegate, isNegative, false, 606 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits); 607 } 608 } 609 610 /** 611 * Format a long to produce a string. 612 * @param number The long to format 613 * @param result where the text is to be appended 614 * @param fieldPosition On input: an alignment field, if desired. 615 * On output: the offsets of the alignment field. 616 * @exception ArithmeticException if rounding is needed with rounding 617 * mode being set to RoundingMode.UNNECESSARY 618 * @return The formatted number string 619 * @see java.text.FieldPosition 620 */ 621 public StringBuffer format(long number, StringBuffer result, 622 FieldPosition fieldPosition) { 623 fieldPosition.setBeginIndex(0); 624 fieldPosition.setEndIndex(0); 625 626 return format(number, result, fieldPosition.getFieldDelegate()); 627 } 628 629 /** 630 * Format a long to produce a string. 631 * @param number The long to format 632 * @param result where the text is to be appended 633 * @param delegate notified of locations of sub fields 634 * @return The formatted number string 635 * @exception ArithmeticException if rounding is needed with rounding 636 * mode being set to RoundingMode.UNNECESSARY 637 * @see java.text.FieldPosition 638 */ 639 private StringBuffer format(long number, StringBuffer result, 640 FieldDelegate delegate) { 641 boolean isNegative = (number < 0); 642 if (isNegative) { 643 number = -number; 644 } 645 646 // In general, long values always represent real finite numbers, so 647 // we don't have to check for +/- Infinity or NaN. However, there 648 // is one case we have to be careful of: The multiplier can push 649 // a number near MIN_VALUE or MAX_VALUE outside the legal range. We 650 // check for this before multiplying, and if it happens we use 651 // BigInteger instead. 652 boolean useBigInteger = false; 653 if (number < 0) { // This can only happen if number == Long.MIN_VALUE. 654 if (multiplier != 0) { 655 useBigInteger = true; 656 } 657 } else if (multiplier != 1 && multiplier != 0) { 658 long cutoff = Long.MAX_VALUE / multiplier; 659 if (cutoff < 0) { 660 cutoff = -cutoff; 661 } 662 useBigInteger = (number > cutoff); 663 } 664 665 if (useBigInteger) { 666 if (isNegative) { 667 number = -number; 668 } 669 BigInteger bigIntegerValue = BigInteger.valueOf(number); 670 return format(bigIntegerValue, result, delegate, true); 671 } 672 673 number *= multiplier; 674 if (number == 0) { 675 isNegative = false; 676 } else { 677 if (multiplier < 0) { 678 number = -number; 679 isNegative = !isNegative; 680 } 681 } 682 683 synchronized(digitList) { 684 int maxIntDigits = super.getMaximumIntegerDigits(); 685 int minIntDigits = super.getMinimumIntegerDigits(); 686 int maxFraDigits = super.getMaximumFractionDigits(); 687 int minFraDigits = super.getMinimumFractionDigits(); 688 689 digitList.set(isNegative, number, 690 useExponentialNotation ? maxIntDigits + maxFraDigits : 0); 691 692 return subformat(result, delegate, isNegative, true, 693 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits); 694 } 695 } 696 697 /** 698 * Formats a BigDecimal to produce a string. 699 * @param number The BigDecimal to format 700 * @param result where the text is to be appended 701 * @param fieldPosition On input: an alignment field, if desired. 702 * On output: the offsets of the alignment field. 703 * @return The formatted number string 704 * @exception ArithmeticException if rounding is needed with rounding 705 * mode being set to RoundingMode.UNNECESSARY 706 * @see java.text.FieldPosition 707 */ 708 private StringBuffer format(BigDecimal number, StringBuffer result, 709 FieldPosition fieldPosition) { 710 fieldPosition.setBeginIndex(0); 711 fieldPosition.setEndIndex(0); 712 return format(number, result, fieldPosition.getFieldDelegate()); 713 } 714 715 /** 716 * Formats a BigDecimal to produce a string. 717 * @param number The BigDecimal to format 718 * @param result where the text is to be appended 719 * @param delegate notified of locations of sub fields 720 * @exception ArithmeticException if rounding is needed with rounding 721 * mode being set to RoundingMode.UNNECESSARY 722 * @return The formatted number string 723 */ 724 private StringBuffer format(BigDecimal number, StringBuffer result, 725 FieldDelegate delegate) { 726 if (multiplier != 1) { 727 number = number.multiply(getBigDecimalMultiplier()); 728 } 729 boolean isNegative = number.signum() == -1; 730 if (isNegative) { 731 number = number.negate(); 732 } 733 734 synchronized(digitList) { 735 int maxIntDigits = getMaximumIntegerDigits(); 736 int minIntDigits = getMinimumIntegerDigits(); 737 int maxFraDigits = getMaximumFractionDigits(); 738 int minFraDigits = getMinimumFractionDigits(); 739 int maximumDigits = maxIntDigits + maxFraDigits; 740 741 digitList.set(isNegative, number, useExponentialNotation ? 742 ((maximumDigits < 0) ? Integer.MAX_VALUE : maximumDigits) : 743 maxFraDigits, !useExponentialNotation); 744 745 return subformat(result, delegate, isNegative, false, 746 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits); 747 } 748 } 749 750 /** 751 * Format a BigInteger to produce a string. 752 * @param number The BigInteger to format 753 * @param result where the text is to be appended 754 * @param fieldPosition On input: an alignment field, if desired. 755 * On output: the offsets of the alignment field. 756 * @return The formatted number string 757 * @exception ArithmeticException if rounding is needed with rounding 758 * mode being set to RoundingMode.UNNECESSARY 759 * @see java.text.FieldPosition 760 */ 761 private StringBuffer format(BigInteger number, StringBuffer result, 762 FieldPosition fieldPosition) { 763 fieldPosition.setBeginIndex(0); 764 fieldPosition.setEndIndex(0); 765 766 return format(number, result, fieldPosition.getFieldDelegate(), false); 767 } 768 769 /** 770 * Format a BigInteger to produce a string. 771 * @param number The BigInteger to format 772 * @param result where the text is to be appended 773 * @param delegate notified of locations of sub fields 774 * @return The formatted number string 775 * @exception ArithmeticException if rounding is needed with rounding 776 * mode being set to RoundingMode.UNNECESSARY 777 * @see java.text.FieldPosition 778 */ 779 private StringBuffer format(BigInteger number, StringBuffer result, 780 FieldDelegate delegate, boolean formatLong) { 781 if (multiplier != 1) { 782 number = number.multiply(getBigIntegerMultiplier()); 783 } 784 boolean isNegative = number.signum() == -1; 785 if (isNegative) { 786 number = number.negate(); 787 } 788 789 synchronized(digitList) { 790 int maxIntDigits, minIntDigits, maxFraDigits, minFraDigits, maximumDigits; 791 if (formatLong) { 792 maxIntDigits = super.getMaximumIntegerDigits(); 793 minIntDigits = super.getMinimumIntegerDigits(); 794 maxFraDigits = super.getMaximumFractionDigits(); 795 minFraDigits = super.getMinimumFractionDigits(); 796 maximumDigits = maxIntDigits + maxFraDigits; 797 } else { 798 maxIntDigits = getMaximumIntegerDigits(); 799 minIntDigits = getMinimumIntegerDigits(); 800 maxFraDigits = getMaximumFractionDigits(); 801 minFraDigits = getMinimumFractionDigits(); 802 maximumDigits = maxIntDigits + maxFraDigits; 803 if (maximumDigits < 0) { 804 maximumDigits = Integer.MAX_VALUE; 805 } 806 } 807 808 digitList.set(isNegative, number, 809 useExponentialNotation ? maximumDigits : 0); 810 811 return subformat(result, delegate, isNegative, true, 812 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits); 813 } 814 } 815 816 /** 817 * Formats an Object producing an <code>AttributedCharacterIterator</code>. 818 * You can use the returned <code>AttributedCharacterIterator</code> 819 * to build the resulting String, as well as to determine information 820 * about the resulting String. 821 * <p> 822 * Each attribute key of the AttributedCharacterIterator will be of type 823 * <code>NumberFormat.Field</code>, with the attribute value being the 824 * same as the attribute key. 825 * 826 * @exception NullPointerException if obj is null. 827 * @exception IllegalArgumentException when the Format cannot format the 828 * given object. 829 * @exception ArithmeticException if rounding is needed with rounding 830 * mode being set to RoundingMode.UNNECESSARY 831 * @param obj The object to format 832 * @return AttributedCharacterIterator describing the formatted value. 833 * @since 1.4 834 */ 835 public AttributedCharacterIterator formatToCharacterIterator(Object obj) { 836 CharacterIteratorFieldDelegate delegate = 837 new CharacterIteratorFieldDelegate(); 838 StringBuffer sb = new StringBuffer(); 839 840 if (obj instanceof Double || obj instanceof Float) { 841 format(((Number)obj).doubleValue(), sb, delegate); 842 } else if (obj instanceof Long || obj instanceof Integer || 843 obj instanceof Short || obj instanceof Byte || 844 obj instanceof AtomicInteger || obj instanceof AtomicLong) { 845 format(((Number)obj).longValue(), sb, delegate); 846 } else if (obj instanceof BigDecimal) { 847 format((BigDecimal)obj, sb, delegate); 848 } else if (obj instanceof BigInteger) { 849 format((BigInteger)obj, sb, delegate, false); 850 } else if (obj == null) { 851 throw new NullPointerException( 852 "formatToCharacterIterator must be passed non-null object"); 853 } else { 854 throw new IllegalArgumentException( 855 "Cannot format given Object as a Number"); 856 } 857 return delegate.getIterator(sb.toString()); 858 } 859 860 /** 861 * Complete the formatting of a finite number. On entry, the digitList must 862 * be filled in with the correct digits. 863 */ 864 private StringBuffer subformat(StringBuffer result, FieldDelegate delegate, 865 boolean isNegative, boolean isInteger, 866 int maxIntDigits, int minIntDigits, 867 int maxFraDigits, int minFraDigits) { 868 // NOTE: This isn't required anymore because DigitList takes care of this. 869 // 870 // // The negative of the exponent represents the number of leading 871 // // zeros between the decimal and the first non-zero digit, for 872 // // a value < 0.1 (e.g., for 0.00123, -fExponent == 2). If this 873 // // is more than the maximum fraction digits, then we have an underflow 874 // // for the printed representation. We recognize this here and set 875 // // the DigitList representation to zero in this situation. 876 // 877 // if (-digitList.decimalAt >= getMaximumFractionDigits()) 878 // { 879 // digitList.count = 0; 880 // } 881 882 char zero = symbols.getZeroDigit(); 883 int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero 884 char grouping = symbols.getGroupingSeparator(); 885 char decimal = isCurrencyFormat ? 886 symbols.getMonetaryDecimalSeparator() : 887 symbols.getDecimalSeparator(); 888 889 /* Per bug 4147706, DecimalFormat must respect the sign of numbers which 890 * format as zero. This allows sensible computations and preserves 891 * relations such as signum(1/x) = signum(x), where x is +Infinity or 892 * -Infinity. Prior to this fix, we always formatted zero values as if 893 * they were positive. Liu 7/6/98. 894 */ 895 if (digitList.isZero()) { 896 digitList.decimalAt = 0; // Normalize 897 } 898 899 if (isNegative) { 900 append(result, negativePrefix, delegate, 901 getNegativePrefixFieldPositions(), Field.SIGN); 902 } else { 903 append(result, positivePrefix, delegate, 904 getPositivePrefixFieldPositions(), Field.SIGN); 905 } 906 907 if (useExponentialNotation) { 908 int iFieldStart = result.length(); 909 int iFieldEnd = -1; 910 int fFieldStart = -1; 911 912 // Minimum integer digits are handled in exponential format by 913 // adjusting the exponent. For example, 0.01234 with 3 minimum 914 // integer digits is "123.4E-4". 915 916 // Maximum integer digits are interpreted as indicating the 917 // repeating range. This is useful for engineering notation, in 918 // which the exponent is restricted to a multiple of 3. For 919 // example, 0.01234 with 3 maximum integer digits is "12.34e-3". 920 // If maximum integer digits are > 1 and are larger than 921 // minimum integer digits, then minimum integer digits are 922 // ignored. 923 int exponent = digitList.decimalAt; 924 int repeat = maxIntDigits; 925 int minimumIntegerDigits = minIntDigits; 926 if (repeat > 1 && repeat > minIntDigits) { 927 // A repeating range is defined; adjust to it as follows. 928 // If repeat == 3, we have 6,5,4=>3; 3,2,1=>0; 0,-1,-2=>-3; 929 // -3,-4,-5=>-6, etc. This takes into account that the 930 // exponent we have here is off by one from what we expect; 931 // it is for the format 0.MMMMMx10^n. 932 if (exponent >= 1) { 933 exponent = ((exponent - 1) / repeat) * repeat; 934 } else { 935 // integer division rounds towards 0 936 exponent = ((exponent - repeat) / repeat) * repeat; 937 } 938 minimumIntegerDigits = 1; 939 } else { 940 // No repeating range is defined; use minimum integer digits. 941 exponent -= minimumIntegerDigits; 942 } 943 944 // We now output a minimum number of digits, and more if there 945 // are more digits, up to the maximum number of digits. We 946 // place the decimal point after the "integer" digits, which 947 // are the first (decimalAt - exponent) digits. 948 int minimumDigits = minIntDigits + minFraDigits; 949 if (minimumDigits < 0) { // overflow? 950 minimumDigits = Integer.MAX_VALUE; 951 } 952 953 // The number of integer digits is handled specially if the number 954 // is zero, since then there may be no digits. 955 int integerDigits = digitList.isZero() ? minimumIntegerDigits : 956 digitList.decimalAt - exponent; 957 if (minimumDigits < integerDigits) { 958 minimumDigits = integerDigits; 959 } 960 int totalDigits = digitList.count; 961 if (minimumDigits > totalDigits) { 962 totalDigits = minimumDigits; 963 } 964 boolean addedDecimalSeparator = false; 965 966 for (int i=0; i<totalDigits; ++i) { 967 if (i == integerDigits) { 968 // Record field information for caller. 969 iFieldEnd = result.length(); 970 971 result.append(decimal); 972 addedDecimalSeparator = true; 973 974 // Record field information for caller. 975 fFieldStart = result.length(); 976 } 977 result.append((i < digitList.count) ? 978 (char)(digitList.digits[i] + zeroDelta) : 979 zero); 980 } 981 982 if (decimalSeparatorAlwaysShown && totalDigits == integerDigits) { 983 // Record field information for caller. 984 iFieldEnd = result.length(); 985 986 result.append(decimal); 987 addedDecimalSeparator = true; 988 989 // Record field information for caller. 990 fFieldStart = result.length(); 991 } 992 993 // Record field information 994 if (iFieldEnd == -1) { 995 iFieldEnd = result.length(); 996 } 997 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER, 998 iFieldStart, iFieldEnd, result); 999 if (addedDecimalSeparator) { 1000 delegate.formatted(Field.DECIMAL_SEPARATOR, 1001 Field.DECIMAL_SEPARATOR, 1002 iFieldEnd, fFieldStart, result); 1003 } 1004 if (fFieldStart == -1) { 1005 fFieldStart = result.length(); 1006 } 1007 delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION, 1008 fFieldStart, result.length(), result); 1009 1010 // The exponent is output using the pattern-specified minimum 1011 // exponent digits. There is no maximum limit to the exponent 1012 // digits, since truncating the exponent would result in an 1013 // unacceptable inaccuracy. 1014 int fieldStart = result.length(); 1015 1016 result.append(symbols.getExponentSeparator()); 1017 1018 delegate.formatted(Field.EXPONENT_SYMBOL, Field.EXPONENT_SYMBOL, 1019 fieldStart, result.length(), result); 1020 1021 // For zero values, we force the exponent to zero. We 1022 // must do this here, and not earlier, because the value 1023 // is used to determine integer digit count above. 1024 if (digitList.isZero()) { 1025 exponent = 0; 1026 } 1027 1028 boolean negativeExponent = exponent < 0; 1029 if (negativeExponent) { 1030 exponent = -exponent; 1031 fieldStart = result.length(); 1032 result.append(symbols.getMinusSign()); 1033 delegate.formatted(Field.EXPONENT_SIGN, Field.EXPONENT_SIGN, 1034 fieldStart, result.length(), result); 1035 } 1036 digitList.set(negativeExponent, exponent); 1037 1038 int eFieldStart = result.length(); 1039 1040 for (int i=digitList.decimalAt; i<minExponentDigits; ++i) { 1041 result.append(zero); 1042 } 1043 for (int i=0; i<digitList.decimalAt; ++i) { 1044 result.append((i < digitList.count) ? 1045 (char)(digitList.digits[i] + zeroDelta) : zero); 1046 } 1047 delegate.formatted(Field.EXPONENT, Field.EXPONENT, eFieldStart, 1048 result.length(), result); 1049 } else { 1050 int iFieldStart = result.length(); 1051 1052 // Output the integer portion. Here 'count' is the total 1053 // number of integer digits we will display, including both 1054 // leading zeros required to satisfy getMinimumIntegerDigits, 1055 // and actual digits present in the number. 1056 int count = minIntDigits; 1057 int digitIndex = 0; // Index into digitList.fDigits[] 1058 if (digitList.decimalAt > 0 && count < digitList.decimalAt) { 1059 count = digitList.decimalAt; 1060 } 1061 1062 // Handle the case where getMaximumIntegerDigits() is smaller 1063 // than the real number of integer digits. If this is so, we 1064 // output the least significant max integer digits. For example, 1065 // the value 1997 printed with 2 max integer digits is just "97". 1066 if (count > maxIntDigits) { 1067 count = maxIntDigits; 1068 digitIndex = digitList.decimalAt - count; 1069 } 1070 1071 int sizeBeforeIntegerPart = result.length(); 1072 for (int i=count-1; i>=0; --i) { 1073 if (i < digitList.decimalAt && digitIndex < digitList.count) { 1074 // Output a real digit 1075 result.append((char)(digitList.digits[digitIndex++] + zeroDelta)); 1076 } else { 1077 // Output a leading zero 1078 result.append(zero); 1079 } 1080 1081 // Output grouping separator if necessary. Don't output a 1082 // grouping separator if i==0 though; that's at the end of 1083 // the integer part. 1084 if (isGroupingUsed() && i>0 && (groupingSize != 0) && 1085 (i % groupingSize == 0)) { 1086 int gStart = result.length(); 1087 result.append(grouping); 1088 delegate.formatted(Field.GROUPING_SEPARATOR, 1089 Field.GROUPING_SEPARATOR, gStart, 1090 result.length(), result); 1091 } 1092 } 1093 1094 // Determine whether or not there are any printable fractional 1095 // digits. If we've used up the digits we know there aren't. 1096 boolean fractionPresent = (minFraDigits > 0) || 1097 (!isInteger && digitIndex < digitList.count); 1098 1099 // If there is no fraction present, and we haven't printed any 1100 // integer digits, then print a zero. Otherwise we won't print 1101 // _any_ digits, and we won't be able to parse this string. 1102 if (!fractionPresent && result.length() == sizeBeforeIntegerPart) { 1103 result.append(zero); 1104 } 1105 1106 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER, 1107 iFieldStart, result.length(), result); 1108 1109 // Output the decimal separator if we always do so. 1110 int sStart = result.length(); 1111 if (decimalSeparatorAlwaysShown || fractionPresent) { 1112 result.append(decimal); 1113 } 1114 1115 if (sStart != result.length()) { 1116 delegate.formatted(Field.DECIMAL_SEPARATOR, 1117 Field.DECIMAL_SEPARATOR, 1118 sStart, result.length(), result); 1119 } 1120 int fFieldStart = result.length(); 1121 1122 for (int i=0; i < maxFraDigits; ++i) { 1123 // Here is where we escape from the loop. We escape if we've 1124 // output the maximum fraction digits (specified in the for 1125 // expression above). 1126 // We also stop when we've output the minimum digits and either: 1127 // we have an integer, so there is no fractional stuff to 1128 // display, or we're out of significant digits. 1129 if (i >= minFraDigits && 1130 (isInteger || digitIndex >= digitList.count)) { 1131 break; 1132 } 1133 1134 // Output leading fractional zeros. These are zeros that come 1135 // after the decimal but before any significant digits. These 1136 // are only output if abs(number being formatted) < 1.0. 1137 if (-1-i > (digitList.decimalAt-1)) { 1138 result.append(zero); 1139 continue; 1140 } 1141 1142 // Output a digit, if we have any precision left, or a 1143 // zero if we don't. We don't want to output noise digits. 1144 if (!isInteger && digitIndex < digitList.count) { 1145 result.append((char)(digitList.digits[digitIndex++] + zeroDelta)); 1146 } else { 1147 result.append(zero); 1148 } 1149 } 1150 1151 // Record field information for caller. 1152 delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION, 1153 fFieldStart, result.length(), result); 1154 } 1155 1156 if (isNegative) { 1157 append(result, negativeSuffix, delegate, 1158 getNegativeSuffixFieldPositions(), Field.SIGN); 1159 } 1160 else { 1161 append(result, positiveSuffix, delegate, 1162 getPositiveSuffixFieldPositions(), Field.SIGN); 1163 } 1164 1165 return result; 1166 } 1167 1168 /** 1169 * Appends the String <code>string</code> to <code>result</code>. 1170 * <code>delegate</code> is notified of all the 1171 * <code>FieldPosition</code>s in <code>positions</code>. 1172 * <p> 1173 * If one of the <code>FieldPosition</code>s in <code>positions</code> 1174 * identifies a <code>SIGN</code> attribute, it is mapped to 1175 * <code>signAttribute</code>. This is used 1176 * to map the <code>SIGN</code> attribute to the <code>EXPONENT</code> 1177 * attribute as necessary. 1178 * <p> 1179 * This is used by <code>subformat</code> to add the prefix/suffix. 1180 */ 1181 private void append(StringBuffer result, String string, 1182 FieldDelegate delegate, 1183 FieldPosition[] positions, 1184 Format.Field signAttribute) { 1185 int start = result.length(); 1186 1187 if (string.length() > 0) { 1188 result.append(string); 1189 for (int counter = 0, max = positions.length; counter < max; 1190 counter++) { 1191 FieldPosition fp = positions[counter]; 1192 Format.Field attribute = fp.getFieldAttribute(); 1193 1194 if (attribute == Field.SIGN) { 1195 attribute = signAttribute; 1196 } 1197 delegate.formatted(attribute, attribute, 1198 start + fp.getBeginIndex(), 1199 start + fp.getEndIndex(), result); 1200 } 1201 } 1202 } 1203 1204 /** 1205 * Parses text from a string to produce a <code>Number</code>. 1206 * <p> 1207 * The method attempts to parse text starting at the index given by 1208 * <code>pos</code>. 1209 * If parsing succeeds, then the index of <code>pos</code> is updated 1210 * to the index after the last character used (parsing does not necessarily 1211 * use all characters up to the end of the string), and the parsed 1212 * number is returned. The updated <code>pos</code> can be used to 1213 * indicate the starting point for the next call to this method. 1214 * If an error occurs, then the index of <code>pos</code> is not 1215 * changed, the error index of <code>pos</code> is set to the index of 1216 * the character where the error occurred, and null is returned. 1217 * <p> 1218 * The subclass returned depends on the value of {@link #isParseBigDecimal} 1219 * as well as on the string being parsed. 1220 * <ul> 1221 * <li>If <code>isParseBigDecimal()</code> is false (the default), 1222 * most integer values are returned as <code>Long</code> 1223 * objects, no matter how they are written: <code>"17"</code> and 1224 * <code>"17.000"</code> both parse to <code>Long(17)</code>. 1225 * Values that cannot fit into a <code>Long</code> are returned as 1226 * <code>Double</code>s. This includes values with a fractional part, 1227 * infinite values, <code>NaN</code>, and the value -0.0. 1228 * <code>DecimalFormat</code> does <em>not</em> decide whether to 1229 * return a <code>Double</code> or a <code>Long</code> based on the 1230 * presence of a decimal separator in the source string. Doing so 1231 * would prevent integers that overflow the mantissa of a double, 1232 * such as <code>"-9,223,372,036,854,775,808.00"</code>, from being 1233 * parsed accurately. 1234 * <p> 1235 * Callers may use the <code>Number</code> methods 1236 * <code>doubleValue</code>, <code>longValue</code>, etc., to obtain 1237 * the type they want. 1238 * <li>If <code>isParseBigDecimal()</code> is true, values are returned 1239 * as <code>BigDecimal</code> objects. The values are the ones 1240 * constructed by {@link java.math.BigDecimal#BigDecimal(String)} 1241 * for corresponding strings in locale-independent format. The 1242 * special cases negative and positive infinity and NaN are returned 1243 * as <code>Double</code> instances holding the values of the 1244 * corresponding <code>Double</code> constants. 1245 * </ul> 1246 * <p> 1247 * <code>DecimalFormat</code> parses all Unicode characters that represent 1248 * decimal digits, as defined by <code>Character.digit()</code>. In 1249 * addition, <code>DecimalFormat</code> also recognizes as digits the ten 1250 * consecutive characters starting with the localized zero digit defined in 1251 * the <code>DecimalFormatSymbols</code> object. 1252 * 1253 * @param text the string to be parsed 1254 * @param pos A <code>ParsePosition</code> object with index and error 1255 * index information as described above. 1256 * @return the parsed value, or <code>null</code> if the parse fails 1257 * @exception NullPointerException if <code>text</code> or 1258 * <code>pos</code> is null. 1259 */ 1260 public Number parse(String text, ParsePosition pos) { 1261 // special case NaN 1262 if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) { 1263 pos.index = pos.index + symbols.getNaN().length(); 1264 return new Double(Double.NaN); 1265 } 1266 1267 boolean[] status = new boolean[STATUS_LENGTH]; 1268 if (!subparse(text, pos, positivePrefix, negativePrefix, digitList, false, status)) { 1269 return null; 1270 } 1271 1272 // special case INFINITY 1273 if (status[STATUS_INFINITE]) { 1274 if (status[STATUS_POSITIVE] == (multiplier >= 0)) { 1275 return new Double(Double.POSITIVE_INFINITY); 1276 } else { 1277 return new Double(Double.NEGATIVE_INFINITY); 1278 } 1279 } 1280 1281 if (multiplier == 0) { 1282 if (digitList.isZero()) { 1283 return new Double(Double.NaN); 1284 } else if (status[STATUS_POSITIVE]) { 1285 return new Double(Double.POSITIVE_INFINITY); 1286 } else { 1287 return new Double(Double.NEGATIVE_INFINITY); 1288 } 1289 } 1290 1291 if (isParseBigDecimal()) { 1292 BigDecimal bigDecimalResult = digitList.getBigDecimal(); 1293 1294 if (multiplier != 1) { 1295 try { 1296 bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier()); 1297 } 1298 catch (ArithmeticException e) { // non-terminating decimal expansion 1299 bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier(), roundingMode); 1300 } 1301 } 1302 1303 if (!status[STATUS_POSITIVE]) { 1304 bigDecimalResult = bigDecimalResult.negate(); 1305 } 1306 return bigDecimalResult; 1307 } else { 1308 boolean gotDouble = true; 1309 boolean gotLongMinimum = false; 1310 double doubleResult = 0.0; 1311 long longResult = 0; 1312 1313 // Finally, have DigitList parse the digits into a value. 1314 if (digitList.fitsIntoLong(status[STATUS_POSITIVE], isParseIntegerOnly())) { 1315 gotDouble = false; 1316 longResult = digitList.getLong(); 1317 if (longResult < 0) { // got Long.MIN_VALUE 1318 gotLongMinimum = true; 1319 } 1320 } else { 1321 doubleResult = digitList.getDouble(); 1322 } 1323 1324 // Divide by multiplier. We have to be careful here not to do 1325 // unneeded conversions between double and long. 1326 if (multiplier != 1) { 1327 if (gotDouble) { 1328 doubleResult /= multiplier; 1329 } else { 1330 // Avoid converting to double if we can 1331 if (longResult % multiplier == 0) { 1332 longResult /= multiplier; 1333 } else { 1334 doubleResult = ((double)longResult) / multiplier; 1335 gotDouble = true; 1336 } 1337 } 1338 } 1339 1340 if (!status[STATUS_POSITIVE] && !gotLongMinimum) { 1341 doubleResult = -doubleResult; 1342 longResult = -longResult; 1343 } 1344 1345 // At this point, if we divided the result by the multiplier, the 1346 // result may fit into a long. We check for this case and return 1347 // a long if possible. 1348 // We must do this AFTER applying the negative (if appropriate) 1349 // in order to handle the case of LONG_MIN; otherwise, if we do 1350 // this with a positive value -LONG_MIN, the double is > 0, but 1351 // the long is < 0. We also must retain a double in the case of 1352 // -0.0, which will compare as == to a long 0 cast to a double 1353 // (bug 4162852). 1354 if (multiplier != 1 && gotDouble) { 1355 longResult = (long)doubleResult; 1356 gotDouble = ((doubleResult != (double)longResult) || 1357 (doubleResult == 0.0 && 1/doubleResult < 0.0)) && 1358 !isParseIntegerOnly(); 1359 } 1360 1361 return gotDouble ? 1362 (Number)new Double(doubleResult) : (Number)new Long(longResult); 1363 } 1364 } 1365 1366 /** 1367 * Return a BigInteger multiplier. 1368 */ 1369 private BigInteger getBigIntegerMultiplier() { 1370 if (bigIntegerMultiplier == null) { 1371 bigIntegerMultiplier = BigInteger.valueOf(multiplier); 1372 } 1373 return bigIntegerMultiplier; 1374 } 1375 private transient BigInteger bigIntegerMultiplier; 1376 1377 /** 1378 * Return a BigDecimal multiplier. 1379 */ 1380 private BigDecimal getBigDecimalMultiplier() { 1381 if (bigDecimalMultiplier == null) { 1382 bigDecimalMultiplier = new BigDecimal(multiplier); 1383 } 1384 return bigDecimalMultiplier; 1385 } 1386 private transient BigDecimal bigDecimalMultiplier; 1387 1388 private static final int STATUS_INFINITE = 0; 1389 private static final int STATUS_POSITIVE = 1; 1390 private static final int STATUS_LENGTH = 2; 1391 1392 /** 1393 * Parse the given text into a number. The text is parsed beginning at 1394 * parsePosition, until an unparseable character is seen. 1395 * @param text The string to parse. 1396 * @param parsePosition The position at which to being parsing. Upon 1397 * return, the first unparseable character. 1398 * @param digits The DigitList to set to the parsed value. 1399 * @param isExponent If true, parse an exponent. This means no 1400 * infinite values and integer only. 1401 * @param status Upon return contains boolean status flags indicating 1402 * whether the value was infinite and whether it was positive. 1403 */ 1404 private final boolean subparse(String text, ParsePosition parsePosition, 1405 String positivePrefix, String negativePrefix, 1406 DigitList digits, boolean isExponent, 1407 boolean status[]) { 1408 int position = parsePosition.index; 1409 int oldStart = parsePosition.index; 1410 int backup; 1411 boolean gotPositive, gotNegative; 1412 1413 // check for positivePrefix; take longest 1414 gotPositive = text.regionMatches(position, positivePrefix, 0, 1415 positivePrefix.length()); 1416 gotNegative = text.regionMatches(position, negativePrefix, 0, 1417 negativePrefix.length()); 1418 1419 if (gotPositive && gotNegative) { 1420 if (positivePrefix.length() > negativePrefix.length()) { 1421 gotNegative = false; 1422 } else if (positivePrefix.length() < negativePrefix.length()) { 1423 gotPositive = false; 1424 } 1425 } 1426 1427 if (gotPositive) { 1428 position += positivePrefix.length(); 1429 } else if (gotNegative) { 1430 position += negativePrefix.length(); 1431 } else { 1432 parsePosition.errorIndex = position; 1433 return false; 1434 } 1435 1436 // process digits or Inf, find decimal position 1437 status[STATUS_INFINITE] = false; 1438 if (!isExponent && text.regionMatches(position,symbols.getInfinity(),0, 1439 symbols.getInfinity().length())) { 1440 position += symbols.getInfinity().length(); 1441 status[STATUS_INFINITE] = true; 1442 } else { 1443 // We now have a string of digits, possibly with grouping symbols, 1444 // and decimal points. We want to process these into a DigitList. 1445 // We don't want to put a bunch of leading zeros into the DigitList 1446 // though, so we keep track of the location of the decimal point, 1447 // put only significant digits into the DigitList, and adjust the 1448 // exponent as needed. 1449 1450 digits.decimalAt = digits.count = 0; 1451 char zero = symbols.getZeroDigit(); 1452 char decimal = isCurrencyFormat ? 1453 symbols.getMonetaryDecimalSeparator() : 1454 symbols.getDecimalSeparator(); 1455 char grouping = symbols.getGroupingSeparator(); 1456 String exponentString = symbols.getExponentSeparator(); 1457 boolean sawDecimal = false; 1458 boolean sawExponent = false; 1459 boolean sawDigit = false; 1460 int exponent = 0; // Set to the exponent value, if any 1461 1462 // We have to track digitCount ourselves, because digits.count will 1463 // pin when the maximum allowable digits is reached. 1464 int digitCount = 0; 1465 1466 backup = -1; 1467 for (; position < text.length(); ++position) { 1468 char ch = text.charAt(position); 1469 1470 /* We recognize all digit ranges, not only the Latin digit range 1471 * '0'..'9'. We do so by using the Character.digit() method, 1472 * which converts a valid Unicode digit to the range 0..9. 1473 * 1474 * The character 'ch' may be a digit. If so, place its value 1475 * from 0 to 9 in 'digit'. First try using the locale digit, 1476 * which may or MAY NOT be a standard Unicode digit range. If 1477 * this fails, try using the standard Unicode digit ranges by 1478 * calling Character.digit(). If this also fails, digit will 1479 * have a value outside the range 0..9. 1480 */ 1481 int digit = ch - zero; 1482 if (digit < 0 || digit > 9) { 1483 digit = Character.digit(ch, 10); 1484 } 1485 1486 if (digit == 0) { 1487 // Cancel out backup setting (see grouping handler below) 1488 backup = -1; // Do this BEFORE continue statement below!!! 1489 sawDigit = true; 1490 1491 // Handle leading zeros 1492 if (digits.count == 0) { 1493 // Ignore leading zeros in integer part of number. 1494 if (!sawDecimal) { 1495 continue; 1496 } 1497 1498 // If we have seen the decimal, but no significant 1499 // digits yet, then we account for leading zeros by 1500 // decrementing the digits.decimalAt into negative 1501 // values. 1502 --digits.decimalAt; 1503 } else { 1504 ++digitCount; 1505 digits.append((char)(digit + '0')); 1506 } 1507 } else if (digit > 0 && digit <= 9) { // [sic] digit==0 handled above 1508 sawDigit = true; 1509 ++digitCount; 1510 digits.append((char)(digit + '0')); 1511 1512 // Cancel out backup setting (see grouping handler below) 1513 backup = -1; 1514 } else if (!isExponent && ch == decimal) { 1515 // If we're only parsing integers, or if we ALREADY saw the 1516 // decimal, then don't parse this one. 1517 if (isParseIntegerOnly() || sawDecimal) { 1518 break; 1519 } 1520 digits.decimalAt = digitCount; // Not digits.count! 1521 sawDecimal = true; 1522 } else if (!isExponent && ch == grouping && isGroupingUsed()) { 1523 if (sawDecimal) { 1524 break; 1525 } 1526 // Ignore grouping characters, if we are using them, but 1527 // require that they be followed by a digit. Otherwise 1528 // we backup and reprocess them. 1529 backup = position; 1530 } else if (!isExponent && text.regionMatches(position, exponentString, 0, exponentString.length()) 1531 && !sawExponent) { 1532 // Process the exponent by recursively calling this method. 1533 ParsePosition pos = new ParsePosition(position + exponentString.length()); 1534 boolean[] stat = new boolean[STATUS_LENGTH]; 1535 DigitList exponentDigits = new DigitList(); 1536 1537 if (subparse(text, pos, "", Character.toString(symbols.getMinusSign()), exponentDigits, true, stat) && 1538 exponentDigits.fitsIntoLong(stat[STATUS_POSITIVE], true)) { 1539 position = pos.index; // Advance past the exponent 1540 exponent = (int)exponentDigits.getLong(); 1541 if (!stat[STATUS_POSITIVE]) { 1542 exponent = -exponent; 1543 } 1544 sawExponent = true; 1545 } 1546 break; // Whether we fail or succeed, we exit this loop 1547 } 1548 else { 1549 break; 1550 } 1551 } 1552 1553 if (backup != -1) { 1554 position = backup; 1555 } 1556 1557 // If there was no decimal point we have an integer 1558 if (!sawDecimal) { 1559 digits.decimalAt = digitCount; // Not digits.count! 1560 } 1561 1562 // Adjust for exponent, if any 1563 digits.decimalAt += exponent; 1564 1565 // If none of the text string was recognized. For example, parse 1566 // "x" with pattern "#0.00" (return index and error index both 0) 1567 // parse "$" with pattern "$#0.00". (return index 0 and error 1568 // index 1). 1569 if (!sawDigit && digitCount == 0) { 1570 parsePosition.index = oldStart; 1571 parsePosition.errorIndex = oldStart; 1572 return false; 1573 } 1574 } 1575 1576 // check for suffix 1577 if (!isExponent) { 1578 if (gotPositive) { 1579 gotPositive = text.regionMatches(position,positiveSuffix,0, 1580 positiveSuffix.length()); 1581 } 1582 if (gotNegative) { 1583 gotNegative = text.regionMatches(position,negativeSuffix,0, 1584 negativeSuffix.length()); 1585 } 1586 1587 // if both match, take longest 1588 if (gotPositive && gotNegative) { 1589 if (positiveSuffix.length() > negativeSuffix.length()) { 1590 gotNegative = false; 1591 } else if (positiveSuffix.length() < negativeSuffix.length()) { 1592 gotPositive = false; 1593 } 1594 } 1595 1596 // fail if neither or both 1597 if (gotPositive == gotNegative) { 1598 parsePosition.errorIndex = position; 1599 return false; 1600 } 1601 1602 parsePosition.index = position + 1603 (gotPositive ? positiveSuffix.length() : negativeSuffix.length()); // mark success! 1604 } else { 1605 parsePosition.index = position; 1606 } 1607 1608 status[STATUS_POSITIVE] = gotPositive; 1609 if (parsePosition.index == oldStart) { 1610 parsePosition.errorIndex = position; 1611 return false; 1612 } 1613 return true; 1614 } 1615 1616 /** 1617 * Returns a copy of the decimal format symbols, which is generally not 1618 * changed by the programmer or user. 1619 * @return a copy of the desired DecimalFormatSymbols 1620 * @see java.text.DecimalFormatSymbols 1621 */ 1622 public DecimalFormatSymbols getDecimalFormatSymbols() { 1623 try { 1624 // don't allow multiple references 1625 return (DecimalFormatSymbols) symbols.clone(); 1626 } catch (Exception foo) { 1627 return null; // should never happen 1628 } 1629 } 1630 1631 1632 /** 1633 * Sets the decimal format symbols, which is generally not changed 1634 * by the programmer or user. 1635 * @param newSymbols desired DecimalFormatSymbols 1636 * @see java.text.DecimalFormatSymbols 1637 */ 1638 public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) { 1639 try { 1640 // don't allow multiple references 1641 symbols = (DecimalFormatSymbols) newSymbols.clone(); 1642 expandAffixes(); 1643 } catch (Exception foo) { 1644 // should never happen 1645 } 1646 } 1647 1648 /** 1649 * Get the positive prefix. 1650 * <P>Examples: +123, $123, sFr123 1651 */ 1652 public String getPositivePrefix () { 1653 return positivePrefix; 1654 } 1655 1656 /** 1657 * Set the positive prefix. 1658 * <P>Examples: +123, $123, sFr123 1659 */ 1660 public void setPositivePrefix (String newValue) { 1661 positivePrefix = newValue; 1662 posPrefixPattern = null; 1663 positivePrefixFieldPositions = null; 1664 } 1665 1666 /** 1667 * Returns the FieldPositions of the fields in the prefix used for 1668 * positive numbers. This is not used if the user has explicitly set 1669 * a positive prefix via <code>setPositivePrefix</code>. This is 1670 * lazily created. 1671 * 1672 * @return FieldPositions in positive prefix 1673 */ 1674 private FieldPosition[] getPositivePrefixFieldPositions() { 1675 if (positivePrefixFieldPositions == null) { 1676 if (posPrefixPattern != null) { 1677 positivePrefixFieldPositions = expandAffix(posPrefixPattern); 1678 } 1679 else { 1680 positivePrefixFieldPositions = EmptyFieldPositionArray; 1681 } 1682 } 1683 return positivePrefixFieldPositions; 1684 } 1685 1686 /** 1687 * Get the negative prefix. 1688 * <P>Examples: -123, ($123) (with negative suffix), sFr-123 1689 */ 1690 public String getNegativePrefix () { 1691 return negativePrefix; 1692 } 1693 1694 /** 1695 * Set the negative prefix. 1696 * <P>Examples: -123, ($123) (with negative suffix), sFr-123 1697 */ 1698 public void setNegativePrefix (String newValue) { 1699 negativePrefix = newValue; 1700 negPrefixPattern = null; 1701 } 1702 1703 /** 1704 * Returns the FieldPositions of the fields in the prefix used for 1705 * negative numbers. This is not used if the user has explicitly set 1706 * a negative prefix via <code>setNegativePrefix</code>. This is 1707 * lazily created. 1708 * 1709 * @return FieldPositions in positive prefix 1710 */ 1711 private FieldPosition[] getNegativePrefixFieldPositions() { 1712 if (negativePrefixFieldPositions == null) { 1713 if (negPrefixPattern != null) { 1714 negativePrefixFieldPositions = expandAffix(negPrefixPattern); 1715 } 1716 else { 1717 negativePrefixFieldPositions = EmptyFieldPositionArray; 1718 } 1719 } 1720 return negativePrefixFieldPositions; 1721 } 1722 1723 /** 1724 * Get the positive suffix. 1725 * <P>Example: 123% 1726 */ 1727 public String getPositiveSuffix () { 1728 return positiveSuffix; 1729 } 1730 1731 /** 1732 * Set the positive suffix. 1733 * <P>Example: 123% 1734 */ 1735 public void setPositiveSuffix (String newValue) { 1736 positiveSuffix = newValue; 1737 posSuffixPattern = null; 1738 } 1739 1740 /** 1741 * Returns the FieldPositions of the fields in the suffix used for 1742 * positive numbers. This is not used if the user has explicitly set 1743 * a positive suffix via <code>setPositiveSuffix</code>. This is 1744 * lazily created. 1745 * 1746 * @return FieldPositions in positive prefix 1747 */ 1748 private FieldPosition[] getPositiveSuffixFieldPositions() { 1749 if (positiveSuffixFieldPositions == null) { 1750 if (posSuffixPattern != null) { 1751 positiveSuffixFieldPositions = expandAffix(posSuffixPattern); 1752 } 1753 else { 1754 positiveSuffixFieldPositions = EmptyFieldPositionArray; 1755 } 1756 } 1757 return positiveSuffixFieldPositions; 1758 } 1759 1760 /** 1761 * Get the negative suffix. 1762 * <P>Examples: -123%, ($123) (with positive suffixes) 1763 */ 1764 public String getNegativeSuffix () { 1765 return negativeSuffix; 1766 } 1767 1768 /** 1769 * Set the negative suffix. 1770 * <P>Examples: 123% 1771 */ 1772 public void setNegativeSuffix (String newValue) { 1773 negativeSuffix = newValue; 1774 negSuffixPattern = null; 1775 } 1776 1777 /** 1778 * Returns the FieldPositions of the fields in the suffix used for 1779 * negative numbers. This is not used if the user has explicitly set 1780 * a negative suffix via <code>setNegativeSuffix</code>. This is 1781 * lazily created. 1782 * 1783 * @return FieldPositions in positive prefix 1784 */ 1785 private FieldPosition[] getNegativeSuffixFieldPositions() { 1786 if (negativeSuffixFieldPositions == null) { 1787 if (negSuffixPattern != null) { 1788 negativeSuffixFieldPositions = expandAffix(negSuffixPattern); 1789 } 1790 else { 1791 negativeSuffixFieldPositions = EmptyFieldPositionArray; 1792 } 1793 } 1794 return negativeSuffixFieldPositions; 1795 } 1796 1797 /** 1798 * Gets the multiplier for use in percent, per mille, and similar 1799 * formats. 1800 * 1801 * @see #setMultiplier(int) 1802 */ 1803 public int getMultiplier () { 1804 return multiplier; 1805 } 1806 1807 /** 1808 * Sets the multiplier for use in percent, per mille, and similar 1809 * formats. 1810 * For a percent format, set the multiplier to 100 and the suffixes to 1811 * have '%' (for Arabic, use the Arabic percent sign). 1812 * For a per mille format, set the multiplier to 1000 and the suffixes to 1813 * have '\u2030'. 1814 * 1815 * <P>Example: with multiplier 100, 1.23 is formatted as "123", and 1816 * "123" is parsed into 1.23. 1817 * 1818 * @see #getMultiplier 1819 */ 1820 public void setMultiplier (int newValue) { 1821 multiplier = newValue; 1822 bigDecimalMultiplier = null; 1823 bigIntegerMultiplier = null; 1824 } 1825 1826 /** 1827 * Return the grouping size. Grouping size is the number of digits between 1828 * grouping separators in the integer portion of a number. For example, 1829 * in the number "123,456.78", the grouping size is 3. 1830 * @see #setGroupingSize 1831 * @see java.text.NumberFormat#isGroupingUsed 1832 * @see java.text.DecimalFormatSymbols#getGroupingSeparator 1833 */ 1834 public int getGroupingSize () { 1835 return groupingSize; 1836 } 1837 1838 /** 1839 * Set the grouping size. Grouping size is the number of digits between 1840 * grouping separators in the integer portion of a number. For example, 1841 * in the number "123,456.78", the grouping size is 3. 1842 * <br> 1843 * The value passed in is converted to a byte, which may lose information. 1844 * @see #getGroupingSize 1845 * @see java.text.NumberFormat#setGroupingUsed 1846 * @see java.text.DecimalFormatSymbols#setGroupingSeparator 1847 */ 1848 public void setGroupingSize (int newValue) { 1849 groupingSize = (byte)newValue; 1850 } 1851 1852 /** 1853 * Allows you to get the behavior of the decimal separator with integers. 1854 * (The decimal separator will always appear with decimals.) 1855 * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345 1856 */ 1857 public boolean isDecimalSeparatorAlwaysShown() { 1858 return decimalSeparatorAlwaysShown; 1859 } 1860 1861 /** 1862 * Allows you to set the behavior of the decimal separator with integers. 1863 * (The decimal separator will always appear with decimals.) 1864 * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345 1865 */ 1866 public void setDecimalSeparatorAlwaysShown(boolean newValue) { 1867 decimalSeparatorAlwaysShown = newValue; 1868 } 1869 1870 /** 1871 * Returns whether the {@link #parse(java.lang.String, java.text.ParsePosition)} 1872 * method returns <code>BigDecimal</code>. The default value is false. 1873 * @see #setParseBigDecimal 1874 * @since 1.5 1875 */ 1876 public boolean isParseBigDecimal() { 1877 return parseBigDecimal; 1878 } 1879 1880 /** 1881 * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)} 1882 * method returns <code>BigDecimal</code>. 1883 * @see #isParseBigDecimal 1884 * @since 1.5 1885 */ 1886 public void setParseBigDecimal(boolean newValue) { 1887 parseBigDecimal = newValue; 1888 } 1889 1890 /** 1891 * Standard override; no change in semantics. 1892 */ 1893 public Object clone() { 1894 DecimalFormat other = (DecimalFormat) super.clone(); 1895 other.symbols = (DecimalFormatSymbols) symbols.clone(); 1896 other.digitList = (DigitList) digitList.clone(); 1897 return other; 1898 } 1899 1900 /** 1901 * Overrides equals 1902 */ 1903 public boolean equals(Object obj) 1904 { 1905 if (obj == null) return false; 1906 if (!super.equals(obj)) return false; // super does class check 1907 DecimalFormat other = (DecimalFormat) obj; 1908 return ((posPrefixPattern == other.posPrefixPattern && 1909 positivePrefix.equals(other.positivePrefix)) 1910 || (posPrefixPattern != null && 1911 posPrefixPattern.equals(other.posPrefixPattern))) 1912 && ((posSuffixPattern == other.posSuffixPattern && 1913 positiveSuffix.equals(other.positiveSuffix)) 1914 || (posSuffixPattern != null && 1915 posSuffixPattern.equals(other.posSuffixPattern))) 1916 && ((negPrefixPattern == other.negPrefixPattern && 1917 negativePrefix.equals(other.negativePrefix)) 1918 || (negPrefixPattern != null && 1919 negPrefixPattern.equals(other.negPrefixPattern))) 1920 && ((negSuffixPattern == other.negSuffixPattern && 1921 negativeSuffix.equals(other.negativeSuffix)) 1922 || (negSuffixPattern != null && 1923 negSuffixPattern.equals(other.negSuffixPattern))) 1924 && multiplier == other.multiplier 1925 && groupingSize == other.groupingSize 1926 && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown 1927 && parseBigDecimal == other.parseBigDecimal 1928 && useExponentialNotation == other.useExponentialNotation 1929 && (!useExponentialNotation || 1930 minExponentDigits == other.minExponentDigits) 1931 && maximumIntegerDigits == other.maximumIntegerDigits 1932 && minimumIntegerDigits == other.minimumIntegerDigits 1933 && maximumFractionDigits == other.maximumFractionDigits 1934 && minimumFractionDigits == other.minimumFractionDigits 1935 && roundingMode == other.roundingMode 1936 && symbols.equals(other.symbols); 1937 } 1938 1939 /** 1940 * Overrides hashCode 1941 */ 1942 public int hashCode() { 1943 return super.hashCode() * 37 + positivePrefix.hashCode(); 1944 // just enough fields for a reasonable distribution 1945 } 1946 1947 /** 1948 * Synthesizes a pattern string that represents the current state 1949 * of this Format object. 1950 * @see #applyPattern 1951 */ 1952 public String toPattern() { 1953 return toPattern( false ); 1954 } 1955 1956 /** 1957 * Synthesizes a localized pattern string that represents the current 1958 * state of this Format object. 1959 * @see #applyPattern 1960 */ 1961 public String toLocalizedPattern() { 1962 return toPattern( true ); 1963 } 1964 1965 /** 1966 * Expand the affix pattern strings into the expanded affix strings. If any 1967 * affix pattern string is null, do not expand it. This method should be 1968 * called any time the symbols or the affix patterns change in order to keep 1969 * the expanded affix strings up to date. 1970 */ 1971 private void expandAffixes() { 1972 // Reuse one StringBuffer for better performance 1973 StringBuffer buffer = new StringBuffer(); 1974 if (posPrefixPattern != null) { 1975 positivePrefix = expandAffix(posPrefixPattern, buffer); 1976 positivePrefixFieldPositions = null; 1977 } 1978 if (posSuffixPattern != null) { 1979 positiveSuffix = expandAffix(posSuffixPattern, buffer); 1980 positiveSuffixFieldPositions = null; 1981 } 1982 if (negPrefixPattern != null) { 1983 negativePrefix = expandAffix(negPrefixPattern, buffer); 1984 negativePrefixFieldPositions = null; 1985 } 1986 if (negSuffixPattern != null) { 1987 negativeSuffix = expandAffix(negSuffixPattern, buffer); 1988 negativeSuffixFieldPositions = null; 1989 } 1990 } 1991 1992 /** 1993 * Expand an affix pattern into an affix string. All characters in the 1994 * pattern are literal unless prefixed by QUOTE. The following characters 1995 * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE, 1996 * PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE + 1997 * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217 1998 * currency code. Any other character after a QUOTE represents itself. 1999 * QUOTE must be followed by another character; QUOTE may not occur by 2000 * itself at the end of the pattern. 2001 * 2002 * @param pattern the non-null, possibly empty pattern 2003 * @param buffer a scratch StringBuffer; its contents will be lost 2004 * @return the expanded equivalent of pattern 2005 */ 2006 private String expandAffix(String pattern, StringBuffer buffer) { 2007 buffer.setLength(0); 2008 for (int i=0; i<pattern.length(); ) { 2009 char c = pattern.charAt(i++); 2010 if (c == QUOTE) { 2011 c = pattern.charAt(i++); 2012 switch (c) { 2013 case CURRENCY_SIGN: 2014 if (i<pattern.length() && 2015 pattern.charAt(i) == CURRENCY_SIGN) { 2016 ++i; 2017 buffer.append(symbols.getInternationalCurrencySymbol()); 2018 } else { 2019 buffer.append(symbols.getCurrencySymbol()); 2020 } 2021 continue; 2022 case PATTERN_PERCENT: 2023 c = symbols.getPercent(); 2024 break; 2025 case PATTERN_PER_MILLE: 2026 c = symbols.getPerMill(); 2027 break; 2028 case PATTERN_MINUS: 2029 c = symbols.getMinusSign(); 2030 break; 2031 } 2032 } 2033 buffer.append(c); 2034 } 2035 return buffer.toString(); 2036 } 2037 2038 /** 2039 * Expand an affix pattern into an array of FieldPositions describing 2040 * how the pattern would be expanded. 2041 * All characters in the 2042 * pattern are literal unless prefixed by QUOTE. The following characters 2043 * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE, 2044 * PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE + 2045 * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217 2046 * currency code. Any other character after a QUOTE represents itself. 2047 * QUOTE must be followed by another character; QUOTE may not occur by 2048 * itself at the end of the pattern. 2049 * 2050 * @param pattern the non-null, possibly empty pattern 2051 * @return FieldPosition array of the resulting fields. 2052 */ 2053 private FieldPosition[] expandAffix(String pattern) { 2054 ArrayList positions = null; 2055 int stringIndex = 0; 2056 for (int i=0; i<pattern.length(); ) { 2057 char c = pattern.charAt(i++); 2058 if (c == QUOTE) { 2059 int field = -1; 2060 Format.Field fieldID = null; 2061 c = pattern.charAt(i++); 2062 switch (c) { 2063 case CURRENCY_SIGN: 2064 String string; 2065 if (i<pattern.length() && 2066 pattern.charAt(i) == CURRENCY_SIGN) { 2067 ++i; 2068 string = symbols.getInternationalCurrencySymbol(); 2069 } else { 2070 string = symbols.getCurrencySymbol(); 2071 } 2072 if (string.length() > 0) { 2073 if (positions == null) { 2074 positions = new ArrayList(2); 2075 } 2076 FieldPosition fp = new FieldPosition(Field.CURRENCY); 2077 fp.setBeginIndex(stringIndex); 2078 fp.setEndIndex(stringIndex + string.length()); 2079 positions.add(fp); 2080 stringIndex += string.length(); 2081 } 2082 continue; 2083 case PATTERN_PERCENT: 2084 c = symbols.getPercent(); 2085 field = -1; 2086 fieldID = Field.PERCENT; 2087 break; 2088 case PATTERN_PER_MILLE: 2089 c = symbols.getPerMill(); 2090 field = -1; 2091 fieldID = Field.PERMILLE; 2092 break; 2093 case PATTERN_MINUS: 2094 c = symbols.getMinusSign(); 2095 field = -1; 2096 fieldID = Field.SIGN; 2097 break; 2098 } 2099 if (fieldID != null) { 2100 if (positions == null) { 2101 positions = new ArrayList(2); 2102 } 2103 FieldPosition fp = new FieldPosition(fieldID, field); 2104 fp.setBeginIndex(stringIndex); 2105 fp.setEndIndex(stringIndex + 1); 2106 positions.add(fp); 2107 } 2108 } 2109 stringIndex++; 2110 } 2111 if (positions != null) { 2112 return (FieldPosition[])positions.toArray(EmptyFieldPositionArray); 2113 } 2114 return EmptyFieldPositionArray; 2115 } 2116 2117 /** 2118 * Appends an affix pattern to the given StringBuffer, quoting special 2119 * characters as needed. Uses the internal affix pattern, if that exists, 2120 * or the literal affix, if the internal affix pattern is null. The 2121 * appended string will generate the same affix pattern (or literal affix) 2122 * when passed to toPattern(). 2123 * 2124 * @param buffer the affix string is appended to this 2125 * @param affixPattern a pattern such as posPrefixPattern; may be null 2126 * @param expAffix a corresponding expanded affix, such as positivePrefix. 2127 * Ignored unless affixPattern is null. If affixPattern is null, then 2128 * expAffix is appended as a literal affix. 2129 * @param localized true if the appended pattern should contain localized 2130 * pattern characters; otherwise, non-localized pattern chars are appended 2131 */ 2132 private void appendAffix(StringBuffer buffer, String affixPattern, 2133 String expAffix, boolean localized) { 2134 if (affixPattern == null) { 2135 appendAffix(buffer, expAffix, localized); 2136 } else { 2137 int i; 2138 for (int pos=0; pos<affixPattern.length(); pos=i) { 2139 i = affixPattern.indexOf(QUOTE, pos); 2140 if (i < 0) { 2141 appendAffix(buffer, affixPattern.substring(pos), localized); 2142 break; 2143 } 2144 if (i > pos) { 2145 appendAffix(buffer, affixPattern.substring(pos, i), localized); 2146 } 2147 char c = affixPattern.charAt(++i); 2148 ++i; 2149 if (c == QUOTE) { 2150 buffer.append(c); 2151 // Fall through and append another QUOTE below 2152 } else if (c == CURRENCY_SIGN && 2153 i<affixPattern.length() && 2154 affixPattern.charAt(i) == CURRENCY_SIGN) { 2155 ++i; 2156 buffer.append(c); 2157 // Fall through and append another CURRENCY_SIGN below 2158 } else if (localized) { 2159 switch (c) { 2160 case PATTERN_PERCENT: 2161 c = symbols.getPercent(); 2162 break; 2163 case PATTERN_PER_MILLE: 2164 c = symbols.getPerMill(); 2165 break; 2166 case PATTERN_MINUS: 2167 c = symbols.getMinusSign(); 2168 break; 2169 } 2170 } 2171 buffer.append(c); 2172 } 2173 } 2174 } 2175 2176 /** 2177 * Append an affix to the given StringBuffer, using quotes if 2178 * there are special characters. Single quotes themselves must be 2179 * escaped in either case. 2180 */ 2181 private void appendAffix(StringBuffer buffer, String affix, boolean localized) { 2182 boolean needQuote; 2183 if (localized) { 2184 needQuote = affix.indexOf(symbols.getZeroDigit()) >= 0 2185 || affix.indexOf(symbols.getGroupingSeparator()) >= 0 2186 || affix.indexOf(symbols.getDecimalSeparator()) >= 0 2187 || affix.indexOf(symbols.getPercent()) >= 0 2188 || affix.indexOf(symbols.getPerMill()) >= 0 2189 || affix.indexOf(symbols.getDigit()) >= 0 2190 || affix.indexOf(symbols.getPatternSeparator()) >= 0 2191 || affix.indexOf(symbols.getMinusSign()) >= 0 2192 || affix.indexOf(CURRENCY_SIGN) >= 0; 2193 } 2194 else { 2195 needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 0 2196 || affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 0 2197 || affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 0 2198 || affix.indexOf(PATTERN_PERCENT) >= 0 2199 || affix.indexOf(PATTERN_PER_MILLE) >= 0 2200 || affix.indexOf(PATTERN_DIGIT) >= 0 2201 || affix.indexOf(PATTERN_SEPARATOR) >= 0 2202 || affix.indexOf(PATTERN_MINUS) >= 0 2203 || affix.indexOf(CURRENCY_SIGN) >= 0; 2204 } 2205 if (needQuote) buffer.append('\''); 2206 if (affix.indexOf('\'') < 0) buffer.append(affix); 2207 else { 2208 for (int j=0; j<affix.length(); ++j) { 2209 char c = affix.charAt(j); 2210 buffer.append(c); 2211 if (c == '\'') buffer.append(c); 2212 } 2213 } 2214 if (needQuote) buffer.append('\''); 2215 } 2216 2217 /** 2218 * Does the real work of generating a pattern. */ 2219 private String toPattern(boolean localized) { 2220 StringBuffer result = new StringBuffer(); 2221 for (int j = 1; j >= 0; --j) { 2222 if (j == 1) 2223 appendAffix(result, posPrefixPattern, positivePrefix, localized); 2224 else appendAffix(result, negPrefixPattern, negativePrefix, localized); 2225 int i; 2226 int digitCount = useExponentialNotation 2227 ? getMaximumIntegerDigits() 2228 : Math.max(groupingSize, getMinimumIntegerDigits())+1; 2229 for (i = digitCount; i > 0; --i) { 2230 if (i != digitCount && isGroupingUsed() && groupingSize != 0 && 2231 i % groupingSize == 0) { 2232 result.append(localized ? symbols.getGroupingSeparator() : 2233 PATTERN_GROUPING_SEPARATOR); 2234 } 2235 result.append(i <= getMinimumIntegerDigits() 2236 ? (localized ? symbols.getZeroDigit() : PATTERN_ZERO_DIGIT) 2237 : (localized ? symbols.getDigit() : PATTERN_DIGIT)); 2238 } 2239 if (getMaximumFractionDigits() > 0 || decimalSeparatorAlwaysShown) 2240 result.append(localized ? symbols.getDecimalSeparator() : 2241 PATTERN_DECIMAL_SEPARATOR); 2242 for (i = 0; i < getMaximumFractionDigits(); ++i) { 2243 if (i < getMinimumFractionDigits()) { 2244 result.append(localized ? symbols.getZeroDigit() : 2245 PATTERN_ZERO_DIGIT); 2246 } else { 2247 result.append(localized ? symbols.getDigit() : 2248 PATTERN_DIGIT); 2249 } 2250 } 2251 if (useExponentialNotation) 2252 { 2253 result.append(localized ? symbols.getExponentSeparator() : 2254 PATTERN_EXPONENT); 2255 for (i=0; i<minExponentDigits; ++i) 2256 result.append(localized ? symbols.getZeroDigit() : 2257 PATTERN_ZERO_DIGIT); 2258 } 2259 if (j == 1) { 2260 appendAffix(result, posSuffixPattern, positiveSuffix, localized); 2261 if ((negSuffixPattern == posSuffixPattern && // n == p == null 2262 negativeSuffix.equals(positiveSuffix)) 2263 || (negSuffixPattern != null && 2264 negSuffixPattern.equals(posSuffixPattern))) { 2265 if ((negPrefixPattern != null && posPrefixPattern != null && 2266 negPrefixPattern.equals("'-" + posPrefixPattern)) || 2267 (negPrefixPattern == posPrefixPattern && // n == p == null 2268 negativePrefix.equals(symbols.getMinusSign() + positivePrefix))) 2269 break; 2270 } 2271 result.append(localized ? symbols.getPatternSeparator() : 2272 PATTERN_SEPARATOR); 2273 } else appendAffix(result, negSuffixPattern, negativeSuffix, localized); 2274 } 2275 return result.toString(); 2276 } 2277 2278 /** 2279 * Apply the given pattern to this Format object. A pattern is a 2280 * short-hand specification for the various formatting properties. 2281 * These properties can also be changed individually through the 2282 * various setter methods. 2283 * <p> 2284 * There is no limit to integer digits set 2285 * by this routine, since that is the typical end-user desire; 2286 * use setMaximumInteger if you want to set a real value. 2287 * For negative numbers, use a second pattern, separated by a semicolon 2288 * <P>Example <code>"#,#00.0#"</code> -> 1,234.56 2289 * <P>This means a minimum of 2 integer digits, 1 fraction digit, and 2290 * a maximum of 2 fraction digits. 2291 * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in 2292 * parentheses. 2293 * <p>In negative patterns, the minimum and maximum counts are ignored; 2294 * these are presumed to be set in the positive pattern. 2295 * 2296 * @exception NullPointerException if <code>pattern</code> is null 2297 * @exception IllegalArgumentException if the given pattern is invalid. 2298 */ 2299 public void applyPattern(String pattern) { 2300 applyPattern(pattern, false); 2301 } 2302 2303 /** 2304 * Apply the given pattern to this Format object. The pattern 2305 * is assumed to be in a localized notation. A pattern is a 2306 * short-hand specification for the various formatting properties. 2307 * These properties can also be changed individually through the 2308 * various setter methods. 2309 * <p> 2310 * There is no limit to integer digits set 2311 * by this routine, since that is the typical end-user desire; 2312 * use setMaximumInteger if you want to set a real value. 2313 * For negative numbers, use a second pattern, separated by a semicolon 2314 * <P>Example <code>"#,#00.0#"</code> -> 1,234.56 2315 * <P>This means a minimum of 2 integer digits, 1 fraction digit, and 2316 * a maximum of 2 fraction digits. 2317 * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in 2318 * parentheses. 2319 * <p>In negative patterns, the minimum and maximum counts are ignored; 2320 * these are presumed to be set in the positive pattern. 2321 * 2322 * @exception NullPointerException if <code>pattern</code> is null 2323 * @exception IllegalArgumentException if the given pattern is invalid. 2324 */ 2325 public void applyLocalizedPattern(String pattern) { 2326 applyPattern(pattern, true); 2327 } 2328 2329 /** 2330 * Does the real work of applying a pattern. 2331 */ 2332 private void applyPattern(String pattern, boolean localized) { 2333 char zeroDigit = PATTERN_ZERO_DIGIT; 2334 char groupingSeparator = PATTERN_GROUPING_SEPARATOR; 2335 char decimalSeparator = PATTERN_DECIMAL_SEPARATOR; 2336 char percent = PATTERN_PERCENT; 2337 char perMill = PATTERN_PER_MILLE; 2338 char digit = PATTERN_DIGIT; 2339 char separator = PATTERN_SEPARATOR; 2340 String exponent = PATTERN_EXPONENT; 2341 char minus = PATTERN_MINUS; 2342 if (localized) { 2343 zeroDigit = symbols.getZeroDigit(); 2344 groupingSeparator = symbols.getGroupingSeparator(); 2345 decimalSeparator = symbols.getDecimalSeparator(); 2346 percent = symbols.getPercent(); 2347 perMill = symbols.getPerMill(); 2348 digit = symbols.getDigit(); 2349 separator = symbols.getPatternSeparator(); 2350 exponent = symbols.getExponentSeparator(); 2351 minus = symbols.getMinusSign(); 2352 } 2353 boolean gotNegative = false; 2354 decimalSeparatorAlwaysShown = false; 2355 isCurrencyFormat = false; 2356 useExponentialNotation = false; 2357 2358 // Two variables are used to record the subrange of the pattern 2359 // occupied by phase 1. This is used during the processing of the 2360 // second pattern (the one representing negative numbers) to ensure 2361 // that no deviation exists in phase 1 between the two patterns. 2362 int phaseOneStart = 0; 2363 int phaseOneLength = 0; 2364 2365 int start = 0; 2366 for (int j = 1; j >= 0 && start < pattern.length(); --j) { 2367 boolean inQuote = false; 2368 StringBuffer prefix = new StringBuffer(); 2369 StringBuffer suffix = new StringBuffer(); 2370 int decimalPos = -1; 2371 int multiplier = 1; 2372 int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0; 2373 byte groupingCount = -1; 2374 2375 // The phase ranges from 0 to 2. Phase 0 is the prefix. Phase 1 is 2376 // the section of the pattern with digits, decimal separator, 2377 // grouping characters. Phase 2 is the suffix. In phases 0 and 2, 2378 // percent, per mille, and currency symbols are recognized and 2379 // translated. The separation of the characters into phases is 2380 // strictly enforced; if phase 1 characters are to appear in the 2381 // suffix, for example, they must be quoted. 2382 int phase = 0; 2383 2384 // The affix is either the prefix or the suffix. 2385 StringBuffer affix = prefix; 2386 2387 for (int pos = start; pos < pattern.length(); ++pos) { 2388 char ch = pattern.charAt(pos); 2389 switch (phase) { 2390 case 0: 2391 case 2: 2392 // Process the prefix / suffix characters 2393 if (inQuote) { 2394 // A quote within quotes indicates either the closing 2395 // quote or two quotes, which is a quote literal. That 2396 // is, we have the second quote in 'do' or 'don''t'. 2397 if (ch == QUOTE) { 2398 if ((pos+1) < pattern.length() && 2399 pattern.charAt(pos+1) == QUOTE) { 2400 ++pos; 2401 affix.append("''"); // 'don''t' 2402 } else { 2403 inQuote = false; // 'do' 2404 } 2405 continue; 2406 } 2407 } else { 2408 // Process unquoted characters seen in prefix or suffix 2409 // phase. 2410 if (ch == digit || 2411 ch == zeroDigit || 2412 ch == groupingSeparator || 2413 ch == decimalSeparator) { 2414 phase = 1; 2415 if (j == 1) { 2416 phaseOneStart = pos; 2417 } 2418 --pos; // Reprocess this character 2419 continue; 2420 } else if (ch == CURRENCY_SIGN) { 2421 // Use lookahead to determine if the currency sign 2422 // is doubled or not. 2423 boolean doubled = (pos + 1) < pattern.length() && 2424 pattern.charAt(pos + 1) == CURRENCY_SIGN; 2425 if (doubled) { // Skip over the doubled character 2426 ++pos; 2427 } 2428 isCurrencyFormat = true; 2429 affix.append(doubled ? "'\u00A4\u00A4" : "'\u00A4"); 2430 continue; 2431 } else if (ch == QUOTE) { 2432 // A quote outside quotes indicates either the 2433 // opening quote or two quotes, which is a quote 2434 // literal. That is, we have the first quote in 'do' 2435 // or o''clock. 2436 if (ch == QUOTE) { 2437 if ((pos+1) < pattern.length() && 2438 pattern.charAt(pos+1) == QUOTE) { 2439 ++pos; 2440 affix.append("''"); // o''clock 2441 } else { 2442 inQuote = true; // 'do' 2443 } 2444 continue; 2445 } 2446 } else if (ch == separator) { 2447 // Don't allow separators before we see digit 2448 // characters of phase 1, and don't allow separators 2449 // in the second pattern (j == 0). 2450 if (phase == 0 || j == 0) { 2451 throw new IllegalArgumentException("Unquoted special character '" + 2452 ch + "' in pattern \"" + pattern + '"'); 2453 } 2454 start = pos + 1; 2455 pos = pattern.length(); 2456 continue; 2457 } 2458 2459 // Next handle characters which are appended directly. 2460 else if (ch == percent) { 2461 if (multiplier != 1) { 2462 throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" + 2463 pattern + '"'); 2464 } 2465 multiplier = 100; 2466 affix.append("'%"); 2467 continue; 2468 } else if (ch == perMill) { 2469 if (multiplier != 1) { 2470 throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" + 2471 pattern + '"'); 2472 } 2473 multiplier = 1000; 2474 affix.append("'\u2030"); 2475 continue; 2476 } else if (ch == minus) { 2477 affix.append("'-"); 2478 continue; 2479 } 2480 } 2481 // Note that if we are within quotes, or if this is an 2482 // unquoted, non-special character, then we usually fall 2483 // through to here. 2484 affix.append(ch); 2485 break; 2486 2487 case 1: 2488 // Phase one must be identical in the two sub-patterns. We 2489 // enforce this by doing a direct comparison. While 2490 // processing the first sub-pattern, we just record its 2491 // length. While processing the second, we compare 2492 // characters. 2493 if (j == 1) { 2494 ++phaseOneLength; 2495 } else { 2496 if (--phaseOneLength == 0) { 2497 phase = 2; 2498 affix = suffix; 2499 } 2500 continue; 2501 } 2502 2503 // Process the digits, decimal, and grouping characters. We 2504 // record five pieces of information. We expect the digits 2505 // to occur in the pattern ####0000.####, and we record the 2506 // number of left digits, zero (central) digits, and right 2507 // digits. The position of the last grouping character is 2508 // recorded (should be somewhere within the first two blocks 2509 // of characters), as is the position of the decimal point, 2510 // if any (should be in the zero digits). If there is no 2511 // decimal point, then there should be no right digits. 2512 if (ch == digit) { 2513 if (zeroDigitCount > 0) { 2514 ++digitRightCount; 2515 } else { 2516 ++digitLeftCount; 2517 } 2518 if (groupingCount >= 0 && decimalPos < 0) { 2519 ++groupingCount; 2520 } 2521 } else if (ch == zeroDigit) { 2522 if (digitRightCount > 0) { 2523 throw new IllegalArgumentException("Unexpected '0' in pattern \"" + 2524 pattern + '"'); 2525 } 2526 ++zeroDigitCount; 2527 if (groupingCount >= 0 && decimalPos < 0) { 2528 ++groupingCount; 2529 } 2530 } else if (ch == groupingSeparator) { 2531 groupingCount = 0; 2532 } else if (ch == decimalSeparator) { 2533 if (decimalPos >= 0) { 2534 throw new IllegalArgumentException("Multiple decimal separators in pattern \"" + 2535 pattern + '"'); 2536 } 2537 decimalPos = digitLeftCount + zeroDigitCount + digitRightCount; 2538 } else if (pattern.regionMatches(pos, exponent, 0, exponent.length())){ 2539 if (useExponentialNotation) { 2540 throw new IllegalArgumentException("Multiple exponential " + 2541 "symbols in pattern \"" + pattern + '"'); 2542 } 2543 useExponentialNotation = true; 2544 minExponentDigits = 0; 2545 2546 // Use lookahead to parse out the exponential part 2547 // of the pattern, then jump into phase 2. 2548 pos = pos+exponent.length(); 2549 while (pos < pattern.length() && 2550 pattern.charAt(pos) == zeroDigit) { 2551 ++minExponentDigits; 2552 ++phaseOneLength; 2553 ++pos; 2554 } 2555 2556 if ((digitLeftCount + zeroDigitCount) < 1 || 2557 minExponentDigits < 1) { 2558 throw new IllegalArgumentException("Malformed exponential " + 2559 "pattern \"" + pattern + '"'); 2560 } 2561 2562 // Transition to phase 2 2563 phase = 2; 2564 affix = suffix; 2565 --pos; 2566 continue; 2567 } else { 2568 phase = 2; 2569 affix = suffix; 2570 --pos; 2571 --phaseOneLength; 2572 continue; 2573 } 2574 break; 2575 } 2576 } 2577 2578 // Handle patterns with no '0' pattern character. These patterns 2579 // are legal, but must be interpreted. "##.###" -> "#0.###". 2580 // ".###" -> ".0##". 2581 /* We allow patterns of the form "####" to produce a zeroDigitCount 2582 * of zero (got that?); although this seems like it might make it 2583 * possible for format() to produce empty strings, format() checks 2584 * for this condition and outputs a zero digit in this situation. 2585 * Having a zeroDigitCount of zero yields a minimum integer digits 2586 * of zero, which allows proper round-trip patterns. That is, we 2587 * don't want "#" to become "#0" when toPattern() is called (even 2588 * though that's what it really is, semantically). 2589 */ 2590 if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) { 2591 // Handle "###.###" and "###." and ".###" 2592 int n = decimalPos; 2593 if (n == 0) { // Handle ".###" 2594 ++n; 2595 } 2596 digitRightCount = digitLeftCount - n; 2597 digitLeftCount = n - 1; 2598 zeroDigitCount = 1; 2599 } 2600 2601 // Do syntax checking on the digits. 2602 if ((decimalPos < 0 && digitRightCount > 0) || 2603 (decimalPos >= 0 && (decimalPos < digitLeftCount || 2604 decimalPos > (digitLeftCount + zeroDigitCount))) || 2605 groupingCount == 0 || inQuote) { 2606 throw new IllegalArgumentException("Malformed pattern \"" + 2607 pattern + '"'); 2608 } 2609 2610 if (j == 1) { 2611 posPrefixPattern = prefix.toString(); 2612 posSuffixPattern = suffix.toString(); 2613 negPrefixPattern = posPrefixPattern; // assume these for now 2614 negSuffixPattern = posSuffixPattern; 2615 int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount; 2616 /* The effectiveDecimalPos is the position the decimal is at or 2617 * would be at if there is no decimal. Note that if decimalPos<0, 2618 * then digitTotalCount == digitLeftCount + zeroDigitCount. 2619 */ 2620 int effectiveDecimalPos = decimalPos >= 0 ? 2621 decimalPos : digitTotalCount; 2622 setMinimumIntegerDigits(effectiveDecimalPos - digitLeftCount); 2623 setMaximumIntegerDigits(useExponentialNotation ? 2624 digitLeftCount + getMinimumIntegerDigits() : 2625 MAXIMUM_INTEGER_DIGITS); 2626 setMaximumFractionDigits(decimalPos >= 0 ? 2627 (digitTotalCount - decimalPos) : 0); 2628 setMinimumFractionDigits(decimalPos >= 0 ? 2629 (digitLeftCount + zeroDigitCount - decimalPos) : 0); 2630 setGroupingUsed(groupingCount > 0); 2631 this.groupingSize = (groupingCount > 0) ? groupingCount : 0; 2632 this.multiplier = multiplier; 2633 setDecimalSeparatorAlwaysShown(decimalPos == 0 || 2634 decimalPos == digitTotalCount); 2635 } else { 2636 negPrefixPattern = prefix.toString(); 2637 negSuffixPattern = suffix.toString(); 2638 gotNegative = true; 2639 } 2640 } 2641 2642 if (pattern.length() == 0) { 2643 posPrefixPattern = posSuffixPattern = ""; 2644 setMinimumIntegerDigits(0); 2645 setMaximumIntegerDigits(MAXIMUM_INTEGER_DIGITS); 2646 setMinimumFractionDigits(0); 2647 setMaximumFractionDigits(MAXIMUM_FRACTION_DIGITS); 2648 } 2649 2650 // If there was no negative pattern, or if the negative pattern is 2651 // identical to the positive pattern, then prepend the minus sign to 2652 // the positive pattern to form the negative pattern. 2653 if (!gotNegative || 2654 (negPrefixPattern.equals(posPrefixPattern) 2655 && negSuffixPattern.equals(posSuffixPattern))) { 2656 negSuffixPattern = posSuffixPattern; 2657 negPrefixPattern = "'-" + posPrefixPattern; 2658 } 2659 2660 expandAffixes(); 2661 } 2662 2663 /** 2664 * Sets the maximum number of digits allowed in the integer portion of a 2665 * number. 2666 * For formatting numbers other than <code>BigInteger</code> and 2667 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and 2668 * 309 is used. Negative input values are replaced with 0. 2669 * @see NumberFormat#setMaximumIntegerDigits 2670 */ 2671 public void setMaximumIntegerDigits(int newValue) { 2672 maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS); 2673 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? 2674 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits); 2675 if (minimumIntegerDigits > maximumIntegerDigits) { 2676 minimumIntegerDigits = maximumIntegerDigits; 2677 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? 2678 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits); 2679 } 2680 } 2681 2682 /** 2683 * Sets the minimum number of digits allowed in the integer portion of a 2684 * number. 2685 * For formatting numbers other than <code>BigInteger</code> and 2686 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and 2687 * 309 is used. Negative input values are replaced with 0. 2688 * @see NumberFormat#setMinimumIntegerDigits 2689 */ 2690 public void setMinimumIntegerDigits(int newValue) { 2691 minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS); 2692 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? 2693 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits); 2694 if (minimumIntegerDigits > maximumIntegerDigits) { 2695 maximumIntegerDigits = minimumIntegerDigits; 2696 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? 2697 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits); 2698 } 2699 } 2700 2701 /** 2702 * Sets the maximum number of digits allowed in the fraction portion of a 2703 * number. 2704 * For formatting numbers other than <code>BigInteger</code> and 2705 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and 2706 * 340 is used. Negative input values are replaced with 0. 2707 * @see NumberFormat#setMaximumFractionDigits 2708 */ 2709 public void setMaximumFractionDigits(int newValue) { 2710 maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS); 2711 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ? 2712 DOUBLE_FRACTION_DIGITS : maximumFractionDigits); 2713 if (minimumFractionDigits > maximumFractionDigits) { 2714 minimumFractionDigits = maximumFractionDigits; 2715 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ? 2716 DOUBLE_FRACTION_DIGITS : minimumFractionDigits); 2717 } 2718 } 2719 2720 /** 2721 * Sets the minimum number of digits allowed in the fraction portion of a 2722 * number. 2723 * For formatting numbers other than <code>BigInteger</code> and 2724 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and 2725 * 340 is used. Negative input values are replaced with 0. 2726 * @see NumberFormat#setMinimumFractionDigits 2727 */ 2728 public void setMinimumFractionDigits(int newValue) { 2729 minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS); 2730 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ? 2731 DOUBLE_FRACTION_DIGITS : minimumFractionDigits); 2732 if (minimumFractionDigits > maximumFractionDigits) { 2733 maximumFractionDigits = minimumFractionDigits; 2734 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ? 2735 DOUBLE_FRACTION_DIGITS : maximumFractionDigits); 2736 } 2737 } 2738 2739 /** 2740 * Gets the maximum number of digits allowed in the integer portion of a 2741 * number. 2742 * For formatting numbers other than <code>BigInteger</code> and 2743 * <code>BigDecimal</code> objects, the lower of the return value and 2744 * 309 is used. 2745 * @see #setMaximumIntegerDigits 2746 */ 2747 public int getMaximumIntegerDigits() { 2748 return maximumIntegerDigits; 2749 } 2750 2751 /** 2752 * Gets the minimum number of digits allowed in the integer portion of a 2753 * number. 2754 * For formatting numbers other than <code>BigInteger</code> and 2755 * <code>BigDecimal</code> objects, the lower of the return value and 2756 * 309 is used. 2757 * @see #setMinimumIntegerDigits 2758 */ 2759 public int getMinimumIntegerDigits() { 2760 return minimumIntegerDigits; 2761 } 2762 2763 /** 2764 * Gets the maximum number of digits allowed in the fraction portion of a 2765 * number. 2766 * For formatting numbers other than <code>BigInteger</code> and 2767 * <code>BigDecimal</code> objects, the lower of the return value and 2768 * 340 is used. 2769 * @see #setMaximumFractionDigits 2770 */ 2771 public int getMaximumFractionDigits() { 2772 return maximumFractionDigits; 2773 } 2774 2775 /** 2776 * Gets the minimum number of digits allowed in the fraction portion of a 2777 * number. 2778 * For formatting numbers other than <code>BigInteger</code> and 2779 * <code>BigDecimal</code> objects, the lower of the return value and 2780 * 340 is used. 2781 * @see #setMinimumFractionDigits 2782 */ 2783 public int getMinimumFractionDigits() { 2784 return minimumFractionDigits; 2785 } 2786 2787 /** 2788 * Gets the currency used by this decimal format when formatting 2789 * currency values. 2790 * The currency is obtained by calling 2791 * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency} 2792 * on this number format's symbols. 2793 * 2794 * @return the currency used by this decimal format, or <code>null</code> 2795 * @since 1.4 2796 */ 2797 public Currency getCurrency() { 2798 return symbols.getCurrency(); 2799 } 2800 2801 /** 2802 * Sets the currency used by this number format when formatting 2803 * currency values. This does not update the minimum or maximum 2804 * number of fraction digits used by the number format. 2805 * The currency is set by calling 2806 * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency} 2807 * on this number format's symbols. 2808 * 2809 * @param currency the new currency to be used by this decimal format 2810 * @exception NullPointerException if <code>currency</code> is null 2811 * @since 1.4 2812 */ 2813 public void setCurrency(Currency currency) { 2814 if (currency != symbols.getCurrency()) { 2815 symbols.setCurrency(currency); 2816 if (isCurrencyFormat) { 2817 expandAffixes(); 2818 } 2819 } 2820 } 2821 2822 /** 2823 * Gets the {@link java.math.RoundingMode} used in this DecimalFormat. 2824 * 2825 * @return The <code>RoundingMode</code> used for this DecimalFormat. 2826 * @see #setRoundingMode(RoundingMode) 2827 * @since 1.6 2828 */ 2829 public RoundingMode getRoundingMode() { 2830 return roundingMode; 2831 } 2832 2833 /** 2834 * Sets the {@link java.math.RoundingMode} used in this DecimalFormat. 2835 * 2836 * @param roundingMode The <code>RoundingMode</code> to be used 2837 * @see #getRoundingMode() 2838 * @exception NullPointerException if <code>roundingMode</code> is null. 2839 * @since 1.6 2840 */ 2841 public void setRoundingMode(RoundingMode roundingMode) { 2842 if (roundingMode == null) { 2843 throw new NullPointerException(); 2844 } 2845 2846 this.roundingMode = roundingMode; 2847 digitList.setRoundingMode(roundingMode); 2848 } 2849 2850 /** 2851 * Adjusts the minimum and maximum fraction digits to values that 2852 * are reasonable for the currency's default fraction digits. 2853 */ 2854 void adjustForCurrencyDefaultFractionDigits() { 2855 Currency currency = symbols.getCurrency(); 2856 if (currency == null) { 2857 try { 2858 currency = Currency.getInstance(symbols.getInternationalCurrencySymbol()); 2859 } catch (IllegalArgumentException e) { 2860 } 2861 } 2862 if (currency != null) { 2863 int digits = currency.getDefaultFractionDigits(); 2864 if (digits != -1) { 2865 int oldMinDigits = getMinimumFractionDigits(); 2866 // Common patterns are "#.##", "#.00", "#". 2867 // Try to adjust all of them in a reasonable way. 2868 if (oldMinDigits == getMaximumFractionDigits()) { 2869 setMinimumFractionDigits(digits); 2870 setMaximumFractionDigits(digits); 2871 } else { 2872 setMinimumFractionDigits(Math.min(digits, oldMinDigits)); 2873 setMaximumFractionDigits(digits); 2874 } 2875 } 2876 } 2877 } 2878 2879 /** 2880 * Reads the default serializable fields from the stream and performs 2881 * validations and adjustments for older serialized versions. The 2882 * validations and adjustments are: 2883 * <ol> 2884 * <li> 2885 * Verify that the superclass's digit count fields correctly reflect 2886 * the limits imposed on formatting numbers other than 2887 * <code>BigInteger</code> and <code>BigDecimal</code> objects. These 2888 * limits are stored in the superclass for serialization compatibility 2889 * with older versions, while the limits for <code>BigInteger</code> and 2890 * <code>BigDecimal</code> objects are kept in this class. 2891 * If, in the superclass, the minimum or maximum integer digit count is 2892 * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or 2893 * maximum fraction digit count is larger than 2894 * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid 2895 * and this method throws an <code>InvalidObjectException</code>. 2896 * <li> 2897 * If <code>serialVersionOnStream</code> is less than 4, initialize 2898 * <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN 2899 * RoundingMode.HALF_EVEN}. This field is new with version 4. 2900 * <li> 2901 * If <code>serialVersionOnStream</code> is less than 3, then call 2902 * the setters for the minimum and maximum integer and fraction digits with 2903 * the values of the corresponding superclass getters to initialize the 2904 * fields in this class. The fields in this class are new with version 3. 2905 * <li> 2906 * If <code>serialVersionOnStream</code> is less than 1, indicating that 2907 * the stream was written by JDK 1.1, initialize 2908 * <code>useExponentialNotation</code> 2909 * to false, since it was not present in JDK 1.1. 2910 * <li> 2911 * Set <code>serialVersionOnStream</code> to the maximum allowed value so 2912 * that default serialization will work properly if this object is streamed 2913 * out again. 2914 * </ol> 2915 * 2916 * <p>Stream versions older than 2 will not have the affix pattern variables 2917 * <code>posPrefixPattern</code> etc. As a result, they will be initialized 2918 * to <code>null</code>, which means the affix strings will be taken as 2919 * literal values. This is exactly what we want, since that corresponds to 2920 * the pre-version-2 behavior. 2921 */ 2922 private void readObject(ObjectInputStream stream) 2923 throws IOException, ClassNotFoundException 2924 { 2925 stream.defaultReadObject(); 2926 digitList = new DigitList(); 2927 2928 if (serialVersionOnStream < 4) { 2929 setRoundingMode(RoundingMode.HALF_EVEN); 2930 } 2931 // We only need to check the maximum counts because NumberFormat 2932 // .readObject has already ensured that the maximum is greater than the 2933 // minimum count. 2934 if (super.getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS || 2935 super.getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) { 2936 throw new InvalidObjectException("Digit count out of range"); 2937 } 2938 if (serialVersionOnStream < 3) { 2939 setMaximumIntegerDigits(super.getMaximumIntegerDigits()); 2940 setMinimumIntegerDigits(super.getMinimumIntegerDigits()); 2941 setMaximumFractionDigits(super.getMaximumFractionDigits()); 2942 setMinimumFractionDigits(super.getMinimumFractionDigits()); 2943 } 2944 if (serialVersionOnStream < 1) { 2945 // Didn't have exponential fields 2946 useExponentialNotation = false; 2947 } 2948 serialVersionOnStream = currentSerialVersion; 2949 } 2950 2951 //---------------------------------------------------------------------- 2952 // INSTANCE VARIABLES 2953 //---------------------------------------------------------------------- 2954 2955 private transient DigitList digitList = new DigitList(); 2956 2957 /** 2958 * The symbol used as a prefix when formatting positive numbers, e.g. "+". 2959 * 2960 * @serial 2961 * @see #getPositivePrefix 2962 */ 2963 private String positivePrefix = ""; 2964 2965 /** 2966 * The symbol used as a suffix when formatting positive numbers. 2967 * This is often an empty string. 2968 * 2969 * @serial 2970 * @see #getPositiveSuffix 2971 */ 2972 private String positiveSuffix = ""; 2973 2974 /** 2975 * The symbol used as a prefix when formatting negative numbers, e.g. "-". 2976 * 2977 * @serial 2978 * @see #getNegativePrefix 2979 */ 2980 private String negativePrefix = "-"; 2981 2982 /** 2983 * The symbol used as a suffix when formatting negative numbers. 2984 * This is often an empty string. 2985 * 2986 * @serial 2987 * @see #getNegativeSuffix 2988 */ 2989 private String negativeSuffix = ""; 2990 2991 /** 2992 * The prefix pattern for non-negative numbers. This variable corresponds 2993 * to <code>positivePrefix</code>. 2994 * 2995 * <p>This pattern is expanded by the method <code>expandAffix()</code> to 2996 * <code>positivePrefix</code> to update the latter to reflect changes in 2997 * <code>symbols</code>. If this variable is <code>null</code> then 2998 * <code>positivePrefix</code> is taken as a literal value that does not 2999 * change when <code>symbols</code> changes. This variable is always 3000 * <code>null</code> for <code>DecimalFormat</code> objects older than 3001 * stream version 2 restored from stream. 3002 * 3003 * @serial 3004 * @since 1.3 3005 */ 3006 private String posPrefixPattern; 3007 3008 /** 3009 * The suffix pattern for non-negative numbers. This variable corresponds 3010 * to <code>positiveSuffix</code>. This variable is analogous to 3011 * <code>posPrefixPattern</code>; see that variable for further 3012 * documentation. 3013 * 3014 * @serial 3015 * @since 1.3 3016 */ 3017 private String posSuffixPattern; 3018 3019 /** 3020 * The prefix pattern for negative numbers. This variable corresponds 3021 * to <code>negativePrefix</code>. This variable is analogous to 3022 * <code>posPrefixPattern</code>; see that variable for further 3023 * documentation. 3024 * 3025 * @serial 3026 * @since 1.3 3027 */ 3028 private String negPrefixPattern; 3029 3030 /** 3031 * The suffix pattern for negative numbers. This variable corresponds 3032 * to <code>negativeSuffix</code>. This variable is analogous to 3033 * <code>posPrefixPattern</code>; see that variable for further 3034 * documentation. 3035 * 3036 * @serial 3037 * @since 1.3 3038 */ 3039 private String negSuffixPattern; 3040 3041 /** 3042 * The multiplier for use in percent, per mille, etc. 3043 * 3044 * @serial 3045 * @see #getMultiplier 3046 */ 3047 private int multiplier = 1; 3048 3049 /** 3050 * The number of digits between grouping separators in the integer 3051 * portion of a number. Must be greater than 0 if 3052 * <code>NumberFormat.groupingUsed</code> is true. 3053 * 3054 * @serial 3055 * @see #getGroupingSize 3056 * @see java.text.NumberFormat#isGroupingUsed 3057 */ 3058 private byte groupingSize = 3; // invariant, > 0 if useThousands 3059 3060 /** 3061 * If true, forces the decimal separator to always appear in a formatted 3062 * number, even if the fractional part of the number is zero. 3063 * 3064 * @serial 3065 * @see #isDecimalSeparatorAlwaysShown 3066 */ 3067 private boolean decimalSeparatorAlwaysShown = false; 3068 3069 /** 3070 * If true, parse returns BigDecimal wherever possible. 3071 * 3072 * @serial 3073 * @see #isParseBigDecimal 3074 * @since 1.5 3075 */ 3076 private boolean parseBigDecimal = false; 3077 3078 3079 /** 3080 * True if this object represents a currency format. This determines 3081 * whether the monetary decimal separator is used instead of the normal one. 3082 */ 3083 private transient boolean isCurrencyFormat = false; 3084 3085 /** 3086 * The <code>DecimalFormatSymbols</code> object used by this format. 3087 * It contains the symbols used to format numbers, e.g. the grouping separator, 3088 * decimal separator, and so on. 3089 * 3090 * @serial 3091 * @see #setDecimalFormatSymbols 3092 * @see java.text.DecimalFormatSymbols 3093 */ 3094 private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols(); 3095 3096 /** 3097 * True to force the use of exponential (i.e. scientific) notation when formatting 3098 * numbers. 3099 * 3100 * @serial 3101 * @since 1.2 3102 */ 3103 private boolean useExponentialNotation; // Newly persistent in the Java 2 platform v.1.2 3104 3105 /** 3106 * FieldPositions describing the positive prefix String. This is 3107 * lazily created. Use <code>getPositivePrefixFieldPositions</code> 3108 * when needed. 3109 */ 3110 private transient FieldPosition[] positivePrefixFieldPositions; 3111 3112 /** 3113 * FieldPositions describing the positive suffix String. This is 3114 * lazily created. Use <code>getPositiveSuffixFieldPositions</code> 3115 * when needed. 3116 */ 3117 private transient FieldPosition[] positiveSuffixFieldPositions; 3118 3119 /** 3120 * FieldPositions describing the negative prefix String. This is 3121 * lazily created. Use <code>getNegativePrefixFieldPositions</code> 3122 * when needed. 3123 */ 3124 private transient FieldPosition[] negativePrefixFieldPositions; 3125 3126 /** 3127 * FieldPositions describing the negative suffix String. This is 3128 * lazily created. Use <code>getNegativeSuffixFieldPositions</code> 3129 * when needed. 3130 */ 3131 private transient FieldPosition[] negativeSuffixFieldPositions; 3132 3133 /** 3134 * The minimum number of digits used to display the exponent when a number is 3135 * formatted in exponential notation. This field is ignored if 3136 * <code>useExponentialNotation</code> is not true. 3137 * 3138 * @serial 3139 * @since 1.2 3140 */ 3141 private byte minExponentDigits; // Newly persistent in the Java 2 platform v.1.2 3142 3143 /** 3144 * The maximum number of digits allowed in the integer portion of a 3145 * <code>BigInteger</code> or <code>BigDecimal</code> number. 3146 * <code>maximumIntegerDigits</code> must be greater than or equal to 3147 * <code>minimumIntegerDigits</code>. 3148 * 3149 * @serial 3150 * @see #getMaximumIntegerDigits 3151 * @since 1.5 3152 */ 3153 private int maximumIntegerDigits = super.getMaximumIntegerDigits(); 3154 3155 /** 3156 * The minimum number of digits allowed in the integer portion of a 3157 * <code>BigInteger</code> or <code>BigDecimal</code> number. 3158 * <code>minimumIntegerDigits</code> must be less than or equal to 3159 * <code>maximumIntegerDigits</code>. 3160 * 3161 * @serial 3162 * @see #getMinimumIntegerDigits 3163 * @since 1.5 3164 */ 3165 private int minimumIntegerDigits = super.getMinimumIntegerDigits(); 3166 3167 /** 3168 * The maximum number of digits allowed in the fractional portion of a 3169 * <code>BigInteger</code> or <code>BigDecimal</code> number. 3170 * <code>maximumFractionDigits</code> must be greater than or equal to 3171 * <code>minimumFractionDigits</code>. 3172 * 3173 * @serial 3174 * @see #getMaximumFractionDigits 3175 * @since 1.5 3176 */ 3177 private int maximumFractionDigits = super.getMaximumFractionDigits(); 3178 3179 /** 3180 * The minimum number of digits allowed in the fractional portion of a 3181 * <code>BigInteger</code> or <code>BigDecimal</code> number. 3182 * <code>minimumFractionDigits</code> must be less than or equal to 3183 * <code>maximumFractionDigits</code>. 3184 * 3185 * @serial 3186 * @see #getMinimumFractionDigits 3187 * @since 1.5 3188 */ 3189 private int minimumFractionDigits = super.getMinimumFractionDigits(); 3190 3191 /** 3192 * The {@link java.math.RoundingMode} used in this DecimalFormat. 3193 * 3194 * @serial 3195 * @since 1.6 3196 */ 3197 private RoundingMode roundingMode = RoundingMode.HALF_EVEN; 3198 3199 //---------------------------------------------------------------------- 3200 3201 static final int currentSerialVersion = 4; 3202 3203 /** 3204 * The internal serial version which says which version was written. 3205 * Possible values are: 3206 * <ul> 3207 * <li><b>0</b> (default): versions before the Java 2 platform v1.2 3208 * <li><b>1</b>: version for 1.2, which includes the two new fields 3209 * <code>useExponentialNotation</code> and 3210 * <code>minExponentDigits</code>. 3211 * <li><b>2</b>: version for 1.3 and later, which adds four new fields: 3212 * <code>posPrefixPattern</code>, <code>posSuffixPattern</code>, 3213 * <code>negPrefixPattern</code>, and <code>negSuffixPattern</code>. 3214 * <li><b>3</b>: version for 1.5 and later, which adds five new fields: 3215 * <code>maximumIntegerDigits</code>, 3216 * <code>minimumIntegerDigits</code>, 3217 * <code>maximumFractionDigits</code>, 3218 * <code>minimumFractionDigits</code>, and 3219 * <code>parseBigDecimal</code>. 3220 * <li><b>4</b>: version for 1.6 and later, which adds one new field: 3221 * <code>roundingMode</code>. 3222 * </ul> 3223 * @since 1.2 3224 * @serial 3225 */ 3226 private int serialVersionOnStream = currentSerialVersion; 3227 3228 //---------------------------------------------------------------------- 3229 // CONSTANTS 3230 //---------------------------------------------------------------------- 3231 3232 // Constants for characters used in programmatic (unlocalized) patterns. 3233 private static final char PATTERN_ZERO_DIGIT = '0'; 3234 private static final char PATTERN_GROUPING_SEPARATOR = ','; 3235 private static final char PATTERN_DECIMAL_SEPARATOR = '.'; 3236 private static final char PATTERN_PER_MILLE = '\u2030'; 3237 private static final char PATTERN_PERCENT = '%'; 3238 private static final char PATTERN_DIGIT = '#'; 3239 private static final char PATTERN_SEPARATOR = ';'; 3240 private static final String PATTERN_EXPONENT = "E"; 3241 private static final char PATTERN_MINUS = '-'; 3242 3243 /** 3244 * The CURRENCY_SIGN is the standard Unicode symbol for currency. It 3245 * is used in patterns and substituted with either the currency symbol, 3246 * or if it is doubled, with the international currency symbol. If the 3247 * CURRENCY_SIGN is seen in a pattern, then the decimal separator is 3248 * replaced with the monetary decimal separator. 3249 * 3250 * The CURRENCY_SIGN is not localized. 3251 */ 3252 private static final char CURRENCY_SIGN = '\u00A4'; 3253 3254 private static final char QUOTE = '\''; 3255 3256 private static FieldPosition[] EmptyFieldPositionArray = new FieldPosition[0]; 3257 3258 // Upper limit on integer and fraction digits for a Java double 3259 static final int DOUBLE_INTEGER_DIGITS = 309; 3260 static final int DOUBLE_FRACTION_DIGITS = 340; 3261 3262 // Upper limit on integer and fraction digits for BigDecimal and BigInteger 3263 static final int MAXIMUM_INTEGER_DIGITS = Integer.MAX_VALUE; 3264 static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE; 3265 3266 // Proclaim JDK 1.1 serial compatibility. 3267 static final long serialVersionUID = 864413376551465018L; 3268 3269 /** 3270 * Cache to hold the NumberPattern of a Locale. 3271 */ 3272 private static final ConcurrentMap<Locale, String> cachedLocaleData 3273 = new ConcurrentHashMap<Locale, String>(3); 3274 }