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