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