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.Arrays; 49 import java.util.Currency; 50 import java.util.Locale; 51 import java.util.ResourceBundle; 52 import java.util.concurrent.ConcurrentHashMap; 53 import java.util.concurrent.ConcurrentMap; 54 import java.util.concurrent.atomic.AtomicInteger; 55 import java.util.concurrent.atomic.AtomicLong; 56 import sun.util.resources.LocaleData; 57 58 /** 59 * <code>DecimalFormat</code> is a concrete subclass of 60 * <code>NumberFormat</code> that formats decimal numbers. It has a variety of 61 * features designed to make it possible to parse and format numbers in any 62 * locale, including support for Western, Arabic, and Indic digits. It also 63 * supports different kinds of numbers, including integers (123), fixed-point 64 * numbers (123.4), scientific notation (1.23E4), percentages (12%), and 65 * currency amounts ($123). All of these can be localized. 66 * 67 * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the 68 * default locale, call one of <code>NumberFormat</code>'s factory methods, such 69 * as <code>getInstance()</code>. In general, do not call the 70 * <code>DecimalFormat</code> constructors directly, since the 71 * <code>NumberFormat</code> factory methods may return subclasses other than 72 * <code>DecimalFormat</code>. If you need to customize the format object, do 73 * something like this: 74 * 75 * <blockquote><pre> 76 * NumberFormat f = NumberFormat.getInstance(loc); 77 * if (f instanceof DecimalFormat) { 78 * ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true); 79 * } 80 * </pre></blockquote> 81 * 82 * <p>A <code>DecimalFormat</code> comprises a <em>pattern</em> and a set of 83 * <em>symbols</em>. The pattern may be set directly using 84 * <code>applyPattern()</code>, or indirectly using the API methods. The 85 * symbols are stored in a <code>DecimalFormatSymbols</code> object. When using 86 * the <code>NumberFormat</code> factory methods, the pattern and symbols are 87 * read from localized <code>ResourceBundle</code>s. 88 * 89 * <h4>Patterns</h4> 90 * 91 * <code>DecimalFormat</code> patterns have the following syntax: 92 * <blockquote><pre> 93 * <i>Pattern:</i> 94 * <i>PositivePattern</i> 95 * <i>PositivePattern</i> ; <i>NegativePattern</i> 96 * <i>PositivePattern:</i> 97 * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i> 98 * <i>NegativePattern:</i> 99 * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i> 100 * <i>Prefix:</i> 101 * any Unicode characters except \uFFFE, \uFFFF, and special characters 102 * <i>Suffix:</i> 103 * any Unicode characters except \uFFFE, \uFFFF, and special characters 104 * <i>Number:</i> 105 * <i>Integer</i> <i>Exponent<sub>opt</sub></i> 106 * <i>Integer</i> . <i>Fraction</i> <i>Exponent<sub>opt</sub></i> 107 * <i>Integer:</i> 108 * <i>MinimumInteger</i> 109 * # 110 * # <i>Integer</i> 111 * # , <i>Integer</i> 112 * <i>MinimumInteger:</i> 113 * 0 114 * 0 <i>MinimumInteger</i> 115 * 0 , <i>MinimumInteger</i> 116 * <i>Fraction:</i> 117 * <i>MinimumFraction<sub>opt</sub></i> <i>OptionalFraction<sub>opt</sub></i> 118 * <i>MinimumFraction:</i> 119 * 0 <i>MinimumFraction<sub>opt</sub></i> 120 * <i>OptionalFraction:</i> 121 * # <i>OptionalFraction<sub>opt</sub></i> 122 * <i>Exponent:</i> 123 * E <i>MinimumExponent</i> 124 * <i>MinimumExponent:</i> 125 * 0 <i>MinimumExponent<sub>opt</sub></i> 126 * </pre></blockquote> 127 * 128 * <p>A <code>DecimalFormat</code> pattern contains a positive and negative 129 * subpattern, for example, <code>"#,##0.00;(#,##0.00)"</code>. Each 130 * subpattern has a prefix, numeric part, and suffix. The negative subpattern 131 * is optional; if absent, then the positive subpattern prefixed with the 132 * localized minus sign (<code>'-'</code> in most locales) is used as the 133 * negative subpattern. That is, <code>"0.00"</code> alone is equivalent to 134 * <code>"0.00;-0.00"</code>. If there is an explicit negative subpattern, it 135 * serves only to specify the negative prefix and suffix; the number of digits, 136 * minimal digits, and other characteristics are all the same as the positive 137 * pattern. That means that <code>"#,##0.0#;(#)"</code> produces precisely 138 * the same behavior as <code>"#,##0.0#;(#,##0.0#)"</code>. 139 * 140 * <p>The prefixes, suffixes, and various symbols used for infinity, digits, 141 * thousands separators, decimal separators, etc. may be set to arbitrary 142 * values, and they will appear properly during formatting. However, care must 143 * be taken that the symbols and strings do not conflict, or parsing will be 144 * unreliable. For example, either the positive and negative prefixes or the 145 * suffixes must be distinct for <code>DecimalFormat.parse()</code> to be able 146 * to distinguish positive from negative values. (If they are identical, then 147 * <code>DecimalFormat</code> will behave as if no negative subpattern was 148 * specified.) Another example is that the decimal separator and thousands 149 * separator should be distinct characters, or parsing will be impossible. 150 * 151 * <p>The grouping separator is commonly used for thousands, but in some 152 * countries it separates ten-thousands. The grouping size is a constant number 153 * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for 154 * 1,0000,0000. If you supply a pattern with multiple grouping characters, the 155 * interval between the last one and the end of the integer is the one that is 156 * used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> == 157 * <code>"##,####,####"</code>. 158 * 159 * <h4>Special Pattern Characters</h4> 160 * 161 * <p>Many characters in a pattern are taken literally; they are matched during 162 * parsing and output unchanged during formatting. Special characters, on the 163 * other hand, stand for other characters, strings, or classes of characters. 164 * They must be quoted, unless noted otherwise, if they are to appear in the 165 * prefix or suffix as literals. 166 * 167 * <p>The characters listed here are used in non-localized patterns. Localized 168 * patterns use the corresponding characters taken from this formatter's 169 * <code>DecimalFormatSymbols</code> object instead, and these characters lose 170 * their special status. Two exceptions are the currency sign and quote, which 171 * are not localized. 172 * 173 * <blockquote> 174 * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol, 175 * location, localized, and meaning."> 176 * <tr bgcolor="#ccccff"> 177 * <th align=left>Symbol 178 * <th align=left>Location 179 * <th align=left>Localized? 180 * <th align=left>Meaning 181 * <tr valign=top> 182 * <td><code>0</code> 183 * <td>Number 184 * <td>Yes 185 * <td>Digit 186 * <tr valign=top bgcolor="#eeeeff"> 187 * <td><code>#</code> 188 * <td>Number 189 * <td>Yes 190 * <td>Digit, zero shows as absent 191 * <tr valign=top> 192 * <td><code>.</code> 193 * <td>Number 194 * <td>Yes 195 * <td>Decimal separator or monetary decimal separator 196 * <tr valign=top bgcolor="#eeeeff"> 197 * <td><code>-</code> 198 * <td>Number 199 * <td>Yes 200 * <td>Minus sign 201 * <tr valign=top> 202 * <td><code>,</code> 203 * <td>Number 204 * <td>Yes 205 * <td>Grouping separator 206 * <tr valign=top bgcolor="#eeeeff"> 207 * <td><code>E</code> 208 * <td>Number 209 * <td>Yes 210 * <td>Separates mantissa and exponent in scientific notation. 211 * <em>Need not be quoted in prefix or suffix.</em> 212 * <tr valign=top> 213 * <td><code>;</code> 214 * <td>Subpattern boundary 215 * <td>Yes 216 * <td>Separates positive and negative subpatterns 217 * <tr valign=top bgcolor="#eeeeff"> 218 * <td><code>%</code> 219 * <td>Prefix or suffix 220 * <td>Yes 221 * <td>Multiply by 100 and show as percentage 222 * <tr valign=top> 223 * <td><code>\u2030</code> 224 * <td>Prefix or suffix 225 * <td>Yes 226 * <td>Multiply by 1000 and show as per mille value 227 * <tr valign=top bgcolor="#eeeeff"> 228 * <td><code>¤</code> (<code>\u00A4</code>) 229 * <td>Prefix or suffix 230 * <td>No 231 * <td>Currency sign, replaced by currency symbol. If 232 * doubled, replaced by international currency symbol. 233 * If present in a pattern, the monetary decimal separator 234 * is used instead of the decimal separator. 235 * <tr valign=top> 236 * <td><code>'</code> 237 * <td>Prefix or suffix 238 * <td>No 239 * <td>Used to quote special characters in a prefix or suffix, 240 * for example, <code>"'#'#"</code> formats 123 to 241 * <code>"#123"</code>. To create a single quote 242 * itself, use two in a row: <code>"# o''clock"</code>. 243 * </table> 244 * </blockquote> 245 * 246 * <h4>Scientific Notation</h4> 247 * 248 * <p>Numbers in scientific notation are expressed as the product of a mantissa 249 * and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3. The 250 * mantissa is often in the range 1.0 <= x < 10.0, but it need not be. 251 * <code>DecimalFormat</code> can be instructed to format and parse scientific 252 * notation <em>only via a pattern</em>; there is currently no factory method 253 * that creates a scientific notation format. In a pattern, the exponent 254 * character immediately followed by one or more digit characters indicates 255 * scientific notation. Example: <code>"0.###E0"</code> formats the number 256 * 1234 as <code>"1.234E3"</code>. 257 * 258 * <ul> 259 * <li>The number of digit characters after the exponent character gives the 260 * minimum exponent digit count. There is no maximum. Negative exponents are 261 * formatted using the localized minus sign, <em>not</em> the prefix and suffix 262 * from the pattern. This allows patterns such as <code>"0.###E0 m/s"</code>. 263 * 264 * <li>The minimum and maximum number of integer digits are interpreted 265 * together: 266 * 267 * <ul> 268 * <li>If the maximum number of integer digits is greater than their minimum number 269 * and greater than 1, it forces the exponent to be a multiple of the maximum 270 * number of integer digits, and the minimum number of integer digits to be 271 * interpreted as 1. The most common use of this is to generate 272 * <em>engineering notation</em>, in which the exponent is a multiple of three, 273 * e.g., <code>"##0.#####E0"</code>. Using this pattern, the number 12345 274 * formats to <code>"12.345E3"</code>, and 123456 formats to 275 * <code>"123.456E3"</code>. 276 * 277 * <li>Otherwise, the minimum number of integer digits is achieved by adjusting the 278 * exponent. Example: 0.00123 formatted with <code>"00.###E0"</code> yields 279 * <code>"12.3E-4"</code>. 280 * </ul> 281 * 282 * <li>The number of significant digits in the mantissa is the sum of the 283 * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is 284 * unaffected by the maximum integer digits. For example, 12345 formatted with 285 * <code>"##0.##E0"</code> is <code>"12.3E3"</code>. To show all digits, set 286 * the significant digits count to zero. The number of significant digits 287 * does not affect parsing. 288 * 289 * <li>Exponential patterns may not contain grouping separators. 290 * </ul> 291 * 292 * <h4>Rounding</h4> 293 * 294 * <code>DecimalFormat</code> provides rounding modes defined in 295 * {@link java.math.RoundingMode} for formatting. By default, it uses 296 * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}. 297 * 298 * <h4>Digits</h4> 299 * 300 * For formatting, <code>DecimalFormat</code> uses the ten consecutive 301 * characters starting with the localized zero digit defined in the 302 * <code>DecimalFormatSymbols</code> object as digits. For parsing, these 303 * digits as well as all Unicode decimal digits, as defined by 304 * {@link Character#digit Character.digit}, are recognized. 305 * 306 * <h4>Special Values</h4> 307 * 308 * <p><code>NaN</code> is formatted as a string, which typically has a single character 309 * <code>\uFFFD</code>. This string is determined by the 310 * <code>DecimalFormatSymbols</code> object. This is the only value for which 311 * the prefixes and suffixes are not used. 312 * 313 * <p>Infinity is formatted as a string, which typically has a single character 314 * <code>\u221E</code>, with the positive or negative prefixes and suffixes 315 * applied. The infinity string is determined by the 316 * <code>DecimalFormatSymbols</code> object. 317 * 318 * <p>Negative zero (<code>"-0"</code>) parses to 319 * <ul> 320 * <li><code>BigDecimal(0)</code> if <code>isParseBigDecimal()</code> is 321 * true, 322 * <li><code>Long(0)</code> if <code>isParseBigDecimal()</code> is false 323 * and <code>isParseIntegerOnly()</code> is true, 324 * <li><code>Double(-0.0)</code> if both <code>isParseBigDecimal()</code> 325 * and <code>isParseIntegerOnly()</code> are false. 326 * </ul> 327 * 328 * <h4><a name="synchronization">Synchronization</a></h4> 329 * 330 * <p> 331 * Decimal formats are generally not synchronized. 332 * It is recommended to create separate format instances for each thread. 333 * If multiple threads access a format concurrently, it must be synchronized 334 * externally. 335 * 336 * <h4>Example</h4> 337 * 338 * <blockquote><pre> 339 * <strong>// Print out a number using the localized number, integer, currency, 340 * // and percent format for each locale</strong> 341 * Locale[] locales = NumberFormat.getAvailableLocales(); 342 * double myNumber = -1234.56; 343 * NumberFormat form; 344 * for (int j=0; j<4; ++j) { 345 * System.out.println("FORMAT"); 346 * for (int i = 0; i < locales.length; ++i) { 347 * if (locales[i].getCountry().length() == 0) { 348 * continue; // Skip language-only locales 349 * } 350 * System.out.print(locales[i].getDisplayName()); 351 * switch (j) { 352 * case 0: 353 * form = NumberFormat.getInstance(locales[i]); break; 354 * case 1: 355 * form = NumberFormat.getIntegerInstance(locales[i]); break; 356 * case 2: 357 * form = NumberFormat.getCurrencyInstance(locales[i]); break; 358 * default: 359 * form = NumberFormat.getPercentInstance(locales[i]); break; 360 * } 361 * if (form instanceof DecimalFormat) { 362 * System.out.print(": " + ((DecimalFormat) form).toPattern()); 363 * } 364 * System.out.print(" -> " + form.format(myNumber)); 365 * try { 366 * System.out.println(" -> " + form.parse(form.format(myNumber))); 367 * } catch (ParseException e) {} 368 * } 369 * } 370 * </pre></blockquote> 371 * 372 * @see <a href="http://java.sun.com/docs/books/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a> 373 * @see NumberFormat 374 * @see DecimalFormatSymbols 375 * @see ParsePosition 376 * @author Mark Davis 377 * @author Alan Liu 378 */ 379 public class DecimalFormat extends NumberFormat { 380 381 /** 382 * Creates a DecimalFormat using the default pattern and symbols 383 * for the default locale. This is a convenient way to obtain a 384 * DecimalFormat when internationalization is not the main concern. 385 * <p> 386 * To obtain standard formats for a given locale, use the factory methods 387 * on NumberFormat such as getNumberInstance. These factories will 388 * return the most appropriate sub-class of NumberFormat for a given 389 * locale. 390 * 391 * @see java.text.NumberFormat#getInstance 392 * @see java.text.NumberFormat#getNumberInstance 393 * @see java.text.NumberFormat#getCurrencyInstance 394 * @see java.text.NumberFormat#getPercentInstance 395 */ 396 public DecimalFormat() { 397 Locale def = Locale.getDefault(Locale.Category.FORMAT); 398 // try to get the pattern from the cache 399 String pattern = cachedLocaleData.get(def); 400 if (pattern == null) { /* cache miss */ 401 // Get the pattern for the default locale. 402 ResourceBundle rb = LocaleData.getNumberFormatData(def); 403 String[] all = rb.getStringArray("NumberPatterns"); 404 pattern = all[0]; 405 /* update cache */ 406 cachedLocaleData.putIfAbsent(def, pattern); 407 } 408 409 // Always applyPattern after the symbols are set 410 this.symbols = new DecimalFormatSymbols(def); 411 applyPattern(pattern, false); 412 } 413 414 415 /** 416 * Creates a DecimalFormat using the given pattern and the symbols 417 * for the default locale. This is a convenient way to obtain a 418 * DecimalFormat when internationalization is not the main concern. 419 * <p> 420 * To obtain standard formats for a given locale, use the factory methods 421 * on NumberFormat such as getNumberInstance. These factories will 422 * return the most appropriate sub-class of NumberFormat for a given 423 * locale. 424 * 425 * @param pattern A non-localized pattern string. 426 * @exception NullPointerException if <code>pattern</code> is null 427 * @exception IllegalArgumentException if the given pattern is invalid. 428 * @see java.text.NumberFormat#getInstance 429 * @see java.text.NumberFormat#getNumberInstance 430 * @see java.text.NumberFormat#getCurrencyInstance 431 * @see java.text.NumberFormat#getPercentInstance 432 */ 433 public DecimalFormat(String pattern) { 434 // Always applyPattern after the symbols are set 435 this.symbols = new DecimalFormatSymbols(Locale.getDefault(Locale.Category.FORMAT)); 436 applyPattern(pattern, false); 437 } 438 439 440 /** 441 * Creates a DecimalFormat using the given pattern and symbols. 442 * Use this constructor when you need to completely customize the 443 * behavior of the format. 444 * <p> 445 * To obtain standard formats for a given 446 * locale, use the factory methods on NumberFormat such as 447 * getInstance or getCurrencyInstance. If you need only minor adjustments 448 * to a standard format, you can modify the format returned by 449 * a NumberFormat factory method. 450 * 451 * @param pattern a non-localized pattern string 452 * @param symbols the set of symbols to be used 453 * @exception NullPointerException if any of the given arguments is null 454 * @exception IllegalArgumentException if the given pattern is invalid 455 * @see java.text.NumberFormat#getInstance 456 * @see java.text.NumberFormat#getNumberInstance 457 * @see java.text.NumberFormat#getCurrencyInstance 458 * @see java.text.NumberFormat#getPercentInstance 459 * @see java.text.DecimalFormatSymbols 460 */ 461 public DecimalFormat (String pattern, DecimalFormatSymbols symbols) { 462 // Always applyPattern after the symbols are set 463 this.symbols = (DecimalFormatSymbols)symbols.clone(); 464 applyPattern(pattern, false); 465 } 466 467 468 // Overrides 469 /** 470 * Formats a number and appends the resulting text to the given string 471 * buffer. 472 * The number can be of any subclass of {@link java.lang.Number}. 473 * <p> 474 * This implementation uses the maximum precision permitted. 475 * @param number the number to format 476 * @param toAppendTo the <code>StringBuffer</code> to which the formatted 477 * text is to be appended 478 * @param pos On input: an alignment field, if desired. 479 * On output: the offsets of the alignment field. 480 * @return the value passed in as <code>toAppendTo</code> 481 * @exception IllegalArgumentException if <code>number</code> is 482 * null or not an instance of <code>Number</code>. 483 * @exception NullPointerException if <code>toAppendTo</code> or 484 * <code>pos</code> is null 485 * @exception ArithmeticException if rounding is needed with rounding 486 * mode being set to RoundingMode.UNNECESSARY 487 * @see java.text.FieldPosition 488 */ 489 public final StringBuffer format(Object number, 490 StringBuffer toAppendTo, 491 FieldPosition pos) { 492 if (number instanceof Long || number instanceof Integer || 493 number instanceof Short || number instanceof Byte || 494 number instanceof AtomicInteger || 495 number instanceof AtomicLong || 496 (number instanceof BigInteger && 497 ((BigInteger)number).bitLength () < 64)) { 498 return format(((Number)number).longValue(), toAppendTo, pos); 499 } else if (number instanceof BigDecimal) { 500 return format((BigDecimal)number, toAppendTo, pos); 501 } else if (number instanceof BigInteger) { 502 return format((BigInteger)number, toAppendTo, pos); 503 } else if (number instanceof Number) { 504 return format(((Number)number).doubleValue(), toAppendTo, pos); 505 } else { 506 throw new IllegalArgumentException("Cannot format given Object as a Number"); 507 } 508 } 509 510 /** 511 * Formats a double to produce a string. 512 * @param number The double to format 513 * @param result where the text is to be appended 514 * @param fieldPosition On input: an alignment field, if desired. 515 * On output: the offsets of the alignment field. 516 * @exception ArithmeticException if rounding is needed with rounding 517 * mode being set to RoundingMode.UNNECESSARY 518 * @return The formatted number string 519 * @see java.text.FieldPosition 520 */ 521 public StringBuffer format(double number, StringBuffer result, 522 FieldPosition fieldPosition) { 523 // If fieldPosition is a DontCareFieldPosition instance we can try to go to fast-path code. 524 boolean tryFastPath = false; 525 if (fieldPosition == DontCareFieldPosition.INSTANCE) tryFastPath = true; 526 else { 527 fieldPosition.setBeginIndex(0); 528 fieldPosition.setEndIndex(0); 529 } 530 531 if (tryFastPath) { 532 String tempResult = fastFormat(number); 533 if (tempResult != null) { 534 result.append(tempResult); 535 return result; 536 } 537 } 538 539 // if fast path could not work, we fallback to standard code. 540 return format(number, result, fieldPosition.getFieldDelegate()); 541 } 542 543 /** 544 * Formats a double to produce a string. 545 * @param number The double to format 546 * @param result where the text is to be appended 547 * @param delegate notified of locations of sub fields 548 * @exception ArithmeticException if rounding is needed with rounding 549 * mode being set to RoundingMode.UNNECESSARY 550 * @return The formatted number string 551 */ 552 private StringBuffer format(double number, StringBuffer result, 553 FieldDelegate delegate) { 554 if (Double.isNaN(number) || 555 (Double.isInfinite(number) && multiplier == 0)) { 556 int iFieldStart = result.length(); 557 result.append(symbols.getNaN()); 558 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER, 559 iFieldStart, result.length(), result); 560 return result; 561 } 562 563 /* Detecting whether a double is negative is easy with the exception of 564 * the value -0.0. This is a double which has a zero mantissa (and 565 * exponent), but a negative sign bit. It is semantically distinct from 566 * a zero with a positive sign bit, and this distinction is important 567 * to certain kinds of computations. However, it's a little tricky to 568 * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0). How then, you may 569 * ask, does it behave distinctly from +0.0? Well, 1/(-0.0) == 570 * -Infinity. Proper detection of -0.0 is needed to deal with the 571 * issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98. 572 */ 573 boolean isNegative = ((number < 0.0) || (number == 0.0 && 1/number < 0.0)) ^ (multiplier < 0); 574 575 if (multiplier != 1) { 576 number *= multiplier; 577 } 578 579 if (Double.isInfinite(number)) { 580 if (isNegative) { 581 append(result, negativePrefix, delegate, 582 getNegativePrefixFieldPositions(), Field.SIGN); 583 } else { 584 append(result, positivePrefix, delegate, 585 getPositivePrefixFieldPositions(), Field.SIGN); 586 } 587 588 int iFieldStart = result.length(); 589 result.append(symbols.getInfinity()); 590 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER, 591 iFieldStart, result.length(), result); 592 593 if (isNegative) { 594 append(result, negativeSuffix, delegate, 595 getNegativeSuffixFieldPositions(), Field.SIGN); 596 } else { 597 append(result, positiveSuffix, delegate, 598 getPositiveSuffixFieldPositions(), Field.SIGN); 599 } 600 601 return result; 602 } 603 604 if (isNegative) { 605 number = -number; 606 } 607 608 // at this point we are guaranteed a nonnegative finite number. 609 assert(number >= 0 && !Double.isInfinite(number)); 610 611 synchronized(digitList) { 612 int maxIntDigits = super.getMaximumIntegerDigits(); 613 int minIntDigits = super.getMinimumIntegerDigits(); 614 int maxFraDigits = super.getMaximumFractionDigits(); 615 int minFraDigits = super.getMinimumFractionDigits(); 616 617 digitList.set(isNegative, number, useExponentialNotation ? 618 maxIntDigits + maxFraDigits : maxFraDigits, 619 !useExponentialNotation); 620 return subformat(result, delegate, isNegative, false, 621 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits); 622 } 623 } 624 625 /** 626 * Format a long to produce a string. 627 * @param number The long to format 628 * @param result where the text is to be appended 629 * @param fieldPosition On input: an alignment field, if desired. 630 * On output: the offsets of the alignment field. 631 * @exception ArithmeticException if rounding is needed with rounding 632 * mode being set to RoundingMode.UNNECESSARY 633 * @return The formatted number string 634 * @see java.text.FieldPosition 635 */ 636 public StringBuffer format(long number, StringBuffer result, 637 FieldPosition fieldPosition) { 638 fieldPosition.setBeginIndex(0); 639 fieldPosition.setEndIndex(0); 640 641 return format(number, result, fieldPosition.getFieldDelegate()); 642 } 643 644 /** 645 * Format a long to produce a string. 646 * @param number The long to format 647 * @param result where the text is to be appended 648 * @param delegate notified of locations of sub fields 649 * @return The formatted number string 650 * @exception ArithmeticException if rounding is needed with rounding 651 * mode being set to RoundingMode.UNNECESSARY 652 * @see java.text.FieldPosition 653 */ 654 private StringBuffer format(long number, StringBuffer result, 655 FieldDelegate delegate) { 656 boolean isNegative = (number < 0); 657 if (isNegative) { 658 number = -number; 659 } 660 661 // In general, long values always represent real finite numbers, so 662 // we don't have to check for +/- Infinity or NaN. However, there 663 // is one case we have to be careful of: The multiplier can push 664 // a number near MIN_VALUE or MAX_VALUE outside the legal range. We 665 // check for this before multiplying, and if it happens we use 666 // BigInteger instead. 667 boolean useBigInteger = false; 668 if (number < 0) { // This can only happen if number == Long.MIN_VALUE. 669 if (multiplier != 0) { 670 useBigInteger = true; 671 } 672 } else if (multiplier != 1 && multiplier != 0) { 673 long cutoff = Long.MAX_VALUE / multiplier; 674 if (cutoff < 0) { 675 cutoff = -cutoff; 676 } 677 useBigInteger = (number > cutoff); 678 } 679 680 if (useBigInteger) { 681 if (isNegative) { 682 number = -number; 683 } 684 BigInteger bigIntegerValue = BigInteger.valueOf(number); 685 return format(bigIntegerValue, result, delegate, true); 686 } 687 688 number *= multiplier; 689 if (number == 0) { 690 isNegative = false; 691 } else { 692 if (multiplier < 0) { 693 number = -number; 694 isNegative = !isNegative; 695 } 696 } 697 698 synchronized(digitList) { 699 int maxIntDigits = super.getMaximumIntegerDigits(); 700 int minIntDigits = super.getMinimumIntegerDigits(); 701 int maxFraDigits = super.getMaximumFractionDigits(); 702 int minFraDigits = super.getMinimumFractionDigits(); 703 704 digitList.set(isNegative, number, 705 useExponentialNotation ? maxIntDigits + maxFraDigits : 0); 706 707 return subformat(result, delegate, isNegative, true, 708 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits); 709 } 710 } 711 712 /** 713 * Formats a BigDecimal to produce a string. 714 * @param number The BigDecimal to format 715 * @param result where the text is to be appended 716 * @param fieldPosition On input: an alignment field, if desired. 717 * On output: the offsets of the alignment field. 718 * @return The formatted number string 719 * @exception ArithmeticException if rounding is needed with rounding 720 * mode being set to RoundingMode.UNNECESSARY 721 * @see java.text.FieldPosition 722 */ 723 private StringBuffer format(BigDecimal number, StringBuffer result, 724 FieldPosition fieldPosition) { 725 fieldPosition.setBeginIndex(0); 726 fieldPosition.setEndIndex(0); 727 return format(number, result, fieldPosition.getFieldDelegate()); 728 } 729 730 /** 731 * Formats a BigDecimal to produce a string. 732 * @param number The BigDecimal to format 733 * @param result where the text is to be appended 734 * @param delegate notified of locations of sub fields 735 * @exception ArithmeticException if rounding is needed with rounding 736 * mode being set to RoundingMode.UNNECESSARY 737 * @return The formatted number string 738 */ 739 private StringBuffer format(BigDecimal number, StringBuffer result, 740 FieldDelegate delegate) { 741 if (multiplier != 1) { 742 number = number.multiply(getBigDecimalMultiplier()); 743 } 744 boolean isNegative = number.signum() == -1; 745 if (isNegative) { 746 number = number.negate(); 747 } 748 749 synchronized(digitList) { 750 int maxIntDigits = getMaximumIntegerDigits(); 751 int minIntDigits = getMinimumIntegerDigits(); 752 int maxFraDigits = getMaximumFractionDigits(); 753 int minFraDigits = getMinimumFractionDigits(); 754 int maximumDigits = maxIntDigits + maxFraDigits; 755 756 digitList.set(isNegative, number, useExponentialNotation ? 757 ((maximumDigits < 0) ? Integer.MAX_VALUE : maximumDigits) : 758 maxFraDigits, !useExponentialNotation); 759 760 return subformat(result, delegate, isNegative, false, 761 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits); 762 } 763 } 764 765 /** 766 * Format a BigInteger to produce a string. 767 * @param number The BigInteger to format 768 * @param result where the text is to be appended 769 * @param fieldPosition On input: an alignment field, if desired. 770 * On output: the offsets of the alignment field. 771 * @return The formatted number string 772 * @exception ArithmeticException if rounding is needed with rounding 773 * mode being set to RoundingMode.UNNECESSARY 774 * @see java.text.FieldPosition 775 */ 776 private StringBuffer format(BigInteger number, StringBuffer result, 777 FieldPosition fieldPosition) { 778 fieldPosition.setBeginIndex(0); 779 fieldPosition.setEndIndex(0); 780 781 return format(number, result, fieldPosition.getFieldDelegate(), false); 782 } 783 784 /** 785 * Format a BigInteger to produce a string. 786 * @param number The BigInteger to format 787 * @param result where the text is to be appended 788 * @param delegate notified of locations of sub fields 789 * @return The formatted number string 790 * @exception ArithmeticException if rounding is needed with rounding 791 * mode being set to RoundingMode.UNNECESSARY 792 * @see java.text.FieldPosition 793 */ 794 private StringBuffer format(BigInteger number, StringBuffer result, 795 FieldDelegate delegate, boolean formatLong) { 796 if (multiplier != 1) { 797 number = number.multiply(getBigIntegerMultiplier()); 798 } 799 boolean isNegative = number.signum() == -1; 800 if (isNegative) { 801 number = number.negate(); 802 } 803 804 synchronized(digitList) { 805 int maxIntDigits, minIntDigits, maxFraDigits, minFraDigits, maximumDigits; 806 if (formatLong) { 807 maxIntDigits = super.getMaximumIntegerDigits(); 808 minIntDigits = super.getMinimumIntegerDigits(); 809 maxFraDigits = super.getMaximumFractionDigits(); 810 minFraDigits = super.getMinimumFractionDigits(); 811 maximumDigits = maxIntDigits + maxFraDigits; 812 } else { 813 maxIntDigits = getMaximumIntegerDigits(); 814 minIntDigits = getMinimumIntegerDigits(); 815 maxFraDigits = getMaximumFractionDigits(); 816 minFraDigits = getMinimumFractionDigits(); 817 maximumDigits = maxIntDigits + maxFraDigits; 818 if (maximumDigits < 0) { 819 maximumDigits = Integer.MAX_VALUE; 820 } 821 } 822 823 digitList.set(isNegative, number, 824 useExponentialNotation ? maximumDigits : 0); 825 826 return subformat(result, delegate, isNegative, true, 827 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits); 828 } 829 } 830 831 /** 832 * Formats an Object producing an <code>AttributedCharacterIterator</code>. 833 * You can use the returned <code>AttributedCharacterIterator</code> 834 * to build the resulting String, as well as to determine information 835 * about the resulting String. 836 * <p> 837 * Each attribute key of the AttributedCharacterIterator will be of type 838 * <code>NumberFormat.Field</code>, with the attribute value being the 839 * same as the attribute key. 840 * 841 * @exception NullPointerException if obj is null. 842 * @exception IllegalArgumentException when the Format cannot format the 843 * given object. 844 * @exception ArithmeticException if rounding is needed with rounding 845 * mode being set to RoundingMode.UNNECESSARY 846 * @param obj The object to format 847 * @return AttributedCharacterIterator describing the formatted value. 848 * @since 1.4 849 */ 850 public AttributedCharacterIterator formatToCharacterIterator(Object obj) { 851 CharacterIteratorFieldDelegate delegate = 852 new CharacterIteratorFieldDelegate(); 853 StringBuffer sb = new StringBuffer(); 854 855 if (obj instanceof Double || obj instanceof Float) { 856 format(((Number)obj).doubleValue(), sb, delegate); 857 } else if (obj instanceof Long || obj instanceof Integer || 858 obj instanceof Short || obj instanceof Byte || 859 obj instanceof AtomicInteger || obj instanceof AtomicLong) { 860 format(((Number)obj).longValue(), sb, delegate); 861 } else if (obj instanceof BigDecimal) { 862 format((BigDecimal)obj, sb, delegate); 863 } else if (obj instanceof BigInteger) { 864 format((BigInteger)obj, sb, delegate, false); 865 } else if (obj == null) { 866 throw new NullPointerException( 867 "formatToCharacterIterator must be passed non-null object"); 868 } else { 869 throw new IllegalArgumentException( 870 "Cannot format given Object as a Number"); 871 } 872 return delegate.getIterator(sb.toString()); 873 } 874 875 // Fast path formating algorithm for double ================================ 876 877 // Fast-path formatting will be used for format(double) if a number of 878 // conditions are met (see checkAndeStFastPathStatus()): 879 // - Only if instance properties meet the right predefined conditions 880 // - The abs value of the double to format is <= Integer.MAX_VALUE 881 882 // ------ The fast path for double methods ------- 883 884 // Decides if rounding up must occur for the passed double. 885 private boolean toBeHalfEvenRounded(double number, 886 int integralPartAsInt, int nbIntegerDigits, 887 int fractionalPartAsInt, int nbFractionalDigits) { 888 // Index of undecidable rounding interval depending on magnitude of number. 889 int boundIndex = 0; 890 if (integralPartAsInt != 0) 891 boundIndex = maximumFractionDigits + nbIntegerDigits; 892 else if (fractionalPartAsInt != 0) boundIndex = nbFractionalDigits; 893 894 // Check poisition of number relative to "Undecidable Rounding Interval". 895 if (remainingFractionalPart <= safeMinusRoundingBounds[boundIndex]) 896 return false; // number is outside below. 897 else if (remainingFractionalPart >= safeMajorRoundingBounds[boundIndex]) 898 return true; // number is outside above. 899 else { 900 // number is inside. We compare against nearest perfect-half. 901 double perfectHalf; 902 if (isCurrencyFormat) 903 perfectHalf = (((double) integralPartAsInt * 1000.0d) + 904 (double) (fractionalPartAsInt * 10 + 5)) / 1000.0d; 905 else 906 perfectHalf = (((double) integralPartAsInt * 10000.0d) + 907 (double) (fractionalPartAsInt * 10 + 5)) / 10000.0d; 908 909 // Applies healf-even rounding rule. 910 if (number == perfectHalf) 911 return (((fractionalPartAsInt % 10) & 1) != 0); 912 else return (number > perfectHalf); 913 } 914 } 915 916 // Returns the exact number of digits (radix 10) representing 917 // the passed paramater i. Sets utility formating fields used in the algorithm 918 private int intStringSize(int i) { 919 if (i <= 99999) { 920 if (i <= 999) { 921 if (i <= 99) { 922 if (i <= 9) { 923 if (i == 9) isAllNines = true; 924 else isAllNines = false; 925 nbGroupsNeeded = 0; 926 return 1; 927 } 928 else { 929 if (i == 99) isAllNines = true; 930 else isAllNines = false; 931 nbGroupsNeeded = 0; 932 return 2; 933 } 934 } 935 else { 936 if (i == 999) isAllNines = true; 937 else isAllNines = false; 938 nbGroupsNeeded = 0; 939 return 3; 940 } 941 } 942 else if (i <= 9999) { 943 if (i == 9999) isAllNines = true; 944 else isAllNines = false; 945 nbGroupsNeeded = 1; 946 return 4; 947 } 948 else { 949 if (i == 99999) isAllNines = true; 950 else isAllNines = false; 951 nbGroupsNeeded = 1; 952 return 5; 953 } 954 } 955 else { 956 if (i <= 99999999) { 957 if (i <= 999999) { 958 if (i == 999999) isAllNines = true; 959 else isAllNines = false; 960 nbGroupsNeeded = 1; 961 return 6; 962 } 963 else if (i <= 9999999) { 964 if (i == 9999999) isAllNines = true; 965 else isAllNines = false; 966 nbGroupsNeeded = 2; 967 return 7; 968 } 969 else { 970 if (i == 99999999) isAllNines = true; 971 else isAllNines = false; 972 nbGroupsNeeded = 2; 973 return 8; 974 } 975 } 976 else if (i <= 999999999) { 977 if (i == 999999999) isAllNines = true; 978 else isAllNines = false; 979 nbGroupsNeeded = 2; 980 return 9; 981 } 982 else { 983 isAllNines = false; 984 nbGroupsNeeded = 3; 985 return 10; 986 } 987 } 988 } 989 990 // Returns the exact number of digits (radix 10) representing the passed i, 991 // Sets utility formating fields used in the algorithm 992 private int fracStringSize(int i) { 993 if (i > 99) { 994 if (i == 999) isAllNines = true; 995 return 3; 996 } 997 else if (i < 10) { 998 if (i == 9) isAllNines = true; 999 return 1; 1000 } 1001 else { 1002 if (i == 99) isAllNines = true; 1003 return 2; 1004 } 1005 } 1006 1007 1008 // Extracts and returns the 2 (Currency pattern) or 3 (Decimal pattern) 1009 // digits int representing the fractional part of passed double. 1010 private int getFracIntegral(double fractional, int nbFractionalDigits) { 1011 int fractAsInt; 1012 double nextFractional; 1013 if (nbFractionalDigits == 2) { 1014 // Default currency pattern case. 2 fractional digits. Scale 100.0d. 1015 nextFractional = fractional * 100.0d; 1016 fractAsInt = (int) nextFractional; 1017 } 1018 else { 1019 // Default decimal pattern case. 3 fractional digits. Scale 1000.0d 1020 nextFractional = fractional * 1000.0d; 1021 fractAsInt = (int) nextFractional; 1022 } 1023 1024 // The remaining fractional part that will be used in rounding decision ... 1025 remainingFractionalPart = nextFractional - (double) fractAsInt; 1026 1027 return fractAsInt; 1028 } 1029 1030 1031 // Check validity of using fast path for this instance. 1032 // If fast-path is valid for this instance, sets fast-path state as true 1033 // and initialize fast-path utility fields as needed. 1034 // 1035 // FAST-PATH RULES: 1036 // Similar to the default DecimalFormat instantiation case. More precisely: 1037 // - HALF_EVEN rounding mode, 1038 // - isGroupingUsed() is true, 1039 // - groupingSize of 3, 1040 // - multiplier is 1, 1041 // - Decimal separator not mandatory, 1042 // - No use of exponential notation, 1043 // - minimumIntegerDigits is exactly 1 and maximumIntegerDigits at least 10 1044 // - for number of fractional digits, the exact values found in the default case: 1045 // Currency : min = max = 2. 1046 // Decimal : min = 0. max = 3. 1047 private void checkAndSetFastPathStatus() { 1048 boolean fastPathWasOn = isFastPath; 1049 if ((roundingMode == RoundingMode.HALF_EVEN) && 1050 (isGroupingUsed()) && 1051 (groupingSize == 3) && 1052 (multiplier == 1) && 1053 (!decimalSeparatorAlwaysShown) && 1054 (!useExponentialNotation)) { 1055 1056 // The fast-path algorithm is semi-hardcoded against 1057 // minimumIntegerDigits and maximumIntegerDigits. 1058 if ((minimumIntegerDigits == 1) && 1059 (maximumIntegerDigits >= 10)) isFastPath = true; 1060 else isFastPath = false; 1061 1062 // The fast-path algorithm is hardcoded against 1063 // minimumFractionDigits and maximumFractionDigits. 1064 if (isFastPath) { 1065 if (isCurrencyFormat) { 1066 if ((minimumFractionDigits != 2) || 1067 (maximumFractionDigits != 2)) isFastPath = false; 1068 } 1069 else if ((minimumFractionDigits != 0) || 1070 (maximumFractionDigits != 3)) isFastPath = false; 1071 } 1072 } 1073 else isFastPath = false; 1074 1075 if (isFastPath) { 1076 // Sets up the locale specific values used when formatting. 1077 zeroDelta = symbols.getZeroDigit() - '0'; // '0' is our default representation of zero. 1078 groupingChar = symbols.getGroupingSeparator(); 1079 decimalSeparatorChar = isCurrencyFormat ? 1080 symbols.getMonetaryDecimalSeparator() : 1081 symbols.getDecimalSeparator(); 1082 1083 // Instantiate and initialize char container arrays used in formatting. 1084 int maxNbIntegralDigits = 10; 1085 int maxNbGroups = 3; 1086 1087 // Max size for positive numbers. 1088 int maxContainerSize = 1089 positivePrefix.length() + 1090 maxNbIntegralDigits + 1091 maxNbGroups + 1092 1 + maximumFractionDigits + 1093 positiveSuffix.length(); 1094 1095 char[] template = new char[maxContainerSize]; 1096 positivePrefix.getChars(0, positivePrefix.length(), template, 0); 1097 positiveFastPathContainer = template; 1098 1099 // Max size for negative numbers. 1100 maxContainerSize = 1101 negativePrefix.length() + 1102 maxNbIntegralDigits + 1103 maxNbGroups + 1104 1 + maximumFractionDigits + 1105 negativeSuffix.length(); 1106 1107 template = new char[maxContainerSize]; 1108 negativePrefix.getChars(0, negativePrefix.length(), template, 0); 1109 negativeFastPathContainer = template; 1110 1111 // Initialize suffix char arrays. 1112 charsPositiveSuffix = positiveSuffix.toCharArray(); 1113 charsNegativeSuffix = negativeSuffix.toCharArray(); 1114 isSuffixPresent = 1115 (charsPositiveSuffix.length != 0) || (charsNegativeSuffix.length != 0); 1116 1117 // Initialize rounding interval constants. 1118 if (isCurrencyFormat) { 1119 safeMinusRoundingBounds = CurrencySafeMinusRoundingBounds; 1120 safeMajorRoundingBounds = CurrencySafeMajorRoundingBounds; 1121 } 1122 else { 1123 safeMinusRoundingBounds = StdSafeMinusRoundingBounds; 1124 safeMajorRoundingBounds = StdSafeMajorRoundingBounds; 1125 } 1126 } 1127 else if (fastPathWasOn) { 1128 // Previous state was fast-path and is no more. Resets cached constants. 1129 positiveFastPathContainer = null; 1130 negativeFastPathContainer = null; 1131 charsPositiveSuffix = null; 1132 charsNegativeSuffix = null; 1133 safeMajorRoundingBounds = null; 1134 safeMinusRoundingBounds = null; 1135 } 1136 1137 fastPathCheckNeeded = false; 1138 } 1139 1140 // Fills efficiently the passed digitsBuffer with digit for up to 4 chars 1141 // for length, starting at startIndex. len must be positive and at most 4. 1142 private void fillUpTo4Chars(char[] digitsBuffer, int startIndex, 1143 int len, char digit) { 1144 int lowerIndex = startIndex; 1145 if (len == 1) digitsBuffer[lowerIndex] = digit; 1146 else { 1147 int upperIndex = lowerIndex + len - 1; // included ! 1148 digitsBuffer[upperIndex] = digit; 1149 digitsBuffer[lowerIndex] = digit; 1150 1151 if (len > 2) { 1152 // Fill the remaining 1 or 2 digits. 1153 digitsBuffer[++lowerIndex] = digit; // at least one additional digit to fill 1154 if (--upperIndex > lowerIndex) digitsBuffer[upperIndex] = digit; 1155 } 1156 } 1157 } 1158 1159 // Appends positive or negative suffix, depending on sign. Updates lastUsedIndex. 1160 private void appendSuffix(boolean isNegative, char[] internalChars) { 1161 // Init to factorise on suffix code 1162 char[] suffix; 1163 if (isNegative) 1164 suffix = charsNegativeSuffix; 1165 else suffix = charsPositiveSuffix; 1166 int len = suffix.length; 1167 1168 // Trivial and most frequent case. 1169 if (len == 0) return; 1170 1171 // We need to append something. 1172 int startIndex = lastUsedIndex + 1; 1173 if (len == 1) internalChars[startIndex] = suffix[0]; 1174 else if (len <= 4) { 1175 int dstLower = startIndex; 1176 int dstUpper = dstLower + len - 1; 1177 int srcUpper = len - 1; 1178 internalChars[dstLower++] = suffix[0]; 1179 internalChars[dstUpper--] = suffix[srcUpper]; 1180 1181 if (len > 2) internalChars[dstLower] = suffix[1]; 1182 if (len == 4) internalChars[dstUpper] = suffix[2]; 1183 } 1184 else System.arraycopy(suffix, 0, internalChars, startIndex, len); 1185 1186 lastUsedIndex += len; 1187 } 1188 1189 // Converts digit chars to current locale. 1190 // Loops downward starting from LastUsedIndex. 1191 private void localizeDigits(char[] digitsBuffer, int startIndex) { 1192 // We localize digits only, taking into account currency/decimal fractional case 1193 int nonDigitCounter = maximumFractionDigits; 1194 for (int cursor = lastUsedIndex; cursor >= startIndex; cursor--) { 1195 if (nonDigitCounter != 0) { 1196 // Cursor char is a digit char and we must localize it. 1197 digitsBuffer[cursor] += zeroDelta; 1198 nonDigitCounter--; 1199 } 1200 else { 1201 // Cursor char is decimal separator or grouping char. Just reinit counter. 1202 nonDigitCounter = groupingSize; 1203 } 1204 } 1205 } 1206 1207 // Faster fast-path for the "all nines" cases. Mainly like a "fill" operation. 1208 private void formatAllNinesCase(char[] digitsBuffer, int startIndex, 1209 boolean toBeRounded, int nbGroups, 1210 int integralLength, int fractionalLength) { 1211 char fillDigit; 1212 if (!toBeRounded) fillDigit = '9'; 1213 else { 1214 // checks for needed additional 3 digits group. 1215 nbGroups += ((integralLength % 3) == 0) ? 1 : 0; 1216 1217 digitsBuffer[startIndex++] = '1'; 1218 fillDigit = '0'; 1219 } 1220 1221 // We will fill buffer with relevant digit. 1222 int totalLength = integralLength + fractionalLength + nbGroups + 1; 1223 Arrays.fill(digitsBuffer, startIndex, (startIndex + totalLength), fillDigit); 1224 1225 // Sets decimal point char and group markers. 1226 lastUsedIndex = startIndex + nbGroups + integralLength; 1227 int cursorIndex = lastUsedIndex; 1228 digitsBuffer[cursorIndex--] = decimalSeparatorChar; 1229 while (cursorIndex > startIndex) { 1230 if (nbGroups > 0) { 1231 cursorIndex -= 3; 1232 digitsBuffer[cursorIndex--] = groupingChar; 1233 nbGroups--; 1234 } 1235 else break; 1236 } 1237 1238 // Removes fractional digits if needed. 1239 if (!toBeRounded || isCurrencyFormat) lastUsedIndex += fractionalLength; 1240 else lastUsedIndex--; // fractional part absent 1241 } 1242 1243 // Collects integral digits from passed number, setting group chars if needed. 1244 // No rounding done here. 1245 // Loops downward starting at backwardIndex position (inclusive). 1246 private void collectIntegralDigits(int number, 1247 char[] digitsBuffer, int backwardIndex) { 1248 int index = backwardIndex; 1249 int q; 1250 int r; 1251 while (number > 999) { 1252 // Generate 3 digits per iteration. 1253 q = number / 1000; 1254 r = number - (q << 10) + (q << 4) + (q << 3); // -1024 +16 +8 = 1000. 1255 number = q; 1256 1257 digitsBuffer[index--] = DigitOnes1000[r]; 1258 digitsBuffer[index--] = DigitTens1000[r]; 1259 digitsBuffer[index--] = DigitHundreds1000[r]; 1260 digitsBuffer[index--] = groupingChar; 1261 } 1262 1263 // Collects last 3 or less digits. 1264 digitsBuffer[index--] = DigitOnes1000[number]; 1265 if (number > 9) { 1266 if (number > 99) { 1267 digitsBuffer[index--] = DigitTens1000[number]; 1268 digitsBuffer[index] = DigitHundreds1000[number]; 1269 } 1270 else digitsBuffer[index] = DigitTens1000[number]; 1271 } 1272 } 1273 1274 // Collects the 2 (currency) or 3 fractional digits. No rounding. 1275 // Starting at startIndex position inclusive. Updates LastUsedIndex. 1276 private void collectFractionalDigits(int number, boolean currency, 1277 char[] digitsBuffer, int startIndex) { 1278 lastUsedIndex = currency ? (startIndex + 1) : (startIndex + 2); 1279 int index = lastUsedIndex; 1280 1281 char digitOnes, digitTens; 1282 digitOnes = DigitOnes1000[number]; 1283 digitTens = DigitTens1000[number]; 1284 1285 if (currency) { 1286 // Currency case. Always collects fractional digits. 1287 digitsBuffer[index] = digitOnes; 1288 digitsBuffer[index - 1] = digitTens; 1289 } 1290 else { 1291 // Decimal case. Don't collect ending zeros. 1292 if (number == 0) index -= 4; 1293 else { 1294 index = index - 2; 1295 digitsBuffer[index] = DigitHundreds1000[number]; 1296 // Takes care of ending zeros that we don't collect. 1297 if (digitOnes == '0') { 1298 if (digitTens != '0') { 1299 index = index + 1; 1300 digitsBuffer[index] = digitTens; 1301 } 1302 } 1303 else { 1304 digitsBuffer[++index] = digitTens; 1305 digitsBuffer[++index] = digitOnes; 1306 } 1307 } 1308 lastUsedIndex = index; 1309 } 1310 } 1311 1312 // Fast path format main entry point method. 1313 // Formatted result is put in passed internalChars char buffer. 1314 // Passed double d must be positive. 1315 private int fastDoubleFormat(double d, boolean negative, 1316 char[] internalChars, int startIndex) { 1317 // Extracting integral and fractional part. 1318 int integralPartAsInt = (int) d; 1319 double fractional = d - (double) integralPartAsInt; 1320 1321 // Collects integral part infos. 1322 int integralLength = intStringSize(integralPartAsInt); 1323 boolean integralPartIsAllNines = isAllNines; 1324 int nbGroups = nbGroupsNeeded; 1325 1326 // Collects fractional part infos. 1327 isAllNines = false; 1328 int fractionalPartAsInt = getFracIntegral(fractional, maximumFractionDigits); 1329 int fractionalLength = fracStringSize(fractionalPartAsInt); 1330 boolean fractionalPartIsAllNines = isAllNines; 1331 1332 // Should we round up ? 1333 boolean toBeRounded = 1334 toBeHalfEvenRounded(d, integralPartAsInt, integralLength, 1335 fractionalPartAsInt, fractionalLength); 1336 1337 if (!integralPartIsAllNines || 1338 !(fractionalPartIsAllNines && (fractionalLength == maximumFractionDigits))) { 1339 int decimalPointIndex = startIndex + integralLength + nbGroups; 1340 int integralLastIndex = decimalPointIndex - 1; 1341 int fractionalStartIndex = decimalPointIndex + 1; 1342 1343 if (!fractionalPartIsAllNines || 1344 (fractionalLength != maximumFractionDigits)) { 1345 // Fractional part to be collected completely in all cases. 1346 internalChars[decimalPointIndex] = decimalSeparatorChar; 1347 if (toBeRounded) fractionalPartAsInt = fractionalPartAsInt + 1; 1348 collectFractionalDigits(fractionalPartAsInt, isCurrencyFormat, 1349 internalChars, fractionalStartIndex); 1350 collectIntegralDigits(integralPartAsInt, 1351 internalChars, integralLastIndex); 1352 } 1353 else { 1354 // Fractional is "all_nines". 1355 // Either we have currency and frac=99, or decimal and frac=999. 1356 // Fractional will end up either in 99[9] or 00[0] depending on rounding. 1357 if (toBeRounded) { 1358 // Rounding is propagated to integral. 1359 integralPartAsInt = integralPartAsInt + 1; 1360 1361 // Collects fractional part. 1362 if (isCurrencyFormat) { 1363 // Fills fractional part with ".00" (pattern rule). 1364 lastUsedIndex = decimalPointIndex + maximumFractionDigits; 1365 internalChars[decimalPointIndex] = decimalSeparatorChar; 1366 internalChars[fractionalStartIndex] = '0'; 1367 internalChars[lastUsedIndex] = '0'; 1368 } 1369 else { 1370 // Not currency, just forget fractional part (pattern rule). 1371 lastUsedIndex = integralLastIndex; 1372 } 1373 } 1374 else { 1375 // No rounding up. Fractional remains all_nines (999 or 99) ! 1376 internalChars[decimalPointIndex] = decimalSeparatorChar; 1377 fillUpTo4Chars(internalChars, fractionalStartIndex, maximumFractionDigits, '9'); 1378 lastUsedIndex = decimalPointIndex + maximumFractionDigits; 1379 } 1380 1381 // Then collects integral part. Already rounded up if needed. 1382 collectIntegralDigits(integralPartAsInt, internalChars, integralLastIndex); 1383 1384 } 1385 } 1386 else formatAllNinesCase(internalChars, startIndex, 1387 toBeRounded, nbGroups, 1388 integralLength, fractionalLength); 1389 1390 // Takes into account locale for the digits part only. 1391 if (zeroDelta != 0) localizeDigits(internalChars, startIndex); 1392 1393 // Adds suffix part if needed. 1394 if (isSuffixPresent) appendSuffix(negative, internalChars); 1395 1396 return lastUsedIndex; 1397 } 1398 1399 // A fasthpath shortcut of format(double) to be called by NumberFormat only. 1400 // 1401 // If instance can be applied fast-path and passed double is not NaN or Infinite, 1402 // and is in the integer range, we call directly fastDoubleFormat using the 1403 // expected container and prefix position. 1404 // 1405 // Otherwise returns null since fast-path not possible (convention). 1406 // 1407 // We check positive and negative zero, minimizing the needed tests 1408 // for the most frequent case. 1409 String fastFormat(double number) { 1410 // Should we check fast path status ? 1411 if (fastPathCheckNeeded) checkAndSetFastPathStatus(); 1412 1413 if (isFastPath ) { 1414 if (!Double.isNaN(number) && 1415 !Double.isInfinite(number)) { 1416 1417 int lastIndex; 1418 char[] container; 1419 1420 if (number > 0.0) { // 1 test only for positive doubles 1421 if (number <= MAX_INT_AS_DOUBLE) { 1422 container = positiveFastPathContainer; 1423 lastIndex = fastDoubleFormat(number, false, 1424 container, positivePrefix.length()); 1425 return new String(container, 0, lastIndex + 1); 1426 } 1427 } 1428 else if (number < 0.0) { // 2 tests for negative doubles 1429 number = -number; 1430 if (number <= MAX_INT_AS_DOUBLE) { 1431 container = negativeFastPathContainer; 1432 lastIndex = fastDoubleFormat(number, true, 1433 container, negativePrefix.length()); 1434 return new String(container, 0, lastIndex + 1); 1435 } 1436 } 1437 else if ( 1/number > 0.0) { // 3 tests for positive zero. Not frequent. 1438 container = positiveFastPathContainer; 1439 lastIndex = fastDoubleFormat(number, false, 1440 container, positivePrefix.length()); 1441 return new String(container, 0, lastIndex + 1); 1442 } 1443 else { // 4 tests for negative zero (hopefully very rare) 1444 container = negativeFastPathContainer; 1445 lastIndex = fastDoubleFormat(number, true, 1446 container, negativePrefix.length()); 1447 return new String(container, 0, lastIndex + 1); 1448 } 1449 } 1450 1451 // Fast-path can't be exercized for this passed double ! 1452 return null; 1453 } 1454 1455 // DecimalFormat instance is not in a fast path state. 1456 return null; 1457 } 1458 1459 // End of Fast path formating algorithm for double ==================================================================== 1460 1461 /** 1462 * Complete the formatting of a finite number. On entry, the digitList must 1463 * be filled in with the correct digits. 1464 */ 1465 private StringBuffer subformat(StringBuffer result, FieldDelegate delegate, 1466 boolean isNegative, boolean isInteger, 1467 int maxIntDigits, int minIntDigits, 1468 int maxFraDigits, int minFraDigits) { 1469 // NOTE: This isn't required anymore because DigitList takes care of this. 1470 // 1471 // // The negative of the exponent represents the number of leading 1472 // // zeros between the decimal and the first non-zero digit, for 1473 // // a value < 0.1 (e.g., for 0.00123, -fExponent == 2). If this 1474 // // is more than the maximum fraction digits, then we have an underflow 1475 // // for the printed representation. We recognize this here and set 1476 // // the DigitList representation to zero in this situation. 1477 // 1478 // if (-digitList.decimalAt >= getMaximumFractionDigits()) 1479 // { 1480 // digitList.count = 0; 1481 // } 1482 1483 char zero = symbols.getZeroDigit(); 1484 int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero 1485 char grouping = symbols.getGroupingSeparator(); 1486 char decimal = isCurrencyFormat ? 1487 symbols.getMonetaryDecimalSeparator() : 1488 symbols.getDecimalSeparator(); 1489 1490 /* Per bug 4147706, DecimalFormat must respect the sign of numbers which 1491 * format as zero. This allows sensible computations and preserves 1492 * relations such as signum(1/x) = signum(x), where x is +Infinity or 1493 * -Infinity. Prior to this fix, we always formatted zero values as if 1494 * they were positive. Liu 7/6/98. 1495 */ 1496 if (digitList.isZero()) { 1497 digitList.decimalAt = 0; // Normalize 1498 } 1499 1500 if (isNegative) { 1501 append(result, negativePrefix, delegate, 1502 getNegativePrefixFieldPositions(), Field.SIGN); 1503 } else { 1504 append(result, positivePrefix, delegate, 1505 getPositivePrefixFieldPositions(), Field.SIGN); 1506 } 1507 1508 if (useExponentialNotation) { 1509 int iFieldStart = result.length(); 1510 int iFieldEnd = -1; 1511 int fFieldStart = -1; 1512 1513 // Minimum integer digits are handled in exponential format by 1514 // adjusting the exponent. For example, 0.01234 with 3 minimum 1515 // integer digits is "123.4E-4". 1516 1517 // Maximum integer digits are interpreted as indicating the 1518 // repeating range. This is useful for engineering notation, in 1519 // which the exponent is restricted to a multiple of 3. For 1520 // example, 0.01234 with 3 maximum integer digits is "12.34e-3". 1521 // If maximum integer digits are > 1 and are larger than 1522 // minimum integer digits, then minimum integer digits are 1523 // ignored. 1524 int exponent = digitList.decimalAt; 1525 int repeat = maxIntDigits; 1526 int minimumIntegerDigits = minIntDigits; 1527 if (repeat > 1 && repeat > minIntDigits) { 1528 // A repeating range is defined; adjust to it as follows. 1529 // If repeat == 3, we have 6,5,4=>3; 3,2,1=>0; 0,-1,-2=>-3; 1530 // -3,-4,-5=>-6, etc. This takes into account that the 1531 // exponent we have here is off by one from what we expect; 1532 // it is for the format 0.MMMMMx10^n. 1533 if (exponent >= 1) { 1534 exponent = ((exponent - 1) / repeat) * repeat; 1535 } else { 1536 // integer division rounds towards 0 1537 exponent = ((exponent - repeat) / repeat) * repeat; 1538 } 1539 minimumIntegerDigits = 1; 1540 } else { 1541 // No repeating range is defined; use minimum integer digits. 1542 exponent -= minimumIntegerDigits; 1543 } 1544 1545 // We now output a minimum number of digits, and more if there 1546 // are more digits, up to the maximum number of digits. We 1547 // place the decimal point after the "integer" digits, which 1548 // are the first (decimalAt - exponent) digits. 1549 int minimumDigits = minIntDigits + minFraDigits; 1550 if (minimumDigits < 0) { // overflow? 1551 minimumDigits = Integer.MAX_VALUE; 1552 } 1553 1554 // The number of integer digits is handled specially if the number 1555 // is zero, since then there may be no digits. 1556 int integerDigits = digitList.isZero() ? minimumIntegerDigits : 1557 digitList.decimalAt - exponent; 1558 if (minimumDigits < integerDigits) { 1559 minimumDigits = integerDigits; 1560 } 1561 int totalDigits = digitList.count; 1562 if (minimumDigits > totalDigits) { 1563 totalDigits = minimumDigits; 1564 } 1565 boolean addedDecimalSeparator = false; 1566 1567 for (int i=0; i<totalDigits; ++i) { 1568 if (i == integerDigits) { 1569 // Record field information for caller. 1570 iFieldEnd = result.length(); 1571 1572 result.append(decimal); 1573 addedDecimalSeparator = true; 1574 1575 // Record field information for caller. 1576 fFieldStart = result.length(); 1577 } 1578 result.append((i < digitList.count) ? 1579 (char)(digitList.digits[i] + zeroDelta) : 1580 zero); 1581 } 1582 1583 if (decimalSeparatorAlwaysShown && totalDigits == integerDigits) { 1584 // Record field information for caller. 1585 iFieldEnd = result.length(); 1586 1587 result.append(decimal); 1588 addedDecimalSeparator = true; 1589 1590 // Record field information for caller. 1591 fFieldStart = result.length(); 1592 } 1593 1594 // Record field information 1595 if (iFieldEnd == -1) { 1596 iFieldEnd = result.length(); 1597 } 1598 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER, 1599 iFieldStart, iFieldEnd, result); 1600 if (addedDecimalSeparator) { 1601 delegate.formatted(Field.DECIMAL_SEPARATOR, 1602 Field.DECIMAL_SEPARATOR, 1603 iFieldEnd, fFieldStart, result); 1604 } 1605 if (fFieldStart == -1) { 1606 fFieldStart = result.length(); 1607 } 1608 delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION, 1609 fFieldStart, result.length(), result); 1610 1611 // The exponent is output using the pattern-specified minimum 1612 // exponent digits. There is no maximum limit to the exponent 1613 // digits, since truncating the exponent would result in an 1614 // unacceptable inaccuracy. 1615 int fieldStart = result.length(); 1616 1617 result.append(symbols.getExponentSeparator()); 1618 1619 delegate.formatted(Field.EXPONENT_SYMBOL, Field.EXPONENT_SYMBOL, 1620 fieldStart, result.length(), result); 1621 1622 // For zero values, we force the exponent to zero. We 1623 // must do this here, and not earlier, because the value 1624 // is used to determine integer digit count above. 1625 if (digitList.isZero()) { 1626 exponent = 0; 1627 } 1628 1629 boolean negativeExponent = exponent < 0; 1630 if (negativeExponent) { 1631 exponent = -exponent; 1632 fieldStart = result.length(); 1633 result.append(symbols.getMinusSign()); 1634 delegate.formatted(Field.EXPONENT_SIGN, Field.EXPONENT_SIGN, 1635 fieldStart, result.length(), result); 1636 } 1637 digitList.set(negativeExponent, exponent); 1638 1639 int eFieldStart = result.length(); 1640 1641 for (int i=digitList.decimalAt; i<minExponentDigits; ++i) { 1642 result.append(zero); 1643 } 1644 for (int i=0; i<digitList.decimalAt; ++i) { 1645 result.append((i < digitList.count) ? 1646 (char)(digitList.digits[i] + zeroDelta) : zero); 1647 } 1648 delegate.formatted(Field.EXPONENT, Field.EXPONENT, eFieldStart, 1649 result.length(), result); 1650 } else { 1651 int iFieldStart = result.length(); 1652 1653 // Output the integer portion. Here 'count' is the total 1654 // number of integer digits we will display, including both 1655 // leading zeros required to satisfy getMinimumIntegerDigits, 1656 // and actual digits present in the number. 1657 int count = minIntDigits; 1658 int digitIndex = 0; // Index into digitList.fDigits[] 1659 if (digitList.decimalAt > 0 && count < digitList.decimalAt) { 1660 count = digitList.decimalAt; 1661 } 1662 1663 // Handle the case where getMaximumIntegerDigits() is smaller 1664 // than the real number of integer digits. If this is so, we 1665 // output the least significant max integer digits. For example, 1666 // the value 1997 printed with 2 max integer digits is just "97". 1667 if (count > maxIntDigits) { 1668 count = maxIntDigits; 1669 digitIndex = digitList.decimalAt - count; 1670 } 1671 1672 int sizeBeforeIntegerPart = result.length(); 1673 for (int i=count-1; i>=0; --i) { 1674 if (i < digitList.decimalAt && digitIndex < digitList.count) { 1675 // Output a real digit 1676 result.append((char)(digitList.digits[digitIndex++] + zeroDelta)); 1677 } else { 1678 // Output a leading zero 1679 result.append(zero); 1680 } 1681 1682 // Output grouping separator if necessary. Don't output a 1683 // grouping separator if i==0 though; that's at the end of 1684 // the integer part. 1685 if (isGroupingUsed() && i>0 && (groupingSize != 0) && 1686 (i % groupingSize == 0)) { 1687 int gStart = result.length(); 1688 result.append(grouping); 1689 delegate.formatted(Field.GROUPING_SEPARATOR, 1690 Field.GROUPING_SEPARATOR, gStart, 1691 result.length(), result); 1692 } 1693 } 1694 1695 // Determine whether or not there are any printable fractional 1696 // digits. If we've used up the digits we know there aren't. 1697 boolean fractionPresent = (minFraDigits > 0) || 1698 (!isInteger && digitIndex < digitList.count); 1699 1700 // If there is no fraction present, and we haven't printed any 1701 // integer digits, then print a zero. Otherwise we won't print 1702 // _any_ digits, and we won't be able to parse this string. 1703 if (!fractionPresent && result.length() == sizeBeforeIntegerPart) { 1704 result.append(zero); 1705 } 1706 1707 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER, 1708 iFieldStart, result.length(), result); 1709 1710 // Output the decimal separator if we always do so. 1711 int sStart = result.length(); 1712 if (decimalSeparatorAlwaysShown || fractionPresent) { 1713 result.append(decimal); 1714 } 1715 1716 if (sStart != result.length()) { 1717 delegate.formatted(Field.DECIMAL_SEPARATOR, 1718 Field.DECIMAL_SEPARATOR, 1719 sStart, result.length(), result); 1720 } 1721 int fFieldStart = result.length(); 1722 1723 for (int i=0; i < maxFraDigits; ++i) { 1724 // Here is where we escape from the loop. We escape if we've 1725 // output the maximum fraction digits (specified in the for 1726 // expression above). 1727 // We also stop when we've output the minimum digits and either: 1728 // we have an integer, so there is no fractional stuff to 1729 // display, or we're out of significant digits. 1730 if (i >= minFraDigits && 1731 (isInteger || digitIndex >= digitList.count)) { 1732 break; 1733 } 1734 1735 // Output leading fractional zeros. These are zeros that come 1736 // after the decimal but before any significant digits. These 1737 // are only output if abs(number being formatted) < 1.0. 1738 if (-1-i > (digitList.decimalAt-1)) { 1739 result.append(zero); 1740 continue; 1741 } 1742 1743 // Output a digit, if we have any precision left, or a 1744 // zero if we don't. We don't want to output noise digits. 1745 if (!isInteger && digitIndex < digitList.count) { 1746 result.append((char)(digitList.digits[digitIndex++] + zeroDelta)); 1747 } else { 1748 result.append(zero); 1749 } 1750 } 1751 1752 // Record field information for caller. 1753 delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION, 1754 fFieldStart, result.length(), result); 1755 } 1756 1757 if (isNegative) { 1758 append(result, negativeSuffix, delegate, 1759 getNegativeSuffixFieldPositions(), Field.SIGN); 1760 } 1761 else { 1762 append(result, positiveSuffix, delegate, 1763 getPositiveSuffixFieldPositions(), Field.SIGN); 1764 } 1765 1766 return result; 1767 } 1768 1769 /** 1770 * Appends the String <code>string</code> to <code>result</code>. 1771 * <code>delegate</code> is notified of all the 1772 * <code>FieldPosition</code>s in <code>positions</code>. 1773 * <p> 1774 * If one of the <code>FieldPosition</code>s in <code>positions</code> 1775 * identifies a <code>SIGN</code> attribute, it is mapped to 1776 * <code>signAttribute</code>. This is used 1777 * to map the <code>SIGN</code> attribute to the <code>EXPONENT</code> 1778 * attribute as necessary. 1779 * <p> 1780 * This is used by <code>subformat</code> to add the prefix/suffix. 1781 */ 1782 private void append(StringBuffer result, String string, 1783 FieldDelegate delegate, 1784 FieldPosition[] positions, 1785 Format.Field signAttribute) { 1786 int start = result.length(); 1787 1788 if (string.length() > 0) { 1789 result.append(string); 1790 for (int counter = 0, max = positions.length; counter < max; 1791 counter++) { 1792 FieldPosition fp = positions[counter]; 1793 Format.Field attribute = fp.getFieldAttribute(); 1794 1795 if (attribute == Field.SIGN) { 1796 attribute = signAttribute; 1797 } 1798 delegate.formatted(attribute, attribute, 1799 start + fp.getBeginIndex(), 1800 start + fp.getEndIndex(), result); 1801 } 1802 } 1803 } 1804 1805 /** 1806 * Parses text from a string to produce a <code>Number</code>. 1807 * <p> 1808 * The method attempts to parse text starting at the index given by 1809 * <code>pos</code>. 1810 * If parsing succeeds, then the index of <code>pos</code> is updated 1811 * to the index after the last character used (parsing does not necessarily 1812 * use all characters up to the end of the string), and the parsed 1813 * number is returned. The updated <code>pos</code> can be used to 1814 * indicate the starting point for the next call to this method. 1815 * If an error occurs, then the index of <code>pos</code> is not 1816 * changed, the error index of <code>pos</code> is set to the index of 1817 * the character where the error occurred, and null is returned. 1818 * <p> 1819 * The subclass returned depends on the value of {@link #isParseBigDecimal} 1820 * as well as on the string being parsed. 1821 * <ul> 1822 * <li>If <code>isParseBigDecimal()</code> is false (the default), 1823 * most integer values are returned as <code>Long</code> 1824 * objects, no matter how they are written: <code>"17"</code> and 1825 * <code>"17.000"</code> both parse to <code>Long(17)</code>. 1826 * Values that cannot fit into a <code>Long</code> are returned as 1827 * <code>Double</code>s. This includes values with a fractional part, 1828 * infinite values, <code>NaN</code>, and the value -0.0. 1829 * <code>DecimalFormat</code> does <em>not</em> decide whether to 1830 * return a <code>Double</code> or a <code>Long</code> based on the 1831 * presence of a decimal separator in the source string. Doing so 1832 * would prevent integers that overflow the mantissa of a double, 1833 * such as <code>"-9,223,372,036,854,775,808.00"</code>, from being 1834 * parsed accurately. 1835 * <p> 1836 * Callers may use the <code>Number</code> methods 1837 * <code>doubleValue</code>, <code>longValue</code>, etc., to obtain 1838 * the type they want. 1839 * <li>If <code>isParseBigDecimal()</code> is true, values are returned 1840 * as <code>BigDecimal</code> objects. The values are the ones 1841 * constructed by {@link java.math.BigDecimal#BigDecimal(String)} 1842 * for corresponding strings in locale-independent format. The 1843 * special cases negative and positive infinity and NaN are returned 1844 * as <code>Double</code> instances holding the values of the 1845 * corresponding <code>Double</code> constants. 1846 * </ul> 1847 * <p> 1848 * <code>DecimalFormat</code> parses all Unicode characters that represent 1849 * decimal digits, as defined by <code>Character.digit()</code>. In 1850 * addition, <code>DecimalFormat</code> also recognizes as digits the ten 1851 * consecutive characters starting with the localized zero digit defined in 1852 * the <code>DecimalFormatSymbols</code> object. 1853 * 1854 * @param text the string to be parsed 1855 * @param pos A <code>ParsePosition</code> object with index and error 1856 * index information as described above. 1857 * @return the parsed value, or <code>null</code> if the parse fails 1858 * @exception NullPointerException if <code>text</code> or 1859 * <code>pos</code> is null. 1860 */ 1861 public Number parse(String text, ParsePosition pos) { 1862 // special case NaN 1863 if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) { 1864 pos.index = pos.index + symbols.getNaN().length(); 1865 return new Double(Double.NaN); 1866 } 1867 1868 boolean[] status = new boolean[STATUS_LENGTH]; 1869 if (!subparse(text, pos, positivePrefix, negativePrefix, digitList, false, status)) { 1870 return null; 1871 } 1872 1873 // special case INFINITY 1874 if (status[STATUS_INFINITE]) { 1875 if (status[STATUS_POSITIVE] == (multiplier >= 0)) { 1876 return new Double(Double.POSITIVE_INFINITY); 1877 } else { 1878 return new Double(Double.NEGATIVE_INFINITY); 1879 } 1880 } 1881 1882 if (multiplier == 0) { 1883 if (digitList.isZero()) { 1884 return new Double(Double.NaN); 1885 } else if (status[STATUS_POSITIVE]) { 1886 return new Double(Double.POSITIVE_INFINITY); 1887 } else { 1888 return new Double(Double.NEGATIVE_INFINITY); 1889 } 1890 } 1891 1892 if (isParseBigDecimal()) { 1893 BigDecimal bigDecimalResult = digitList.getBigDecimal(); 1894 1895 if (multiplier != 1) { 1896 try { 1897 bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier()); 1898 } 1899 catch (ArithmeticException e) { // non-terminating decimal expansion 1900 bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier(), roundingMode); 1901 } 1902 } 1903 1904 if (!status[STATUS_POSITIVE]) { 1905 bigDecimalResult = bigDecimalResult.negate(); 1906 } 1907 return bigDecimalResult; 1908 } else { 1909 boolean gotDouble = true; 1910 boolean gotLongMinimum = false; 1911 double doubleResult = 0.0; 1912 long longResult = 0; 1913 1914 // Finally, have DigitList parse the digits into a value. 1915 if (digitList.fitsIntoLong(status[STATUS_POSITIVE], isParseIntegerOnly())) { 1916 gotDouble = false; 1917 longResult = digitList.getLong(); 1918 if (longResult < 0) { // got Long.MIN_VALUE 1919 gotLongMinimum = true; 1920 } 1921 } else { 1922 doubleResult = digitList.getDouble(); 1923 } 1924 1925 // Divide by multiplier. We have to be careful here not to do 1926 // unneeded conversions between double and long. 1927 if (multiplier != 1) { 1928 if (gotDouble) { 1929 doubleResult /= multiplier; 1930 } else { 1931 // Avoid converting to double if we can 1932 if (longResult % multiplier == 0) { 1933 longResult /= multiplier; 1934 } else { 1935 doubleResult = ((double)longResult) / multiplier; 1936 gotDouble = true; 1937 } 1938 } 1939 } 1940 1941 if (!status[STATUS_POSITIVE] && !gotLongMinimum) { 1942 doubleResult = -doubleResult; 1943 longResult = -longResult; 1944 } 1945 1946 // At this point, if we divided the result by the multiplier, the 1947 // result may fit into a long. We check for this case and return 1948 // a long if possible. 1949 // We must do this AFTER applying the negative (if appropriate) 1950 // in order to handle the case of LONG_MIN; otherwise, if we do 1951 // this with a positive value -LONG_MIN, the double is > 0, but 1952 // the long is < 0. We also must retain a double in the case of 1953 // -0.0, which will compare as == to a long 0 cast to a double 1954 // (bug 4162852). 1955 if (multiplier != 1 && gotDouble) { 1956 longResult = (long)doubleResult; 1957 gotDouble = ((doubleResult != (double)longResult) || 1958 (doubleResult == 0.0 && 1/doubleResult < 0.0)) && 1959 !isParseIntegerOnly(); 1960 } 1961 1962 return gotDouble ? 1963 (Number)new Double(doubleResult) : (Number)new Long(longResult); 1964 } 1965 } 1966 1967 /** 1968 * Return a BigInteger multiplier. 1969 */ 1970 private BigInteger getBigIntegerMultiplier() { 1971 if (bigIntegerMultiplier == null) { 1972 bigIntegerMultiplier = BigInteger.valueOf(multiplier); 1973 } 1974 return bigIntegerMultiplier; 1975 } 1976 private transient BigInteger bigIntegerMultiplier; 1977 1978 /** 1979 * Return a BigDecimal multiplier. 1980 */ 1981 private BigDecimal getBigDecimalMultiplier() { 1982 if (bigDecimalMultiplier == null) { 1983 bigDecimalMultiplier = new BigDecimal(multiplier); 1984 } 1985 return bigDecimalMultiplier; 1986 } 1987 private transient BigDecimal bigDecimalMultiplier; 1988 1989 private static final int STATUS_INFINITE = 0; 1990 private static final int STATUS_POSITIVE = 1; 1991 private static final int STATUS_LENGTH = 2; 1992 1993 /** 1994 * Parse the given text into a number. The text is parsed beginning at 1995 * parsePosition, until an unparseable character is seen. 1996 * @param text The string to parse. 1997 * @param parsePosition The position at which to being parsing. Upon 1998 * return, the first unparseable character. 1999 * @param digits The DigitList to set to the parsed value. 2000 * @param isExponent If true, parse an exponent. This means no 2001 * infinite values and integer only. 2002 * @param status Upon return contains boolean status flags indicating 2003 * whether the value was infinite and whether it was positive. 2004 */ 2005 private final boolean subparse(String text, ParsePosition parsePosition, 2006 String positivePrefix, String negativePrefix, 2007 DigitList digits, boolean isExponent, 2008 boolean status[]) { 2009 int position = parsePosition.index; 2010 int oldStart = parsePosition.index; 2011 int backup; 2012 boolean gotPositive, gotNegative; 2013 2014 // check for positivePrefix; take longest 2015 gotPositive = text.regionMatches(position, positivePrefix, 0, 2016 positivePrefix.length()); 2017 gotNegative = text.regionMatches(position, negativePrefix, 0, 2018 negativePrefix.length()); 2019 2020 if (gotPositive && gotNegative) { 2021 if (positivePrefix.length() > negativePrefix.length()) { 2022 gotNegative = false; 2023 } else if (positivePrefix.length() < negativePrefix.length()) { 2024 gotPositive = false; 2025 } 2026 } 2027 2028 if (gotPositive) { 2029 position += positivePrefix.length(); 2030 } else if (gotNegative) { 2031 position += negativePrefix.length(); 2032 } else { 2033 parsePosition.errorIndex = position; 2034 return false; 2035 } 2036 2037 // process digits or Inf, find decimal position 2038 status[STATUS_INFINITE] = false; 2039 if (!isExponent && text.regionMatches(position,symbols.getInfinity(),0, 2040 symbols.getInfinity().length())) { 2041 position += symbols.getInfinity().length(); 2042 status[STATUS_INFINITE] = true; 2043 } else { 2044 // We now have a string of digits, possibly with grouping symbols, 2045 // and decimal points. We want to process these into a DigitList. 2046 // We don't want to put a bunch of leading zeros into the DigitList 2047 // though, so we keep track of the location of the decimal point, 2048 // put only significant digits into the DigitList, and adjust the 2049 // exponent as needed. 2050 2051 digits.decimalAt = digits.count = 0; 2052 char zero = symbols.getZeroDigit(); 2053 char decimal = isCurrencyFormat ? 2054 symbols.getMonetaryDecimalSeparator() : 2055 symbols.getDecimalSeparator(); 2056 char grouping = symbols.getGroupingSeparator(); 2057 String exponentString = symbols.getExponentSeparator(); 2058 boolean sawDecimal = false; 2059 boolean sawExponent = false; 2060 boolean sawDigit = false; 2061 int exponent = 0; // Set to the exponent value, if any 2062 2063 // We have to track digitCount ourselves, because digits.count will 2064 // pin when the maximum allowable digits is reached. 2065 int digitCount = 0; 2066 2067 backup = -1; 2068 for (; position < text.length(); ++position) { 2069 char ch = text.charAt(position); 2070 2071 /* We recognize all digit ranges, not only the Latin digit range 2072 * '0'..'9'. We do so by using the Character.digit() method, 2073 * which converts a valid Unicode digit to the range 0..9. 2074 * 2075 * The character 'ch' may be a digit. If so, place its value 2076 * from 0 to 9 in 'digit'. First try using the locale digit, 2077 * which may or MAY NOT be a standard Unicode digit range. If 2078 * this fails, try using the standard Unicode digit ranges by 2079 * calling Character.digit(). If this also fails, digit will 2080 * have a value outside the range 0..9. 2081 */ 2082 int digit = ch - zero; 2083 if (digit < 0 || digit > 9) { 2084 digit = Character.digit(ch, 10); 2085 } 2086 2087 if (digit == 0) { 2088 // Cancel out backup setting (see grouping handler below) 2089 backup = -1; // Do this BEFORE continue statement below!!! 2090 sawDigit = true; 2091 2092 // Handle leading zeros 2093 if (digits.count == 0) { 2094 // Ignore leading zeros in integer part of number. 2095 if (!sawDecimal) { 2096 continue; 2097 } 2098 2099 // If we have seen the decimal, but no significant 2100 // digits yet, then we account for leading zeros by 2101 // decrementing the digits.decimalAt into negative 2102 // values. 2103 --digits.decimalAt; 2104 } else { 2105 ++digitCount; 2106 digits.append((char)(digit + '0')); 2107 } 2108 } else if (digit > 0 && digit <= 9) { // [sic] digit==0 handled above 2109 sawDigit = true; 2110 ++digitCount; 2111 digits.append((char)(digit + '0')); 2112 2113 // Cancel out backup setting (see grouping handler below) 2114 backup = -1; 2115 } else if (!isExponent && ch == decimal) { 2116 // If we're only parsing integers, or if we ALREADY saw the 2117 // decimal, then don't parse this one. 2118 if (isParseIntegerOnly() || sawDecimal) { 2119 break; 2120 } 2121 digits.decimalAt = digitCount; // Not digits.count! 2122 sawDecimal = true; 2123 } else if (!isExponent && ch == grouping && isGroupingUsed()) { 2124 if (sawDecimal) { 2125 break; 2126 } 2127 // Ignore grouping characters, if we are using them, but 2128 // require that they be followed by a digit. Otherwise 2129 // we backup and reprocess them. 2130 backup = position; 2131 } else if (!isExponent && text.regionMatches(position, exponentString, 0, exponentString.length()) 2132 && !sawExponent) { 2133 // Process the exponent by recursively calling this method. 2134 ParsePosition pos = new ParsePosition(position + exponentString.length()); 2135 boolean[] stat = new boolean[STATUS_LENGTH]; 2136 DigitList exponentDigits = new DigitList(); 2137 2138 if (subparse(text, pos, "", Character.toString(symbols.getMinusSign()), exponentDigits, true, stat) && 2139 exponentDigits.fitsIntoLong(stat[STATUS_POSITIVE], true)) { 2140 position = pos.index; // Advance past the exponent 2141 exponent = (int)exponentDigits.getLong(); 2142 if (!stat[STATUS_POSITIVE]) { 2143 exponent = -exponent; 2144 } 2145 sawExponent = true; 2146 } 2147 break; // Whether we fail or succeed, we exit this loop 2148 } 2149 else { 2150 break; 2151 } 2152 } 2153 2154 if (backup != -1) { 2155 position = backup; 2156 } 2157 2158 // If there was no decimal point we have an integer 2159 if (!sawDecimal) { 2160 digits.decimalAt = digitCount; // Not digits.count! 2161 } 2162 2163 // Adjust for exponent, if any 2164 digits.decimalAt += exponent; 2165 2166 // If none of the text string was recognized. For example, parse 2167 // "x" with pattern "#0.00" (return index and error index both 0) 2168 // parse "$" with pattern "$#0.00". (return index 0 and error 2169 // index 1). 2170 if (!sawDigit && digitCount == 0) { 2171 parsePosition.index = oldStart; 2172 parsePosition.errorIndex = oldStart; 2173 return false; 2174 } 2175 } 2176 2177 // check for suffix 2178 if (!isExponent) { 2179 if (gotPositive) { 2180 gotPositive = text.regionMatches(position,positiveSuffix,0, 2181 positiveSuffix.length()); 2182 } 2183 if (gotNegative) { 2184 gotNegative = text.regionMatches(position,negativeSuffix,0, 2185 negativeSuffix.length()); 2186 } 2187 2188 // if both match, take longest 2189 if (gotPositive && gotNegative) { 2190 if (positiveSuffix.length() > negativeSuffix.length()) { 2191 gotNegative = false; 2192 } else if (positiveSuffix.length() < negativeSuffix.length()) { 2193 gotPositive = false; 2194 } 2195 } 2196 2197 // fail if neither or both 2198 if (gotPositive == gotNegative) { 2199 parsePosition.errorIndex = position; 2200 return false; 2201 } 2202 2203 parsePosition.index = position + 2204 (gotPositive ? positiveSuffix.length() : negativeSuffix.length()); // mark success! 2205 } else { 2206 parsePosition.index = position; 2207 } 2208 2209 status[STATUS_POSITIVE] = gotPositive; 2210 if (parsePosition.index == oldStart) { 2211 parsePosition.errorIndex = position; 2212 return false; 2213 } 2214 return true; 2215 } 2216 2217 /** 2218 * Returns a copy of the decimal format symbols, which is generally not 2219 * changed by the programmer or user. 2220 * @return a copy of the desired DecimalFormatSymbols 2221 * @see java.text.DecimalFormatSymbols 2222 */ 2223 public DecimalFormatSymbols getDecimalFormatSymbols() { 2224 try { 2225 // don't allow multiple references 2226 return (DecimalFormatSymbols) symbols.clone(); 2227 } catch (Exception foo) { 2228 return null; // should never happen 2229 } 2230 } 2231 2232 2233 /** 2234 * Sets the decimal format symbols, which is generally not changed 2235 * by the programmer or user. 2236 * @param newSymbols desired DecimalFormatSymbols 2237 * @see java.text.DecimalFormatSymbols 2238 */ 2239 public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) { 2240 try { 2241 // don't allow multiple references 2242 symbols = (DecimalFormatSymbols) newSymbols.clone(); 2243 expandAffixes(); 2244 fastPathCheckNeeded = true; 2245 } catch (Exception foo) { 2246 // should never happen 2247 } 2248 } 2249 2250 /** 2251 * Get the positive prefix. 2252 * <P>Examples: +123, $123, sFr123 2253 */ 2254 public String getPositivePrefix () { 2255 return positivePrefix; 2256 } 2257 2258 /** 2259 * Set the positive prefix. 2260 * <P>Examples: +123, $123, sFr123 2261 */ 2262 public void setPositivePrefix (String newValue) { 2263 positivePrefix = newValue; 2264 posPrefixPattern = null; 2265 positivePrefixFieldPositions = null; 2266 fastPathCheckNeeded = true; 2267 } 2268 2269 /** 2270 * Returns the FieldPositions of the fields in the prefix used for 2271 * positive numbers. This is not used if the user has explicitly set 2272 * a positive prefix via <code>setPositivePrefix</code>. This is 2273 * lazily created. 2274 * 2275 * @return FieldPositions in positive prefix 2276 */ 2277 private FieldPosition[] getPositivePrefixFieldPositions() { 2278 if (positivePrefixFieldPositions == null) { 2279 if (posPrefixPattern != null) { 2280 positivePrefixFieldPositions = expandAffix(posPrefixPattern); 2281 } 2282 else { 2283 positivePrefixFieldPositions = EmptyFieldPositionArray; 2284 } 2285 } 2286 return positivePrefixFieldPositions; 2287 } 2288 2289 /** 2290 * Get the negative prefix. 2291 * <P>Examples: -123, ($123) (with negative suffix), sFr-123 2292 */ 2293 public String getNegativePrefix () { 2294 return negativePrefix; 2295 } 2296 2297 /** 2298 * Set the negative prefix. 2299 * <P>Examples: -123, ($123) (with negative suffix), sFr-123 2300 */ 2301 public void setNegativePrefix (String newValue) { 2302 negativePrefix = newValue; 2303 negPrefixPattern = null; 2304 fastPathCheckNeeded = true; 2305 } 2306 2307 /** 2308 * Returns the FieldPositions of the fields in the prefix used for 2309 * negative numbers. This is not used if the user has explicitly set 2310 * a negative prefix via <code>setNegativePrefix</code>. This is 2311 * lazily created. 2312 * 2313 * @return FieldPositions in positive prefix 2314 */ 2315 private FieldPosition[] getNegativePrefixFieldPositions() { 2316 if (negativePrefixFieldPositions == null) { 2317 if (negPrefixPattern != null) { 2318 negativePrefixFieldPositions = expandAffix(negPrefixPattern); 2319 } 2320 else { 2321 negativePrefixFieldPositions = EmptyFieldPositionArray; 2322 } 2323 } 2324 return negativePrefixFieldPositions; 2325 } 2326 2327 /** 2328 * Get the positive suffix. 2329 * <P>Example: 123% 2330 */ 2331 public String getPositiveSuffix () { 2332 return positiveSuffix; 2333 } 2334 2335 /** 2336 * Set the positive suffix. 2337 * <P>Example: 123% 2338 */ 2339 public void setPositiveSuffix (String newValue) { 2340 positiveSuffix = newValue; 2341 posSuffixPattern = null; 2342 fastPathCheckNeeded = true; 2343 } 2344 2345 /** 2346 * Returns the FieldPositions of the fields in the suffix used for 2347 * positive numbers. This is not used if the user has explicitly set 2348 * a positive suffix via <code>setPositiveSuffix</code>. This is 2349 * lazily created. 2350 * 2351 * @return FieldPositions in positive prefix 2352 */ 2353 private FieldPosition[] getPositiveSuffixFieldPositions() { 2354 if (positiveSuffixFieldPositions == null) { 2355 if (posSuffixPattern != null) { 2356 positiveSuffixFieldPositions = expandAffix(posSuffixPattern); 2357 } 2358 else { 2359 positiveSuffixFieldPositions = EmptyFieldPositionArray; 2360 } 2361 } 2362 return positiveSuffixFieldPositions; 2363 } 2364 2365 /** 2366 * Get the negative suffix. 2367 * <P>Examples: -123%, ($123) (with positive suffixes) 2368 */ 2369 public String getNegativeSuffix () { 2370 return negativeSuffix; 2371 } 2372 2373 /** 2374 * Set the negative suffix. 2375 * <P>Examples: 123% 2376 */ 2377 public void setNegativeSuffix (String newValue) { 2378 negativeSuffix = newValue; 2379 negSuffixPattern = null; 2380 fastPathCheckNeeded = true; 2381 } 2382 2383 /** 2384 * Returns the FieldPositions of the fields in the suffix used for 2385 * negative numbers. This is not used if the user has explicitly set 2386 * a negative suffix via <code>setNegativeSuffix</code>. This is 2387 * lazily created. 2388 * 2389 * @return FieldPositions in positive prefix 2390 */ 2391 private FieldPosition[] getNegativeSuffixFieldPositions() { 2392 if (negativeSuffixFieldPositions == null) { 2393 if (negSuffixPattern != null) { 2394 negativeSuffixFieldPositions = expandAffix(negSuffixPattern); 2395 } 2396 else { 2397 negativeSuffixFieldPositions = EmptyFieldPositionArray; 2398 } 2399 } 2400 return negativeSuffixFieldPositions; 2401 } 2402 2403 /** 2404 * Gets the multiplier for use in percent, per mille, and similar 2405 * formats. 2406 * 2407 * @see #setMultiplier(int) 2408 */ 2409 public int getMultiplier () { 2410 return multiplier; 2411 } 2412 2413 /** 2414 * Sets the multiplier for use in percent, per mille, and similar 2415 * formats. 2416 * For a percent format, set the multiplier to 100 and the suffixes to 2417 * have '%' (for Arabic, use the Arabic percent sign). 2418 * For a per mille format, set the multiplier to 1000 and the suffixes to 2419 * have '\u2030'. 2420 * 2421 * <P>Example: with multiplier 100, 1.23 is formatted as "123", and 2422 * "123" is parsed into 1.23. 2423 * 2424 * @see #getMultiplier 2425 */ 2426 public void setMultiplier (int newValue) { 2427 multiplier = newValue; 2428 bigDecimalMultiplier = null; 2429 bigIntegerMultiplier = null; 2430 fastPathCheckNeeded = true; 2431 } 2432 2433 /** 2434 * Set whether or not grouping will be used in this format. 2435 * @see #isGroupingUsed 2436 */ 2437 public void setGroupingUsed(boolean newValue) { 2438 super.setGroupingUsed(newValue); 2439 fastPathCheckNeeded = true; 2440 } 2441 2442 /** 2443 * Return the grouping size. Grouping size is the number of digits between 2444 * grouping separators in the integer portion of a number. For example, 2445 * in the number "123,456.78", the grouping size is 3. 2446 * @see #setGroupingSize 2447 * @see java.text.NumberFormat#isGroupingUsed 2448 * @see java.text.DecimalFormatSymbols#getGroupingSeparator 2449 */ 2450 public int getGroupingSize () { 2451 return groupingSize; 2452 } 2453 2454 /** 2455 * Set the grouping size. Grouping size is the number of digits between 2456 * grouping separators in the integer portion of a number. For example, 2457 * in the number "123,456.78", the grouping size is 3. 2458 * <br> 2459 * The value passed in is converted to a byte, which may lose information. 2460 * @see #getGroupingSize 2461 * @see java.text.NumberFormat#setGroupingUsed 2462 * @see java.text.DecimalFormatSymbols#setGroupingSeparator 2463 */ 2464 public void setGroupingSize (int newValue) { 2465 groupingSize = (byte)newValue; 2466 fastPathCheckNeeded = true; 2467 } 2468 2469 /** 2470 * Allows you to get the behavior of the decimal separator with integers. 2471 * (The decimal separator will always appear with decimals.) 2472 * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345 2473 */ 2474 public boolean isDecimalSeparatorAlwaysShown() { 2475 return decimalSeparatorAlwaysShown; 2476 } 2477 2478 /** 2479 * Allows you to set the behavior of the decimal separator with integers. 2480 * (The decimal separator will always appear with decimals.) 2481 * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345 2482 */ 2483 public void setDecimalSeparatorAlwaysShown(boolean newValue) { 2484 decimalSeparatorAlwaysShown = newValue; 2485 fastPathCheckNeeded = true; 2486 } 2487 2488 /** 2489 * Returns whether the {@link #parse(java.lang.String, java.text.ParsePosition)} 2490 * method returns <code>BigDecimal</code>. The default value is false. 2491 * @see #setParseBigDecimal 2492 * @since 1.5 2493 */ 2494 public boolean isParseBigDecimal() { 2495 return parseBigDecimal; 2496 } 2497 2498 /** 2499 * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)} 2500 * method returns <code>BigDecimal</code>. 2501 * @see #isParseBigDecimal 2502 * @since 1.5 2503 */ 2504 public void setParseBigDecimal(boolean newValue) { 2505 parseBigDecimal = newValue; 2506 } 2507 2508 /** 2509 * Standard override; no change in semantics. 2510 */ 2511 public Object clone() { 2512 DecimalFormat other = (DecimalFormat) super.clone(); 2513 other.symbols = (DecimalFormatSymbols) symbols.clone(); 2514 other.digitList = (DigitList) digitList.clone(); 2515 return other; 2516 } 2517 2518 /** 2519 * Overrides equals 2520 */ 2521 public boolean equals(Object obj) 2522 { 2523 if (obj == null) return false; 2524 if (!super.equals(obj)) return false; // super does class check 2525 DecimalFormat other = (DecimalFormat) obj; 2526 return ((posPrefixPattern == other.posPrefixPattern && 2527 positivePrefix.equals(other.positivePrefix)) 2528 || (posPrefixPattern != null && 2529 posPrefixPattern.equals(other.posPrefixPattern))) 2530 && ((posSuffixPattern == other.posSuffixPattern && 2531 positiveSuffix.equals(other.positiveSuffix)) 2532 || (posSuffixPattern != null && 2533 posSuffixPattern.equals(other.posSuffixPattern))) 2534 && ((negPrefixPattern == other.negPrefixPattern && 2535 negativePrefix.equals(other.negativePrefix)) 2536 || (negPrefixPattern != null && 2537 negPrefixPattern.equals(other.negPrefixPattern))) 2538 && ((negSuffixPattern == other.negSuffixPattern && 2539 negativeSuffix.equals(other.negativeSuffix)) 2540 || (negSuffixPattern != null && 2541 negSuffixPattern.equals(other.negSuffixPattern))) 2542 && multiplier == other.multiplier 2543 && groupingSize == other.groupingSize 2544 && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown 2545 && parseBigDecimal == other.parseBigDecimal 2546 && useExponentialNotation == other.useExponentialNotation 2547 && (!useExponentialNotation || 2548 minExponentDigits == other.minExponentDigits) 2549 && maximumIntegerDigits == other.maximumIntegerDigits 2550 && minimumIntegerDigits == other.minimumIntegerDigits 2551 && maximumFractionDigits == other.maximumFractionDigits 2552 && minimumFractionDigits == other.minimumFractionDigits 2553 && roundingMode == other.roundingMode 2554 && symbols.equals(other.symbols); 2555 } 2556 2557 /** 2558 * Overrides hashCode 2559 */ 2560 public int hashCode() { 2561 return super.hashCode() * 37 + positivePrefix.hashCode(); 2562 // just enough fields for a reasonable distribution 2563 } 2564 2565 /** 2566 * Synthesizes a pattern string that represents the current state 2567 * of this Format object. 2568 * @see #applyPattern 2569 */ 2570 public String toPattern() { 2571 return toPattern( false ); 2572 } 2573 2574 /** 2575 * Synthesizes a localized pattern string that represents the current 2576 * state of this Format object. 2577 * @see #applyPattern 2578 */ 2579 public String toLocalizedPattern() { 2580 return toPattern( true ); 2581 } 2582 2583 /** 2584 * Expand the affix pattern strings into the expanded affix strings. If any 2585 * affix pattern string is null, do not expand it. This method should be 2586 * called any time the symbols or the affix patterns change in order to keep 2587 * the expanded affix strings up to date. 2588 */ 2589 private void expandAffixes() { 2590 // Reuse one StringBuffer for better performance 2591 StringBuffer buffer = new StringBuffer(); 2592 if (posPrefixPattern != null) { 2593 positivePrefix = expandAffix(posPrefixPattern, buffer); 2594 positivePrefixFieldPositions = null; 2595 } 2596 if (posSuffixPattern != null) { 2597 positiveSuffix = expandAffix(posSuffixPattern, buffer); 2598 positiveSuffixFieldPositions = null; 2599 } 2600 if (negPrefixPattern != null) { 2601 negativePrefix = expandAffix(negPrefixPattern, buffer); 2602 negativePrefixFieldPositions = null; 2603 } 2604 if (negSuffixPattern != null) { 2605 negativeSuffix = expandAffix(negSuffixPattern, buffer); 2606 negativeSuffixFieldPositions = null; 2607 } 2608 } 2609 2610 /** 2611 * Expand an affix pattern into an affix string. All characters in the 2612 * pattern are literal unless prefixed by QUOTE. The following characters 2613 * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE, 2614 * PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE + 2615 * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217 2616 * currency code. Any other character after a QUOTE represents itself. 2617 * QUOTE must be followed by another character; QUOTE may not occur by 2618 * itself at the end of the pattern. 2619 * 2620 * @param pattern the non-null, possibly empty pattern 2621 * @param buffer a scratch StringBuffer; its contents will be lost 2622 * @return the expanded equivalent of pattern 2623 */ 2624 private String expandAffix(String pattern, StringBuffer buffer) { 2625 buffer.setLength(0); 2626 for (int i=0; i<pattern.length(); ) { 2627 char c = pattern.charAt(i++); 2628 if (c == QUOTE) { 2629 c = pattern.charAt(i++); 2630 switch (c) { 2631 case CURRENCY_SIGN: 2632 if (i<pattern.length() && 2633 pattern.charAt(i) == CURRENCY_SIGN) { 2634 ++i; 2635 buffer.append(symbols.getInternationalCurrencySymbol()); 2636 } else { 2637 buffer.append(symbols.getCurrencySymbol()); 2638 } 2639 continue; 2640 case PATTERN_PERCENT: 2641 c = symbols.getPercent(); 2642 break; 2643 case PATTERN_PER_MILLE: 2644 c = symbols.getPerMill(); 2645 break; 2646 case PATTERN_MINUS: 2647 c = symbols.getMinusSign(); 2648 break; 2649 } 2650 } 2651 buffer.append(c); 2652 } 2653 return buffer.toString(); 2654 } 2655 2656 /** 2657 * Expand an affix pattern into an array of FieldPositions describing 2658 * how the pattern would be expanded. 2659 * All characters in the 2660 * pattern are literal unless prefixed by QUOTE. The following characters 2661 * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE, 2662 * PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE + 2663 * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217 2664 * currency code. Any other character after a QUOTE represents itself. 2665 * QUOTE must be followed by another character; QUOTE may not occur by 2666 * itself at the end of the pattern. 2667 * 2668 * @param pattern the non-null, possibly empty pattern 2669 * @return FieldPosition array of the resulting fields. 2670 */ 2671 private FieldPosition[] expandAffix(String pattern) { 2672 ArrayList positions = null; 2673 int stringIndex = 0; 2674 for (int i=0; i<pattern.length(); ) { 2675 char c = pattern.charAt(i++); 2676 if (c == QUOTE) { 2677 int field = -1; 2678 Format.Field fieldID = null; 2679 c = pattern.charAt(i++); 2680 switch (c) { 2681 case CURRENCY_SIGN: 2682 String string; 2683 if (i<pattern.length() && 2684 pattern.charAt(i) == CURRENCY_SIGN) { 2685 ++i; 2686 string = symbols.getInternationalCurrencySymbol(); 2687 } else { 2688 string = symbols.getCurrencySymbol(); 2689 } 2690 if (string.length() > 0) { 2691 if (positions == null) { 2692 positions = new ArrayList(2); 2693 } 2694 FieldPosition fp = new FieldPosition(Field.CURRENCY); 2695 fp.setBeginIndex(stringIndex); 2696 fp.setEndIndex(stringIndex + string.length()); 2697 positions.add(fp); 2698 stringIndex += string.length(); 2699 } 2700 continue; 2701 case PATTERN_PERCENT: 2702 c = symbols.getPercent(); 2703 field = -1; 2704 fieldID = Field.PERCENT; 2705 break; 2706 case PATTERN_PER_MILLE: 2707 c = symbols.getPerMill(); 2708 field = -1; 2709 fieldID = Field.PERMILLE; 2710 break; 2711 case PATTERN_MINUS: 2712 c = symbols.getMinusSign(); 2713 field = -1; 2714 fieldID = Field.SIGN; 2715 break; 2716 } 2717 if (fieldID != null) { 2718 if (positions == null) { 2719 positions = new ArrayList(2); 2720 } 2721 FieldPosition fp = new FieldPosition(fieldID, field); 2722 fp.setBeginIndex(stringIndex); 2723 fp.setEndIndex(stringIndex + 1); 2724 positions.add(fp); 2725 } 2726 } 2727 stringIndex++; 2728 } 2729 if (positions != null) { 2730 return (FieldPosition[])positions.toArray(EmptyFieldPositionArray); 2731 } 2732 return EmptyFieldPositionArray; 2733 } 2734 2735 /** 2736 * Appends an affix pattern to the given StringBuffer, quoting special 2737 * characters as needed. Uses the internal affix pattern, if that exists, 2738 * or the literal affix, if the internal affix pattern is null. The 2739 * appended string will generate the same affix pattern (or literal affix) 2740 * when passed to toPattern(). 2741 * 2742 * @param buffer the affix string is appended to this 2743 * @param affixPattern a pattern such as posPrefixPattern; may be null 2744 * @param expAffix a corresponding expanded affix, such as positivePrefix. 2745 * Ignored unless affixPattern is null. If affixPattern is null, then 2746 * expAffix is appended as a literal affix. 2747 * @param localized true if the appended pattern should contain localized 2748 * pattern characters; otherwise, non-localized pattern chars are appended 2749 */ 2750 private void appendAffix(StringBuffer buffer, String affixPattern, 2751 String expAffix, boolean localized) { 2752 if (affixPattern == null) { 2753 appendAffix(buffer, expAffix, localized); 2754 } else { 2755 int i; 2756 for (int pos=0; pos<affixPattern.length(); pos=i) { 2757 i = affixPattern.indexOf(QUOTE, pos); 2758 if (i < 0) { 2759 appendAffix(buffer, affixPattern.substring(pos), localized); 2760 break; 2761 } 2762 if (i > pos) { 2763 appendAffix(buffer, affixPattern.substring(pos, i), localized); 2764 } 2765 char c = affixPattern.charAt(++i); 2766 ++i; 2767 if (c == QUOTE) { 2768 buffer.append(c); 2769 // Fall through and append another QUOTE below 2770 } else if (c == CURRENCY_SIGN && 2771 i<affixPattern.length() && 2772 affixPattern.charAt(i) == CURRENCY_SIGN) { 2773 ++i; 2774 buffer.append(c); 2775 // Fall through and append another CURRENCY_SIGN below 2776 } else if (localized) { 2777 switch (c) { 2778 case PATTERN_PERCENT: 2779 c = symbols.getPercent(); 2780 break; 2781 case PATTERN_PER_MILLE: 2782 c = symbols.getPerMill(); 2783 break; 2784 case PATTERN_MINUS: 2785 c = symbols.getMinusSign(); 2786 break; 2787 } 2788 } 2789 buffer.append(c); 2790 } 2791 } 2792 } 2793 2794 /** 2795 * Append an affix to the given StringBuffer, using quotes if 2796 * there are special characters. Single quotes themselves must be 2797 * escaped in either case. 2798 */ 2799 private void appendAffix(StringBuffer buffer, String affix, boolean localized) { 2800 boolean needQuote; 2801 if (localized) { 2802 needQuote = affix.indexOf(symbols.getZeroDigit()) >= 0 2803 || affix.indexOf(symbols.getGroupingSeparator()) >= 0 2804 || affix.indexOf(symbols.getDecimalSeparator()) >= 0 2805 || affix.indexOf(symbols.getPercent()) >= 0 2806 || affix.indexOf(symbols.getPerMill()) >= 0 2807 || affix.indexOf(symbols.getDigit()) >= 0 2808 || affix.indexOf(symbols.getPatternSeparator()) >= 0 2809 || affix.indexOf(symbols.getMinusSign()) >= 0 2810 || affix.indexOf(CURRENCY_SIGN) >= 0; 2811 } 2812 else { 2813 needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 0 2814 || affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 0 2815 || affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 0 2816 || affix.indexOf(PATTERN_PERCENT) >= 0 2817 || affix.indexOf(PATTERN_PER_MILLE) >= 0 2818 || affix.indexOf(PATTERN_DIGIT) >= 0 2819 || affix.indexOf(PATTERN_SEPARATOR) >= 0 2820 || affix.indexOf(PATTERN_MINUS) >= 0 2821 || affix.indexOf(CURRENCY_SIGN) >= 0; 2822 } 2823 if (needQuote) buffer.append('\''); 2824 if (affix.indexOf('\'') < 0) buffer.append(affix); 2825 else { 2826 for (int j=0; j<affix.length(); ++j) { 2827 char c = affix.charAt(j); 2828 buffer.append(c); 2829 if (c == '\'') buffer.append(c); 2830 } 2831 } 2832 if (needQuote) buffer.append('\''); 2833 } 2834 2835 /** 2836 * Does the real work of generating a pattern. */ 2837 private String toPattern(boolean localized) { 2838 StringBuffer result = new StringBuffer(); 2839 for (int j = 1; j >= 0; --j) { 2840 if (j == 1) 2841 appendAffix(result, posPrefixPattern, positivePrefix, localized); 2842 else appendAffix(result, negPrefixPattern, negativePrefix, localized); 2843 int i; 2844 int digitCount = useExponentialNotation 2845 ? getMaximumIntegerDigits() 2846 : Math.max(groupingSize, getMinimumIntegerDigits())+1; 2847 for (i = digitCount; i > 0; --i) { 2848 if (i != digitCount && isGroupingUsed() && groupingSize != 0 && 2849 i % groupingSize == 0) { 2850 result.append(localized ? symbols.getGroupingSeparator() : 2851 PATTERN_GROUPING_SEPARATOR); 2852 } 2853 result.append(i <= getMinimumIntegerDigits() 2854 ? (localized ? symbols.getZeroDigit() : PATTERN_ZERO_DIGIT) 2855 : (localized ? symbols.getDigit() : PATTERN_DIGIT)); 2856 } 2857 if (getMaximumFractionDigits() > 0 || decimalSeparatorAlwaysShown) 2858 result.append(localized ? symbols.getDecimalSeparator() : 2859 PATTERN_DECIMAL_SEPARATOR); 2860 for (i = 0; i < getMaximumFractionDigits(); ++i) { 2861 if (i < getMinimumFractionDigits()) { 2862 result.append(localized ? symbols.getZeroDigit() : 2863 PATTERN_ZERO_DIGIT); 2864 } else { 2865 result.append(localized ? symbols.getDigit() : 2866 PATTERN_DIGIT); 2867 } 2868 } 2869 if (useExponentialNotation) 2870 { 2871 result.append(localized ? symbols.getExponentSeparator() : 2872 PATTERN_EXPONENT); 2873 for (i=0; i<minExponentDigits; ++i) 2874 result.append(localized ? symbols.getZeroDigit() : 2875 PATTERN_ZERO_DIGIT); 2876 } 2877 if (j == 1) { 2878 appendAffix(result, posSuffixPattern, positiveSuffix, localized); 2879 if ((negSuffixPattern == posSuffixPattern && // n == p == null 2880 negativeSuffix.equals(positiveSuffix)) 2881 || (negSuffixPattern != null && 2882 negSuffixPattern.equals(posSuffixPattern))) { 2883 if ((negPrefixPattern != null && posPrefixPattern != null && 2884 negPrefixPattern.equals("'-" + posPrefixPattern)) || 2885 (negPrefixPattern == posPrefixPattern && // n == p == null 2886 negativePrefix.equals(symbols.getMinusSign() + positivePrefix))) 2887 break; 2888 } 2889 result.append(localized ? symbols.getPatternSeparator() : 2890 PATTERN_SEPARATOR); 2891 } else appendAffix(result, negSuffixPattern, negativeSuffix, localized); 2892 } 2893 return result.toString(); 2894 } 2895 2896 /** 2897 * Apply the given pattern to this Format object. A pattern is a 2898 * short-hand specification for the various formatting properties. 2899 * These properties can also be changed individually through the 2900 * various setter methods. 2901 * <p> 2902 * There is no limit to integer digits set 2903 * by this routine, since that is the typical end-user desire; 2904 * use setMaximumInteger if you want to set a real value. 2905 * For negative numbers, use a second pattern, separated by a semicolon 2906 * <P>Example <code>"#,#00.0#"</code> -> 1,234.56 2907 * <P>This means a minimum of 2 integer digits, 1 fraction digit, and 2908 * a maximum of 2 fraction digits. 2909 * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in 2910 * parentheses. 2911 * <p>In negative patterns, the minimum and maximum counts are ignored; 2912 * these are presumed to be set in the positive pattern. 2913 * 2914 * @exception NullPointerException if <code>pattern</code> is null 2915 * @exception IllegalArgumentException if the given pattern is invalid. 2916 */ 2917 public void applyPattern(String pattern) { 2918 applyPattern(pattern, false); 2919 } 2920 2921 /** 2922 * Apply the given pattern to this Format object. The pattern 2923 * is assumed to be in a localized notation. A pattern is a 2924 * short-hand specification for the various formatting properties. 2925 * These properties can also be changed individually through the 2926 * various setter methods. 2927 * <p> 2928 * There is no limit to integer digits set 2929 * by this routine, since that is the typical end-user desire; 2930 * use setMaximumInteger if you want to set a real value. 2931 * For negative numbers, use a second pattern, separated by a semicolon 2932 * <P>Example <code>"#,#00.0#"</code> -> 1,234.56 2933 * <P>This means a minimum of 2 integer digits, 1 fraction digit, and 2934 * a maximum of 2 fraction digits. 2935 * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in 2936 * parentheses. 2937 * <p>In negative patterns, the minimum and maximum counts are ignored; 2938 * these are presumed to be set in the positive pattern. 2939 * 2940 * @exception NullPointerException if <code>pattern</code> is null 2941 * @exception IllegalArgumentException if the given pattern is invalid. 2942 */ 2943 public void applyLocalizedPattern(String pattern) { 2944 applyPattern(pattern, true); 2945 } 2946 2947 /** 2948 * Does the real work of applying a pattern. 2949 */ 2950 private void applyPattern(String pattern, boolean localized) { 2951 char zeroDigit = PATTERN_ZERO_DIGIT; 2952 char groupingSeparator = PATTERN_GROUPING_SEPARATOR; 2953 char decimalSeparator = PATTERN_DECIMAL_SEPARATOR; 2954 char percent = PATTERN_PERCENT; 2955 char perMill = PATTERN_PER_MILLE; 2956 char digit = PATTERN_DIGIT; 2957 char separator = PATTERN_SEPARATOR; 2958 String exponent = PATTERN_EXPONENT; 2959 char minus = PATTERN_MINUS; 2960 if (localized) { 2961 zeroDigit = symbols.getZeroDigit(); 2962 groupingSeparator = symbols.getGroupingSeparator(); 2963 decimalSeparator = symbols.getDecimalSeparator(); 2964 percent = symbols.getPercent(); 2965 perMill = symbols.getPerMill(); 2966 digit = symbols.getDigit(); 2967 separator = symbols.getPatternSeparator(); 2968 exponent = symbols.getExponentSeparator(); 2969 minus = symbols.getMinusSign(); 2970 } 2971 boolean gotNegative = false; 2972 decimalSeparatorAlwaysShown = false; 2973 isCurrencyFormat = false; 2974 useExponentialNotation = false; 2975 2976 // Two variables are used to record the subrange of the pattern 2977 // occupied by phase 1. This is used during the processing of the 2978 // second pattern (the one representing negative numbers) to ensure 2979 // that no deviation exists in phase 1 between the two patterns. 2980 int phaseOneStart = 0; 2981 int phaseOneLength = 0; 2982 2983 int start = 0; 2984 for (int j = 1; j >= 0 && start < pattern.length(); --j) { 2985 boolean inQuote = false; 2986 StringBuffer prefix = new StringBuffer(); 2987 StringBuffer suffix = new StringBuffer(); 2988 int decimalPos = -1; 2989 int multiplier = 1; 2990 int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0; 2991 byte groupingCount = -1; 2992 2993 // The phase ranges from 0 to 2. Phase 0 is the prefix. Phase 1 is 2994 // the section of the pattern with digits, decimal separator, 2995 // grouping characters. Phase 2 is the suffix. In phases 0 and 2, 2996 // percent, per mille, and currency symbols are recognized and 2997 // translated. The separation of the characters into phases is 2998 // strictly enforced; if phase 1 characters are to appear in the 2999 // suffix, for example, they must be quoted. 3000 int phase = 0; 3001 3002 // The affix is either the prefix or the suffix. 3003 StringBuffer affix = prefix; 3004 3005 for (int pos = start; pos < pattern.length(); ++pos) { 3006 char ch = pattern.charAt(pos); 3007 switch (phase) { 3008 case 0: 3009 case 2: 3010 // Process the prefix / suffix characters 3011 if (inQuote) { 3012 // A quote within quotes indicates either the closing 3013 // quote or two quotes, which is a quote literal. That 3014 // is, we have the second quote in 'do' or 'don''t'. 3015 if (ch == QUOTE) { 3016 if ((pos+1) < pattern.length() && 3017 pattern.charAt(pos+1) == QUOTE) { 3018 ++pos; 3019 affix.append("''"); // 'don''t' 3020 } else { 3021 inQuote = false; // 'do' 3022 } 3023 continue; 3024 } 3025 } else { 3026 // Process unquoted characters seen in prefix or suffix 3027 // phase. 3028 if (ch == digit || 3029 ch == zeroDigit || 3030 ch == groupingSeparator || 3031 ch == decimalSeparator) { 3032 phase = 1; 3033 if (j == 1) { 3034 phaseOneStart = pos; 3035 } 3036 --pos; // Reprocess this character 3037 continue; 3038 } else if (ch == CURRENCY_SIGN) { 3039 // Use lookahead to determine if the currency sign 3040 // is doubled or not. 3041 boolean doubled = (pos + 1) < pattern.length() && 3042 pattern.charAt(pos + 1) == CURRENCY_SIGN; 3043 if (doubled) { // Skip over the doubled character 3044 ++pos; 3045 } 3046 isCurrencyFormat = true; 3047 affix.append(doubled ? "'\u00A4\u00A4" : "'\u00A4"); 3048 continue; 3049 } else if (ch == QUOTE) { 3050 // A quote outside quotes indicates either the 3051 // opening quote or two quotes, which is a quote 3052 // literal. That is, we have the first quote in 'do' 3053 // or o''clock. 3054 if (ch == QUOTE) { 3055 if ((pos+1) < pattern.length() && 3056 pattern.charAt(pos+1) == QUOTE) { 3057 ++pos; 3058 affix.append("''"); // o''clock 3059 } else { 3060 inQuote = true; // 'do' 3061 } 3062 continue; 3063 } 3064 } else if (ch == separator) { 3065 // Don't allow separators before we see digit 3066 // characters of phase 1, and don't allow separators 3067 // in the second pattern (j == 0). 3068 if (phase == 0 || j == 0) { 3069 throw new IllegalArgumentException("Unquoted special character '" + 3070 ch + "' in pattern \"" + pattern + '"'); 3071 } 3072 start = pos + 1; 3073 pos = pattern.length(); 3074 continue; 3075 } 3076 3077 // Next handle characters which are appended directly. 3078 else if (ch == percent) { 3079 if (multiplier != 1) { 3080 throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" + 3081 pattern + '"'); 3082 } 3083 multiplier = 100; 3084 affix.append("'%"); 3085 continue; 3086 } else if (ch == perMill) { 3087 if (multiplier != 1) { 3088 throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" + 3089 pattern + '"'); 3090 } 3091 multiplier = 1000; 3092 affix.append("'\u2030"); 3093 continue; 3094 } else if (ch == minus) { 3095 affix.append("'-"); 3096 continue; 3097 } 3098 } 3099 // Note that if we are within quotes, or if this is an 3100 // unquoted, non-special character, then we usually fall 3101 // through to here. 3102 affix.append(ch); 3103 break; 3104 3105 case 1: 3106 // Phase one must be identical in the two sub-patterns. We 3107 // enforce this by doing a direct comparison. While 3108 // processing the first sub-pattern, we just record its 3109 // length. While processing the second, we compare 3110 // characters. 3111 if (j == 1) { 3112 ++phaseOneLength; 3113 } else { 3114 if (--phaseOneLength == 0) { 3115 phase = 2; 3116 affix = suffix; 3117 } 3118 continue; 3119 } 3120 3121 // Process the digits, decimal, and grouping characters. We 3122 // record five pieces of information. We expect the digits 3123 // to occur in the pattern ####0000.####, and we record the 3124 // number of left digits, zero (central) digits, and right 3125 // digits. The position of the last grouping character is 3126 // recorded (should be somewhere within the first two blocks 3127 // of characters), as is the position of the decimal point, 3128 // if any (should be in the zero digits). If there is no 3129 // decimal point, then there should be no right digits. 3130 if (ch == digit) { 3131 if (zeroDigitCount > 0) { 3132 ++digitRightCount; 3133 } else { 3134 ++digitLeftCount; 3135 } 3136 if (groupingCount >= 0 && decimalPos < 0) { 3137 ++groupingCount; 3138 } 3139 } else if (ch == zeroDigit) { 3140 if (digitRightCount > 0) { 3141 throw new IllegalArgumentException("Unexpected '0' in pattern \"" + 3142 pattern + '"'); 3143 } 3144 ++zeroDigitCount; 3145 if (groupingCount >= 0 && decimalPos < 0) { 3146 ++groupingCount; 3147 } 3148 } else if (ch == groupingSeparator) { 3149 groupingCount = 0; 3150 } else if (ch == decimalSeparator) { 3151 if (decimalPos >= 0) { 3152 throw new IllegalArgumentException("Multiple decimal separators in pattern \"" + 3153 pattern + '"'); 3154 } 3155 decimalPos = digitLeftCount + zeroDigitCount + digitRightCount; 3156 } else if (pattern.regionMatches(pos, exponent, 0, exponent.length())){ 3157 if (useExponentialNotation) { 3158 throw new IllegalArgumentException("Multiple exponential " + 3159 "symbols in pattern \"" + pattern + '"'); 3160 } 3161 useExponentialNotation = true; 3162 minExponentDigits = 0; 3163 3164 // Use lookahead to parse out the exponential part 3165 // of the pattern, then jump into phase 2. 3166 pos = pos+exponent.length(); 3167 while (pos < pattern.length() && 3168 pattern.charAt(pos) == zeroDigit) { 3169 ++minExponentDigits; 3170 ++phaseOneLength; 3171 ++pos; 3172 } 3173 3174 if ((digitLeftCount + zeroDigitCount) < 1 || 3175 minExponentDigits < 1) { 3176 throw new IllegalArgumentException("Malformed exponential " + 3177 "pattern \"" + pattern + '"'); 3178 } 3179 3180 // Transition to phase 2 3181 phase = 2; 3182 affix = suffix; 3183 --pos; 3184 continue; 3185 } else { 3186 phase = 2; 3187 affix = suffix; 3188 --pos; 3189 --phaseOneLength; 3190 continue; 3191 } 3192 break; 3193 } 3194 } 3195 3196 // Handle patterns with no '0' pattern character. These patterns 3197 // are legal, but must be interpreted. "##.###" -> "#0.###". 3198 // ".###" -> ".0##". 3199 /* We allow patterns of the form "####" to produce a zeroDigitCount 3200 * of zero (got that?); although this seems like it might make it 3201 * possible for format() to produce empty strings, format() checks 3202 * for this condition and outputs a zero digit in this situation. 3203 * Having a zeroDigitCount of zero yields a minimum integer digits 3204 * of zero, which allows proper round-trip patterns. That is, we 3205 * don't want "#" to become "#0" when toPattern() is called (even 3206 * though that's what it really is, semantically). 3207 */ 3208 if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) { 3209 // Handle "###.###" and "###." and ".###" 3210 int n = decimalPos; 3211 if (n == 0) { // Handle ".###" 3212 ++n; 3213 } 3214 digitRightCount = digitLeftCount - n; 3215 digitLeftCount = n - 1; 3216 zeroDigitCount = 1; 3217 } 3218 3219 // Do syntax checking on the digits. 3220 if ((decimalPos < 0 && digitRightCount > 0) || 3221 (decimalPos >= 0 && (decimalPos < digitLeftCount || 3222 decimalPos > (digitLeftCount + zeroDigitCount))) || 3223 groupingCount == 0 || inQuote) { 3224 throw new IllegalArgumentException("Malformed pattern \"" + 3225 pattern + '"'); 3226 } 3227 3228 if (j == 1) { 3229 posPrefixPattern = prefix.toString(); 3230 posSuffixPattern = suffix.toString(); 3231 negPrefixPattern = posPrefixPattern; // assume these for now 3232 negSuffixPattern = posSuffixPattern; 3233 int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount; 3234 /* The effectiveDecimalPos is the position the decimal is at or 3235 * would be at if there is no decimal. Note that if decimalPos<0, 3236 * then digitTotalCount == digitLeftCount + zeroDigitCount. 3237 */ 3238 int effectiveDecimalPos = decimalPos >= 0 ? 3239 decimalPos : digitTotalCount; 3240 setMinimumIntegerDigits(effectiveDecimalPos - digitLeftCount); 3241 setMaximumIntegerDigits(useExponentialNotation ? 3242 digitLeftCount + getMinimumIntegerDigits() : 3243 MAXIMUM_INTEGER_DIGITS); 3244 setMaximumFractionDigits(decimalPos >= 0 ? 3245 (digitTotalCount - decimalPos) : 0); 3246 setMinimumFractionDigits(decimalPos >= 0 ? 3247 (digitLeftCount + zeroDigitCount - decimalPos) : 0); 3248 setGroupingUsed(groupingCount > 0); 3249 this.groupingSize = (groupingCount > 0) ? groupingCount : 0; 3250 this.multiplier = multiplier; 3251 setDecimalSeparatorAlwaysShown(decimalPos == 0 || 3252 decimalPos == digitTotalCount); 3253 } else { 3254 negPrefixPattern = prefix.toString(); 3255 negSuffixPattern = suffix.toString(); 3256 gotNegative = true; 3257 } 3258 } 3259 3260 if (pattern.length() == 0) { 3261 posPrefixPattern = posSuffixPattern = ""; 3262 setMinimumIntegerDigits(0); 3263 setMaximumIntegerDigits(MAXIMUM_INTEGER_DIGITS); 3264 setMinimumFractionDigits(0); 3265 setMaximumFractionDigits(MAXIMUM_FRACTION_DIGITS); 3266 } 3267 3268 // If there was no negative pattern, or if the negative pattern is 3269 // identical to the positive pattern, then prepend the minus sign to 3270 // the positive pattern to form the negative pattern. 3271 if (!gotNegative || 3272 (negPrefixPattern.equals(posPrefixPattern) 3273 && negSuffixPattern.equals(posSuffixPattern))) { 3274 negSuffixPattern = posSuffixPattern; 3275 negPrefixPattern = "'-" + posPrefixPattern; 3276 } 3277 3278 expandAffixes(); 3279 } 3280 3281 /** 3282 * Sets the maximum number of digits allowed in the integer portion of a 3283 * number. 3284 * For formatting numbers other than <code>BigInteger</code> and 3285 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and 3286 * 309 is used. Negative input values are replaced with 0. 3287 * @see NumberFormat#setMaximumIntegerDigits 3288 */ 3289 public void setMaximumIntegerDigits(int newValue) { 3290 maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS); 3291 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? 3292 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits); 3293 if (minimumIntegerDigits > maximumIntegerDigits) { 3294 minimumIntegerDigits = maximumIntegerDigits; 3295 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? 3296 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits); 3297 } 3298 fastPathCheckNeeded = true; 3299 } 3300 3301 /** 3302 * Sets the minimum number of digits allowed in the integer portion of a 3303 * number. 3304 * For formatting numbers other than <code>BigInteger</code> and 3305 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and 3306 * 309 is used. Negative input values are replaced with 0. 3307 * @see NumberFormat#setMinimumIntegerDigits 3308 */ 3309 public void setMinimumIntegerDigits(int newValue) { 3310 minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS); 3311 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? 3312 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits); 3313 if (minimumIntegerDigits > maximumIntegerDigits) { 3314 maximumIntegerDigits = minimumIntegerDigits; 3315 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? 3316 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits); 3317 } 3318 fastPathCheckNeeded = true; 3319 } 3320 3321 /** 3322 * Sets the maximum number of digits allowed in the fraction portion of a 3323 * number. 3324 * For formatting numbers other than <code>BigInteger</code> and 3325 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and 3326 * 340 is used. Negative input values are replaced with 0. 3327 * @see NumberFormat#setMaximumFractionDigits 3328 */ 3329 public void setMaximumFractionDigits(int newValue) { 3330 maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS); 3331 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ? 3332 DOUBLE_FRACTION_DIGITS : maximumFractionDigits); 3333 if (minimumFractionDigits > maximumFractionDigits) { 3334 minimumFractionDigits = maximumFractionDigits; 3335 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ? 3336 DOUBLE_FRACTION_DIGITS : minimumFractionDigits); 3337 } 3338 fastPathCheckNeeded = true; 3339 } 3340 3341 /** 3342 * Sets the minimum number of digits allowed in the fraction portion of a 3343 * number. 3344 * For formatting numbers other than <code>BigInteger</code> and 3345 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and 3346 * 340 is used. Negative input values are replaced with 0. 3347 * @see NumberFormat#setMinimumFractionDigits 3348 */ 3349 public void setMinimumFractionDigits(int newValue) { 3350 minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS); 3351 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ? 3352 DOUBLE_FRACTION_DIGITS : minimumFractionDigits); 3353 if (minimumFractionDigits > maximumFractionDigits) { 3354 maximumFractionDigits = minimumFractionDigits; 3355 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ? 3356 DOUBLE_FRACTION_DIGITS : maximumFractionDigits); 3357 } 3358 fastPathCheckNeeded = true; 3359 } 3360 3361 /** 3362 * Gets the maximum number of digits allowed in the integer portion of a 3363 * number. 3364 * For formatting numbers other than <code>BigInteger</code> and 3365 * <code>BigDecimal</code> objects, the lower of the return value and 3366 * 309 is used. 3367 * @see #setMaximumIntegerDigits 3368 */ 3369 public int getMaximumIntegerDigits() { 3370 return maximumIntegerDigits; 3371 } 3372 3373 /** 3374 * Gets the minimum number of digits allowed in the integer portion of a 3375 * number. 3376 * For formatting numbers other than <code>BigInteger</code> and 3377 * <code>BigDecimal</code> objects, the lower of the return value and 3378 * 309 is used. 3379 * @see #setMinimumIntegerDigits 3380 */ 3381 public int getMinimumIntegerDigits() { 3382 return minimumIntegerDigits; 3383 } 3384 3385 /** 3386 * Gets the maximum number of digits allowed in the fraction portion of a 3387 * number. 3388 * For formatting numbers other than <code>BigInteger</code> and 3389 * <code>BigDecimal</code> objects, the lower of the return value and 3390 * 340 is used. 3391 * @see #setMaximumFractionDigits 3392 */ 3393 public int getMaximumFractionDigits() { 3394 return maximumFractionDigits; 3395 } 3396 3397 /** 3398 * Gets the minimum number of digits allowed in the fraction portion of a 3399 * number. 3400 * For formatting numbers other than <code>BigInteger</code> and 3401 * <code>BigDecimal</code> objects, the lower of the return value and 3402 * 340 is used. 3403 * @see #setMinimumFractionDigits 3404 */ 3405 public int getMinimumFractionDigits() { 3406 return minimumFractionDigits; 3407 } 3408 3409 /** 3410 * Gets the currency used by this decimal format when formatting 3411 * currency values. 3412 * The currency is obtained by calling 3413 * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency} 3414 * on this number format's symbols. 3415 * 3416 * @return the currency used by this decimal format, or <code>null</code> 3417 * @since 1.4 3418 */ 3419 public Currency getCurrency() { 3420 return symbols.getCurrency(); 3421 } 3422 3423 /** 3424 * Sets the currency used by this number format when formatting 3425 * currency values. This does not update the minimum or maximum 3426 * number of fraction digits used by the number format. 3427 * The currency is set by calling 3428 * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency} 3429 * on this number format's symbols. 3430 * 3431 * @param currency the new currency to be used by this decimal format 3432 * @exception NullPointerException if <code>currency</code> is null 3433 * @since 1.4 3434 */ 3435 public void setCurrency(Currency currency) { 3436 if (currency != symbols.getCurrency()) { 3437 symbols.setCurrency(currency); 3438 if (isCurrencyFormat) { 3439 expandAffixes(); 3440 } 3441 } 3442 fastPathCheckNeeded = true; 3443 } 3444 3445 /** 3446 * Gets the {@link java.math.RoundingMode} used in this DecimalFormat. 3447 * 3448 * @return The <code>RoundingMode</code> used for this DecimalFormat. 3449 * @see #setRoundingMode(RoundingMode) 3450 * @since 1.6 3451 */ 3452 public RoundingMode getRoundingMode() { 3453 return roundingMode; 3454 } 3455 3456 /** 3457 * Sets the {@link java.math.RoundingMode} used in this DecimalFormat. 3458 * 3459 * @param roundingMode The <code>RoundingMode</code> to be used 3460 * @see #getRoundingMode() 3461 * @exception NullPointerException if <code>roundingMode</code> is null. 3462 * @since 1.6 3463 */ 3464 public void setRoundingMode(RoundingMode roundingMode) { 3465 if (roundingMode == null) { 3466 throw new NullPointerException(); 3467 } 3468 3469 this.roundingMode = roundingMode; 3470 digitList.setRoundingMode(roundingMode); 3471 fastPathCheckNeeded = true; 3472 } 3473 3474 /** 3475 * Adjusts the minimum and maximum fraction digits to values that 3476 * are reasonable for the currency's default fraction digits. 3477 */ 3478 void adjustForCurrencyDefaultFractionDigits() { 3479 Currency currency = symbols.getCurrency(); 3480 if (currency == null) { 3481 try { 3482 currency = Currency.getInstance(symbols.getInternationalCurrencySymbol()); 3483 } catch (IllegalArgumentException e) { 3484 } 3485 } 3486 if (currency != null) { 3487 int digits = currency.getDefaultFractionDigits(); 3488 if (digits != -1) { 3489 int oldMinDigits = getMinimumFractionDigits(); 3490 // Common patterns are "#.##", "#.00", "#". 3491 // Try to adjust all of them in a reasonable way. 3492 if (oldMinDigits == getMaximumFractionDigits()) { 3493 setMinimumFractionDigits(digits); 3494 setMaximumFractionDigits(digits); 3495 } else { 3496 setMinimumFractionDigits(Math.min(digits, oldMinDigits)); 3497 setMaximumFractionDigits(digits); 3498 } 3499 } 3500 } 3501 } 3502 3503 /** 3504 * Reads the default serializable fields from the stream and performs 3505 * validations and adjustments for older serialized versions. The 3506 * validations and adjustments are: 3507 * <ol> 3508 * <li> 3509 * Verify that the superclass's digit count fields correctly reflect 3510 * the limits imposed on formatting numbers other than 3511 * <code>BigInteger</code> and <code>BigDecimal</code> objects. These 3512 * limits are stored in the superclass for serialization compatibility 3513 * with older versions, while the limits for <code>BigInteger</code> and 3514 * <code>BigDecimal</code> objects are kept in this class. 3515 * If, in the superclass, the minimum or maximum integer digit count is 3516 * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or 3517 * maximum fraction digit count is larger than 3518 * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid 3519 * and this method throws an <code>InvalidObjectException</code>. 3520 * <li> 3521 * If <code>serialVersionOnStream</code> is less than 4, initialize 3522 * <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN 3523 * RoundingMode.HALF_EVEN}. This field is new with version 4. 3524 * <li> 3525 * If <code>serialVersionOnStream</code> is less than 3, then call 3526 * the setters for the minimum and maximum integer and fraction digits with 3527 * the values of the corresponding superclass getters to initialize the 3528 * fields in this class. The fields in this class are new with version 3. 3529 * <li> 3530 * If <code>serialVersionOnStream</code> is less than 1, indicating that 3531 * the stream was written by JDK 1.1, initialize 3532 * <code>useExponentialNotation</code> 3533 * to false, since it was not present in JDK 1.1. 3534 * <li> 3535 * Set <code>serialVersionOnStream</code> to the maximum allowed value so 3536 * that default serialization will work properly if this object is streamed 3537 * out again. 3538 * </ol> 3539 * 3540 * <p>Stream versions older than 2 will not have the affix pattern variables 3541 * <code>posPrefixPattern</code> etc. As a result, they will be initialized 3542 * to <code>null</code>, which means the affix strings will be taken as 3543 * literal values. This is exactly what we want, since that corresponds to 3544 * the pre-version-2 behavior. 3545 */ 3546 private void readObject(ObjectInputStream stream) 3547 throws IOException, ClassNotFoundException 3548 { 3549 stream.defaultReadObject(); 3550 digitList = new DigitList(); 3551 3552 if (serialVersionOnStream < 4) { 3553 setRoundingMode(RoundingMode.HALF_EVEN); 3554 } 3555 // We only need to check the maximum counts because NumberFormat 3556 // .readObject has already ensured that the maximum is greater than the 3557 // minimum count. 3558 if (super.getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS || 3559 super.getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) { 3560 throw new InvalidObjectException("Digit count out of range"); 3561 } 3562 if (serialVersionOnStream < 3) { 3563 setMaximumIntegerDigits(super.getMaximumIntegerDigits()); 3564 setMinimumIntegerDigits(super.getMinimumIntegerDigits()); 3565 setMaximumFractionDigits(super.getMaximumFractionDigits()); 3566 setMinimumFractionDigits(super.getMinimumFractionDigits()); 3567 } 3568 if (serialVersionOnStream < 1) { 3569 // Didn't have exponential fields 3570 useExponentialNotation = false; 3571 } 3572 serialVersionOnStream = currentSerialVersion; 3573 } 3574 3575 //---------------------------------------------------------------------- 3576 // INSTANCE VARIABLES 3577 //---------------------------------------------------------------------- 3578 3579 private transient DigitList digitList = new DigitList(); 3580 3581 /** 3582 * The symbol used as a prefix when formatting positive numbers, e.g. "+". 3583 * 3584 * @serial 3585 * @see #getPositivePrefix 3586 */ 3587 private String positivePrefix = ""; 3588 3589 /** 3590 * The symbol used as a suffix when formatting positive numbers. 3591 * This is often an empty string. 3592 * 3593 * @serial 3594 * @see #getPositiveSuffix 3595 */ 3596 private String positiveSuffix = ""; 3597 3598 /** 3599 * The symbol used as a prefix when formatting negative numbers, e.g. "-". 3600 * 3601 * @serial 3602 * @see #getNegativePrefix 3603 */ 3604 private String negativePrefix = "-"; 3605 3606 /** 3607 * The symbol used as a suffix when formatting negative numbers. 3608 * This is often an empty string. 3609 * 3610 * @serial 3611 * @see #getNegativeSuffix 3612 */ 3613 private String negativeSuffix = ""; 3614 3615 /** 3616 * The prefix pattern for non-negative numbers. This variable corresponds 3617 * to <code>positivePrefix</code>. 3618 * 3619 * <p>This pattern is expanded by the method <code>expandAffix()</code> to 3620 * <code>positivePrefix</code> to update the latter to reflect changes in 3621 * <code>symbols</code>. If this variable is <code>null</code> then 3622 * <code>positivePrefix</code> is taken as a literal value that does not 3623 * change when <code>symbols</code> changes. This variable is always 3624 * <code>null</code> for <code>DecimalFormat</code> objects older than 3625 * stream version 2 restored from stream. 3626 * 3627 * @serial 3628 * @since 1.3 3629 */ 3630 private String posPrefixPattern; 3631 3632 /** 3633 * The suffix pattern for non-negative numbers. This variable corresponds 3634 * to <code>positiveSuffix</code>. This variable is analogous to 3635 * <code>posPrefixPattern</code>; see that variable for further 3636 * documentation. 3637 * 3638 * @serial 3639 * @since 1.3 3640 */ 3641 private String posSuffixPattern; 3642 3643 /** 3644 * The prefix pattern for negative numbers. This variable corresponds 3645 * to <code>negativePrefix</code>. This variable is analogous to 3646 * <code>posPrefixPattern</code>; see that variable for further 3647 * documentation. 3648 * 3649 * @serial 3650 * @since 1.3 3651 */ 3652 private String negPrefixPattern; 3653 3654 /** 3655 * The suffix pattern for negative numbers. This variable corresponds 3656 * to <code>negativeSuffix</code>. This variable is analogous to 3657 * <code>posPrefixPattern</code>; see that variable for further 3658 * documentation. 3659 * 3660 * @serial 3661 * @since 1.3 3662 */ 3663 private String negSuffixPattern; 3664 3665 /** 3666 * The multiplier for use in percent, per mille, etc. 3667 * 3668 * @serial 3669 * @see #getMultiplier 3670 */ 3671 private int multiplier = 1; 3672 3673 /** 3674 * The number of digits between grouping separators in the integer 3675 * portion of a number. Must be greater than 0 if 3676 * <code>NumberFormat.groupingUsed</code> is true. 3677 * 3678 * @serial 3679 * @see #getGroupingSize 3680 * @see java.text.NumberFormat#isGroupingUsed 3681 */ 3682 private byte groupingSize = 3; // invariant, > 0 if useThousands 3683 3684 /** 3685 * If true, forces the decimal separator to always appear in a formatted 3686 * number, even if the fractional part of the number is zero. 3687 * 3688 * @serial 3689 * @see #isDecimalSeparatorAlwaysShown 3690 */ 3691 private boolean decimalSeparatorAlwaysShown = false; 3692 3693 /** 3694 * If true, parse returns BigDecimal wherever possible. 3695 * 3696 * @serial 3697 * @see #isParseBigDecimal 3698 * @since 1.5 3699 */ 3700 private boolean parseBigDecimal = false; 3701 3702 3703 /** 3704 * True if this object represents a currency format. This determines 3705 * whether the monetary decimal separator is used instead of the normal one. 3706 */ 3707 private transient boolean isCurrencyFormat = false; 3708 3709 /** 3710 * The <code>DecimalFormatSymbols</code> object used by this format. 3711 * It contains the symbols used to format numbers, e.g. the grouping separator, 3712 * decimal separator, and so on. 3713 * 3714 * @serial 3715 * @see #setDecimalFormatSymbols 3716 * @see java.text.DecimalFormatSymbols 3717 */ 3718 private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols(); 3719 3720 /** 3721 * True to force the use of exponential (i.e. scientific) notation when formatting 3722 * numbers. 3723 * 3724 * @serial 3725 * @since 1.2 3726 */ 3727 private boolean useExponentialNotation; // Newly persistent in the Java 2 platform v.1.2 3728 3729 /** 3730 * FieldPositions describing the positive prefix String. This is 3731 * lazily created. Use <code>getPositivePrefixFieldPositions</code> 3732 * when needed. 3733 */ 3734 private transient FieldPosition[] positivePrefixFieldPositions; 3735 3736 /** 3737 * FieldPositions describing the positive suffix String. This is 3738 * lazily created. Use <code>getPositiveSuffixFieldPositions</code> 3739 * when needed. 3740 */ 3741 private transient FieldPosition[] positiveSuffixFieldPositions; 3742 3743 /** 3744 * FieldPositions describing the negative prefix String. This is 3745 * lazily created. Use <code>getNegativePrefixFieldPositions</code> 3746 * when needed. 3747 */ 3748 private transient FieldPosition[] negativePrefixFieldPositions; 3749 3750 /** 3751 * FieldPositions describing the negative suffix String. This is 3752 * lazily created. Use <code>getNegativeSuffixFieldPositions</code> 3753 * when needed. 3754 */ 3755 private transient FieldPosition[] negativeSuffixFieldPositions; 3756 3757 /** 3758 * The minimum number of digits used to display the exponent when a number is 3759 * formatted in exponential notation. This field is ignored if 3760 * <code>useExponentialNotation</code> is not true. 3761 * 3762 * @serial 3763 * @since 1.2 3764 */ 3765 private byte minExponentDigits; // Newly persistent in the Java 2 platform v.1.2 3766 3767 /** 3768 * The maximum number of digits allowed in the integer portion of a 3769 * <code>BigInteger</code> or <code>BigDecimal</code> number. 3770 * <code>maximumIntegerDigits</code> must be greater than or equal to 3771 * <code>minimumIntegerDigits</code>. 3772 * 3773 * @serial 3774 * @see #getMaximumIntegerDigits 3775 * @since 1.5 3776 */ 3777 private int maximumIntegerDigits = super.getMaximumIntegerDigits(); 3778 3779 /** 3780 * The minimum number of digits allowed in the integer portion of a 3781 * <code>BigInteger</code> or <code>BigDecimal</code> number. 3782 * <code>minimumIntegerDigits</code> must be less than or equal to 3783 * <code>maximumIntegerDigits</code>. 3784 * 3785 * @serial 3786 * @see #getMinimumIntegerDigits 3787 * @since 1.5 3788 */ 3789 private int minimumIntegerDigits = super.getMinimumIntegerDigits(); 3790 3791 /** 3792 * The maximum number of digits allowed in the fractional portion of a 3793 * <code>BigInteger</code> or <code>BigDecimal</code> number. 3794 * <code>maximumFractionDigits</code> must be greater than or equal to 3795 * <code>minimumFractionDigits</code>. 3796 * 3797 * @serial 3798 * @see #getMaximumFractionDigits 3799 * @since 1.5 3800 */ 3801 private int maximumFractionDigits = super.getMaximumFractionDigits(); 3802 3803 /** 3804 * The minimum number of digits allowed in the fractional portion of a 3805 * <code>BigInteger</code> or <code>BigDecimal</code> number. 3806 * <code>minimumFractionDigits</code> must be less than or equal to 3807 * <code>maximumFractionDigits</code>. 3808 * 3809 * @serial 3810 * @see #getMinimumFractionDigits 3811 * @since 1.5 3812 */ 3813 private int minimumFractionDigits = super.getMinimumFractionDigits(); 3814 3815 /** 3816 * The {@link java.math.RoundingMode} used in this DecimalFormat. 3817 * 3818 * @serial 3819 * @since 1.6 3820 */ 3821 private RoundingMode roundingMode = RoundingMode.HALF_EVEN; 3822 3823 // ------ DecimalFormat fields for Fast Path for double algorithm ------ 3824 3825 // --- Utility temporary fields only used in fast-path algorithms and shared by several methods. 3826 3827 /* Flag field for "all nine" integers like 99999999 (see StringSize). */ 3828 private boolean isAllNines = false; 3829 3830 /* The fractional part of double that is past 2 (currency) or 3 fractional digits. */ 3831 private double remainingFractionalPart = 0.0d; 3832 3833 /* The last valid index in the buffer containing the formated result. */ 3834 private int lastUsedIndex = 0; 3835 3836 /* Number of groups needed in formatting the double (see intStringSize and fastDoubleFormat). */ 3837 private int nbGroupsNeeded = 0; 3838 3839 // --- New state fields of DecimalFormat, necessary for fast-path. 3840 3841 /* The format-fast-path status of the instance. */ 3842 private boolean isFastPath = false; 3843 3844 /* Flag stating need of check fast path status on next format call. */ 3845 private boolean fastPathCheckNeeded = true; 3846 3847 /* Preinstantiated digits buffer templates for perf purpose (see checkAndSetFastPathStatus). */ 3848 private char[] positiveFastPathContainer; 3849 private char[] negativeFastPathContainer; 3850 3851 /* Rounding bounds assigned at initialization (see checkAndSetFastPathStatus). */ 3852 private double[] safeMinusRoundingBounds = null; 3853 private double[] safeMajorRoundingBounds = null; 3854 3855 /* Suffixes recorded as char array (see checkAndSetFastPathStatus). */ 3856 private boolean isSuffixPresent; 3857 private char[] charsPositiveSuffix; 3858 private char[] charsNegativeSuffix; 3859 3860 /* Difference between locale zero and default zero representation (see checkAndSetFastPathStatus). */ 3861 private int zeroDelta; 3862 3863 /* Locale char for grouping separator (see checkAndSetFastPathStatus). */ 3864 private char groupingChar; 3865 3866 /* Locale char for decimal separator (see checkAndSetFastPathStatus). */ 3867 private char decimalSeparatorChar; 3868 3869 //---------------------------------------------------------------------- 3870 3871 static final int currentSerialVersion = 4; 3872 3873 /** 3874 * The internal serial version which says which version was written. 3875 * Possible values are: 3876 * <ul> 3877 * <li><b>0</b> (default): versions before the Java 2 platform v1.2 3878 * <li><b>1</b>: version for 1.2, which includes the two new fields 3879 * <code>useExponentialNotation</code> and 3880 * <code>minExponentDigits</code>. 3881 * <li><b>2</b>: version for 1.3 and later, which adds four new fields: 3882 * <code>posPrefixPattern</code>, <code>posSuffixPattern</code>, 3883 * <code>negPrefixPattern</code>, and <code>negSuffixPattern</code>. 3884 * <li><b>3</b>: version for 1.5 and later, which adds five new fields: 3885 * <code>maximumIntegerDigits</code>, 3886 * <code>minimumIntegerDigits</code>, 3887 * <code>maximumFractionDigits</code>, 3888 * <code>minimumFractionDigits</code>, and 3889 * <code>parseBigDecimal</code>. 3890 * <li><b>4</b>: version for 1.6 and later, which adds one new field: 3891 * <code>roundingMode</code>. 3892 * </ul> 3893 * @since 1.2 3894 * @serial 3895 */ 3896 private int serialVersionOnStream = currentSerialVersion; 3897 3898 //---------------------------------------------------------------------- 3899 // CONSTANTS 3900 //---------------------------------------------------------------------- 3901 3902 // ------ The Fast Path for double Constants ------ 3903 3904 /* New DecimalFormat static constant */ 3905 private static double MAX_INT_AS_DOUBLE = (double) Integer.MAX_VALUE; 3906 3907 /* Digit arrays for collecting digits. */ 3908 private static final char[] DigitOnes1000 = new char[1000]; 3909 private static final char[] DigitTens1000 = new char[1000]; 3910 private static final char[] DigitHundreds1000 = new char[1000]; 3911 3912 static { 3913 int tenIndex = 0; 3914 int hundredIndex = 0; 3915 char digitOne = '0'; 3916 char digitTen = '0'; 3917 char digitHundred = '0'; 3918 for (int i = 0; i < 1000; i++ ) { 3919 3920 DigitOnes1000[i] = digitOne; 3921 if (digitOne == '9') digitOne = '0'; 3922 else digitOne++; 3923 3924 DigitTens1000[i] = digitTen; 3925 if (i == (tenIndex + 9)) { 3926 tenIndex += 10; 3927 if (digitTen == '9') digitTen = '0'; 3928 else digitTen++; 3929 } 3930 3931 DigitHundreds1000[i] = digitHundred; 3932 if (i == (hundredIndex + 99)) { 3933 digitHundred++; 3934 hundredIndex += 100; 3935 } 3936 } 3937 3938 } 3939 3940 // --- Constant double arrays defining "Undecidable Rounding Interval" 3941 private static final double[] StdSafeMajorRoundingBounds = { 3942 0.5000000000000005, // < 0.001d 3943 0.5000000000000005, // < 0.01d 3944 0.50000000000002, // < 0.1d 3945 0.50000000000006, // < 1.0d 3946 0.5000000000010, // < 10.0d 3947 0.500000000008, // < 100.0d 3948 0.50000000006, // < 1000.0d 3949 0.5000000010, // < 10000.0d 3950 0.500000008, // < 100000.0d 3951 0.50000006, // < 1000000.0d 3952 0.5000010, // < 10000000.0d 3953 0.500008, // < 100000000.0d 3954 0.50006, // < 1000000000.0d 3955 0.5002 // < (2**31) - 1 3956 }; 3957 3958 // SafeMinusRoundingBounds are set as counterpart of SafeMajorRoundingBounds : 3959 // if 0.50000006 for major, then we set to 0.49999994 for minus. 3960 private static final double[] StdSafeMinusRoundingBounds = { 3961 0.4999999999999995, // < 0.001d 3962 0.4999999999999995, // < 0.01d 3963 0.49999999999998, // < 0.1d 3964 0.49999999999994, // < 1.0d 3965 0.4999999999990, // < 10.0d 3966 0.499999999992, // < 100.0d 3967 0.49999999994, // < 1000.0d 3968 0.4999999990, // < 10000.0d 3969 0.499999992, // < 100000.0d 3970 0.49999994, // < 1000000.0d 3971 0.4999990, // < 10000000.0d 3972 0.499992, // < 100000000.0d 3973 0.49994, // < 1000000000.0d 3974 0.4998 // < (2**31) - 1 3975 }; 3976 3977 private static final double[] CurrencySafeMajorRoundingBounds = { 3978 0.50000000000000009, // < 0.01d 3979 0.5000000000000005, // < 0.1d 3980 0.500000000000008, // < 1.0d 3981 0.50000000000009, // < 10.0d 3982 0.5000000000007, // < 100.0d 3983 0.500000000006, // < 1000.0d 3984 0.50000000009, // < 10000.0d 3985 0.5000000007, // < 100000.0d 3986 0.500000006, // < 1000000.0d 3987 0.50000009, // < 10000000.0d 3988 0.5000008, // < 100000000.0d 3989 0.500006, // < 1000000000.0d 3990 0.50002 // < (2**31) - 1 3991 }; 3992 3993 // CurrencySafeMinusRoundingBounds are set as counterpart of CurrencySafeMajorRoundingBounds : 3994 // if 0.50000009 for major, then we set to 0.49999991 for minus. This is because program calculating 3995 private static final double[] CurrencySafeMinusRoundingBounds = { 3996 0.49999999999999991, // < 0.01d 3997 0.4999999999999995, // < 0.1d 3998 0.499999999999992, // < 1.0d 3999 0.49999999999991, // < 10.0d 4000 0.4999999999993, // < 100.0d 4001 0.499999999994, // < 1000.0d 4002 0.49999999991, // < 10000.0d 4003 0.4999999993, // < 100000.0d 4004 0.499999994, // < 1000000.0d 4005 0.49999991, // < 10000000.0d 4006 0.4999992, // < 100000000.0d 4007 0.499994, // < 1000000000.0d 4008 0.49998 // < (2**31) - 1 4009 }; 4010 4011 // Constants for characters used in programmatic (unlocalized) patterns. 4012 private static final char PATTERN_ZERO_DIGIT = '0'; 4013 private static final char PATTERN_GROUPING_SEPARATOR = ','; 4014 private static final char PATTERN_DECIMAL_SEPARATOR = '.'; 4015 private static final char PATTERN_PER_MILLE = '\u2030'; 4016 private static final char PATTERN_PERCENT = '%'; 4017 private static final char PATTERN_DIGIT = '#'; 4018 private static final char PATTERN_SEPARATOR = ';'; 4019 private static final String PATTERN_EXPONENT = "E"; 4020 private static final char PATTERN_MINUS = '-'; 4021 4022 /** 4023 * The CURRENCY_SIGN is the standard Unicode symbol for currency. It 4024 * is used in patterns and substituted with either the currency symbol, 4025 * or if it is doubled, with the international currency symbol. If the 4026 * CURRENCY_SIGN is seen in a pattern, then the decimal separator is 4027 * replaced with the monetary decimal separator. 4028 * 4029 * The CURRENCY_SIGN is not localized. 4030 */ 4031 private static final char CURRENCY_SIGN = '\u00A4'; 4032 4033 private static final char QUOTE = '\''; 4034 4035 private static FieldPosition[] EmptyFieldPositionArray = new FieldPosition[0]; 4036 4037 // Upper limit on integer and fraction digits for a Java double 4038 static final int DOUBLE_INTEGER_DIGITS = 309; 4039 static final int DOUBLE_FRACTION_DIGITS = 340; 4040 4041 // Upper limit on integer and fraction digits for BigDecimal and BigInteger 4042 static final int MAXIMUM_INTEGER_DIGITS = Integer.MAX_VALUE; 4043 static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE; 4044 4045 // Proclaim JDK 1.1 serial compatibility. 4046 static final long serialVersionUID = 864413376551465018L; 4047 4048 /** 4049 * Cache to hold the NumberPattern of a Locale. 4050 */ 4051 private static final ConcurrentMap<Locale, String> cachedLocaleData 4052 = new ConcurrentHashMap<Locale, String>(3); 4053 }