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