Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/text/DecimalFormat.java
38829 views
/*1* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26* (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved27* (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved28*29* The original version of this source code and documentation is copyrighted30* and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These31* materials are provided under terms of a License Agreement between Taligent32* and Sun. This technology is protected by multiple US and International33* patents. This notice and attribution to Taligent may not be removed.34* Taligent is a registered trademark of Taligent, Inc.35*36*/3738package java.text;3940import java.io.IOException;41import java.io.InvalidObjectException;42import java.io.ObjectInputStream;43import java.math.BigDecimal;44import java.math.BigInteger;45import java.math.RoundingMode;46import java.text.spi.NumberFormatProvider;47import java.util.ArrayList;48import java.util.Currency;49import java.util.Locale;50import java.util.ResourceBundle;51import java.util.concurrent.ConcurrentHashMap;52import java.util.concurrent.ConcurrentMap;53import java.util.concurrent.atomic.AtomicInteger;54import java.util.concurrent.atomic.AtomicLong;55import sun.util.locale.provider.LocaleProviderAdapter;56import sun.util.locale.provider.ResourceBundleBasedAdapter;5758/**59* <code>DecimalFormat</code> is a concrete subclass of60* <code>NumberFormat</code> that formats decimal numbers. It has a variety of61* features designed to make it possible to parse and format numbers in any62* locale, including support for Western, Arabic, and Indic digits. It also63* supports different kinds of numbers, including integers (123), fixed-point64* numbers (123.4), scientific notation (1.23E4), percentages (12%), and65* currency amounts ($123). All of these can be localized.66*67* <p>To obtain a <code>NumberFormat</code> for a specific locale, including the68* default locale, call one of <code>NumberFormat</code>'s factory methods, such69* as <code>getInstance()</code>. In general, do not call the70* <code>DecimalFormat</code> constructors directly, since the71* <code>NumberFormat</code> factory methods may return subclasses other than72* <code>DecimalFormat</code>. If you need to customize the format object, do73* something like this:74*75* <blockquote><pre>76* NumberFormat f = NumberFormat.getInstance(loc);77* if (f instanceof DecimalFormat) {78* ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);79* }80* </pre></blockquote>81*82* <p>A <code>DecimalFormat</code> comprises a <em>pattern</em> and a set of83* <em>symbols</em>. The pattern may be set directly using84* <code>applyPattern()</code>, or indirectly using the API methods. The85* symbols are stored in a <code>DecimalFormatSymbols</code> object. When using86* the <code>NumberFormat</code> factory methods, the pattern and symbols are87* read from localized <code>ResourceBundle</code>s.88*89* <h3>Patterns</h3>90*91* <code>DecimalFormat</code> patterns have the following syntax:92* <blockquote><pre>93* <i>Pattern:</i>94* <i>PositivePattern</i>95* <i>PositivePattern</i> ; <i>NegativePattern</i>96* <i>PositivePattern:</i>97* <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>98* <i>NegativePattern:</i>99* <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>100* <i>Prefix:</i>101* any Unicode characters except \uFFFE, \uFFFF, and special characters102* <i>Suffix:</i>103* any Unicode characters except \uFFFE, \uFFFF, and special characters104* <i>Number:</i>105* <i>Integer</i> <i>Exponent<sub>opt</sub></i>106* <i>Integer</i> . <i>Fraction</i> <i>Exponent<sub>opt</sub></i>107* <i>Integer:</i>108* <i>MinimumInteger</i>109* #110* # <i>Integer</i>111* # , <i>Integer</i>112* <i>MinimumInteger:</i>113* 0114* 0 <i>MinimumInteger</i>115* 0 , <i>MinimumInteger</i>116* <i>Fraction:</i>117* <i>MinimumFraction<sub>opt</sub></i> <i>OptionalFraction<sub>opt</sub></i>118* <i>MinimumFraction:</i>119* 0 <i>MinimumFraction<sub>opt</sub></i>120* <i>OptionalFraction:</i>121* # <i>OptionalFraction<sub>opt</sub></i>122* <i>Exponent:</i>123* E <i>MinimumExponent</i>124* <i>MinimumExponent:</i>125* 0 <i>MinimumExponent<sub>opt</sub></i>126* </pre></blockquote>127*128* <p>A <code>DecimalFormat</code> pattern contains a positive and negative129* subpattern, for example, <code>"#,##0.00;(#,##0.00)"</code>. Each130* subpattern has a prefix, numeric part, and suffix. The negative subpattern131* is optional; if absent, then the positive subpattern prefixed with the132* localized minus sign (<code>'-'</code> in most locales) is used as the133* negative subpattern. That is, <code>"0.00"</code> alone is equivalent to134* <code>"0.00;-0.00"</code>. If there is an explicit negative subpattern, it135* serves only to specify the negative prefix and suffix; the number of digits,136* minimal digits, and other characteristics are all the same as the positive137* pattern. That means that <code>"#,##0.0#;(#)"</code> produces precisely138* the same behavior as <code>"#,##0.0#;(#,##0.0#)"</code>.139*140* <p>The prefixes, suffixes, and various symbols used for infinity, digits,141* thousands separators, decimal separators, etc. may be set to arbitrary142* values, and they will appear properly during formatting. However, care must143* be taken that the symbols and strings do not conflict, or parsing will be144* unreliable. For example, either the positive and negative prefixes or the145* suffixes must be distinct for <code>DecimalFormat.parse()</code> to be able146* to distinguish positive from negative values. (If they are identical, then147* <code>DecimalFormat</code> will behave as if no negative subpattern was148* specified.) Another example is that the decimal separator and thousands149* separator should be distinct characters, or parsing will be impossible.150*151* <p>The grouping separator is commonly used for thousands, but in some152* countries it separates ten-thousands. The grouping size is a constant number153* of digits between the grouping characters, such as 3 for 100,000,000 or 4 for154* 1,0000,0000. If you supply a pattern with multiple grouping characters, the155* interval between the last one and the end of the integer is the one that is156* used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> ==157* <code>"##,####,####"</code>.158*159* <h4>Special Pattern Characters</h4>160*161* <p>Many characters in a pattern are taken literally; they are matched during162* parsing and output unchanged during formatting. Special characters, on the163* other hand, stand for other characters, strings, or classes of characters.164* They must be quoted, unless noted otherwise, if they are to appear in the165* prefix or suffix as literals.166*167* <p>The characters listed here are used in non-localized patterns. Localized168* patterns use the corresponding characters taken from this formatter's169* <code>DecimalFormatSymbols</code> object instead, and these characters lose170* their special status. Two exceptions are the currency sign and quote, which171* are not localized.172*173* <blockquote>174* <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol,175* location, localized, and meaning.">176* <tr style="background-color: rgb(204, 204, 255);">177* <th align=left>Symbol178* <th align=left>Location179* <th align=left>Localized?180* <th align=left>Meaning181* <tr valign=top>182* <td><code>0</code>183* <td>Number184* <td>Yes185* <td>Digit186* <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">187* <td><code>#</code>188* <td>Number189* <td>Yes190* <td>Digit, zero shows as absent191* <tr valign=top>192* <td><code>.</code>193* <td>Number194* <td>Yes195* <td>Decimal separator or monetary decimal separator196* <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">197* <td><code>-</code>198* <td>Number199* <td>Yes200* <td>Minus sign201* <tr valign=top>202* <td><code>,</code>203* <td>Number204* <td>Yes205* <td>Grouping separator206* <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">207* <td><code>E</code>208* <td>Number209* <td>Yes210* <td>Separates mantissa and exponent in scientific notation.211* <em>Need not be quoted in prefix or suffix.</em>212* <tr valign=top>213* <td><code>;</code>214* <td>Subpattern boundary215* <td>Yes216* <td>Separates positive and negative subpatterns217* <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">218* <td><code>%</code>219* <td>Prefix or suffix220* <td>Yes221* <td>Multiply by 100 and show as percentage222* <tr valign=top>223* <td><code>\u2030</code>224* <td>Prefix or suffix225* <td>Yes226* <td>Multiply by 1000 and show as per mille value227* <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">228* <td><code>¤</code> (<code>\u00A4</code>)229* <td>Prefix or suffix230* <td>No231* <td>Currency sign, replaced by currency symbol. If232* doubled, replaced by international currency symbol.233* If present in a pattern, the monetary decimal separator234* is used instead of the decimal separator.235* <tr valign=top>236* <td><code>'</code>237* <td>Prefix or suffix238* <td>No239* <td>Used to quote special characters in a prefix or suffix,240* for example, <code>"'#'#"</code> formats 123 to241* <code>"#123"</code>. To create a single quote242* itself, use two in a row: <code>"# o''clock"</code>.243* </table>244* </blockquote>245*246* <h4>Scientific Notation</h4>247*248* <p>Numbers in scientific notation are expressed as the product of a mantissa249* and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3. The250* mantissa is often in the range 1.0 ≤ x {@literal <} 10.0, but it need not251* be.252* <code>DecimalFormat</code> can be instructed to format and parse scientific253* notation <em>only via a pattern</em>; there is currently no factory method254* that creates a scientific notation format. In a pattern, the exponent255* character immediately followed by one or more digit characters indicates256* scientific notation. Example: <code>"0.###E0"</code> formats the number257* 1234 as <code>"1.234E3"</code>.258*259* <ul>260* <li>The number of digit characters after the exponent character gives the261* minimum exponent digit count. There is no maximum. Negative exponents are262* formatted using the localized minus sign, <em>not</em> the prefix and suffix263* from the pattern. This allows patterns such as <code>"0.###E0 m/s"</code>.264*265* <li>The minimum and maximum number of integer digits are interpreted266* together:267*268* <ul>269* <li>If the maximum number of integer digits is greater than their minimum number270* and greater than 1, it forces the exponent to be a multiple of the maximum271* number of integer digits, and the minimum number of integer digits to be272* interpreted as 1. The most common use of this is to generate273* <em>engineering notation</em>, in which the exponent is a multiple of three,274* e.g., <code>"##0.#####E0"</code>. Using this pattern, the number 12345275* formats to <code>"12.345E3"</code>, and 123456 formats to276* <code>"123.456E3"</code>.277*278* <li>Otherwise, the minimum number of integer digits is achieved by adjusting the279* exponent. Example: 0.00123 formatted with <code>"00.###E0"</code> yields280* <code>"12.3E-4"</code>.281* </ul>282*283* <li>The number of significant digits in the mantissa is the sum of the284* <em>minimum integer</em> and <em>maximum fraction</em> digits, and is285* unaffected by the maximum integer digits. For example, 12345 formatted with286* <code>"##0.##E0"</code> is <code>"12.3E3"</code>. To show all digits, set287* the significant digits count to zero. The number of significant digits288* does not affect parsing.289*290* <li>Exponential patterns may not contain grouping separators.291* </ul>292*293* <h4>Rounding</h4>294*295* <code>DecimalFormat</code> provides rounding modes defined in296* {@link java.math.RoundingMode} for formatting. By default, it uses297* {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.298*299* <h4>Digits</h4>300*301* For formatting, <code>DecimalFormat</code> uses the ten consecutive302* characters starting with the localized zero digit defined in the303* <code>DecimalFormatSymbols</code> object as digits. For parsing, these304* digits as well as all Unicode decimal digits, as defined by305* {@link Character#digit Character.digit}, are recognized.306*307* <h4>Special Values</h4>308*309* <p><code>NaN</code> is formatted as a string, which typically has a single character310* <code>\uFFFD</code>. This string is determined by the311* <code>DecimalFormatSymbols</code> object. This is the only value for which312* the prefixes and suffixes are not used.313*314* <p>Infinity is formatted as a string, which typically has a single character315* <code>\u221E</code>, with the positive or negative prefixes and suffixes316* applied. The infinity string is determined by the317* <code>DecimalFormatSymbols</code> object.318*319* <p>Negative zero (<code>"-0"</code>) parses to320* <ul>321* <li><code>BigDecimal(0)</code> if <code>isParseBigDecimal()</code> is322* true,323* <li><code>Long(0)</code> if <code>isParseBigDecimal()</code> is false324* and <code>isParseIntegerOnly()</code> is true,325* <li><code>Double(-0.0)</code> if both <code>isParseBigDecimal()</code>326* and <code>isParseIntegerOnly()</code> are false.327* </ul>328*329* <h4><a name="synchronization">Synchronization</a></h4>330*331* <p>332* Decimal formats are generally not synchronized.333* It is recommended to create separate format instances for each thread.334* If multiple threads access a format concurrently, it must be synchronized335* externally.336*337* <h4>Example</h4>338*339* <blockquote><pre>{@code340* <strong>// Print out a number using the localized number, integer, currency,341* // and percent format for each locale</strong>342* Locale[] locales = NumberFormat.getAvailableLocales();343* double myNumber = -1234.56;344* NumberFormat form;345* for (int j = 0; j < 4; ++j) {346* System.out.println("FORMAT");347* for (int i = 0; i < locales.length; ++i) {348* if (locales[i].getCountry().length() == 0) {349* continue; // Skip language-only locales350* }351* System.out.print(locales[i].getDisplayName());352* switch (j) {353* case 0:354* form = NumberFormat.getInstance(locales[i]); break;355* case 1:356* form = NumberFormat.getIntegerInstance(locales[i]); break;357* case 2:358* form = NumberFormat.getCurrencyInstance(locales[i]); break;359* default:360* form = NumberFormat.getPercentInstance(locales[i]); break;361* }362* if (form instanceof DecimalFormat) {363* System.out.print(": " + ((DecimalFormat) form).toPattern());364* }365* System.out.print(" -> " + form.format(myNumber));366* try {367* System.out.println(" -> " + form.parse(form.format(myNumber)));368* } catch (ParseException e) {}369* }370* }371* }</pre></blockquote>372*373* @see <a href="https://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a>374* @see NumberFormat375* @see DecimalFormatSymbols376* @see ParsePosition377* @author Mark Davis378* @author Alan Liu379*/380public class DecimalFormat extends NumberFormat {381382/**383* Creates a DecimalFormat using the default pattern and symbols384* for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.385* This is a convenient way to obtain a386* DecimalFormat when internationalization is not the main concern.387* <p>388* To obtain standard formats for a given locale, use the factory methods389* on NumberFormat such as getNumberInstance. These factories will390* return the most appropriate sub-class of NumberFormat for a given391* locale.392*393* @see java.text.NumberFormat#getInstance394* @see java.text.NumberFormat#getNumberInstance395* @see java.text.NumberFormat#getCurrencyInstance396* @see java.text.NumberFormat#getPercentInstance397*/398public DecimalFormat() {399// Get the pattern for the default locale.400Locale def = Locale.getDefault(Locale.Category.FORMAT);401LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class, def);402if (!(adapter instanceof ResourceBundleBasedAdapter)) {403adapter = LocaleProviderAdapter.getResourceBundleBased();404}405String[] all = adapter.getLocaleResources(def).getNumberPatterns();406407// Always applyPattern after the symbols are set408this.symbols = DecimalFormatSymbols.getInstance(def);409applyPattern(all[0], false);410}411412413/**414* Creates a DecimalFormat using the given pattern and the symbols415* for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.416* This is a convenient way to obtain a417* DecimalFormat when internationalization is not the main concern.418* <p>419* To obtain standard formats for a given locale, use the factory methods420* on NumberFormat such as getNumberInstance. These factories will421* return the most appropriate sub-class of NumberFormat for a given422* locale.423*424* @param pattern a non-localized pattern string.425* @exception NullPointerException if <code>pattern</code> is null426* @exception IllegalArgumentException if the given pattern is invalid.427* @see java.text.NumberFormat#getInstance428* @see java.text.NumberFormat#getNumberInstance429* @see java.text.NumberFormat#getCurrencyInstance430* @see java.text.NumberFormat#getPercentInstance431*/432public DecimalFormat(String pattern) {433// Always applyPattern after the symbols are set434this.symbols = DecimalFormatSymbols.getInstance(Locale.getDefault(Locale.Category.FORMAT));435applyPattern(pattern, false);436}437438439/**440* Creates a DecimalFormat using the given pattern and symbols.441* Use this constructor when you need to completely customize the442* behavior of the format.443* <p>444* To obtain standard formats for a given445* locale, use the factory methods on NumberFormat such as446* getInstance or getCurrencyInstance. If you need only minor adjustments447* to a standard format, you can modify the format returned by448* a NumberFormat factory method.449*450* @param pattern a non-localized pattern string451* @param symbols the set of symbols to be used452* @exception NullPointerException if any of the given arguments is null453* @exception IllegalArgumentException if the given pattern is invalid454* @see java.text.NumberFormat#getInstance455* @see java.text.NumberFormat#getNumberInstance456* @see java.text.NumberFormat#getCurrencyInstance457* @see java.text.NumberFormat#getPercentInstance458* @see java.text.DecimalFormatSymbols459*/460public DecimalFormat (String pattern, DecimalFormatSymbols symbols) {461// Always applyPattern after the symbols are set462this.symbols = (DecimalFormatSymbols)symbols.clone();463applyPattern(pattern, false);464}465466467// Overrides468/**469* Formats a number and appends the resulting text to the given string470* buffer.471* The number can be of any subclass of {@link java.lang.Number}.472* <p>473* This implementation uses the maximum precision permitted.474* @param number the number to format475* @param toAppendTo the <code>StringBuffer</code> to which the formatted476* text is to be appended477* @param pos On input: an alignment field, if desired.478* On output: the offsets of the alignment field.479* @return the value passed in as <code>toAppendTo</code>480* @exception IllegalArgumentException if <code>number</code> is481* null or not an instance of <code>Number</code>.482* @exception NullPointerException if <code>toAppendTo</code> or483* <code>pos</code> is null484* @exception ArithmeticException if rounding is needed with rounding485* mode being set to RoundingMode.UNNECESSARY486* @see java.text.FieldPosition487*/488@Override489public final StringBuffer format(Object number,490StringBuffer toAppendTo,491FieldPosition pos) {492if (number instanceof Long || number instanceof Integer ||493number instanceof Short || number instanceof Byte ||494number instanceof AtomicInteger ||495number instanceof AtomicLong ||496(number instanceof BigInteger &&497((BigInteger)number).bitLength () < 64)) {498return format(((Number)number).longValue(), toAppendTo, pos);499} else if (number instanceof BigDecimal) {500return format((BigDecimal)number, toAppendTo, pos);501} else if (number instanceof BigInteger) {502return format((BigInteger)number, toAppendTo, pos);503} else if (number instanceof Number) {504return format(((Number)number).doubleValue(), toAppendTo, pos);505} else {506throw new IllegalArgumentException("Cannot format given Object as a Number");507}508}509510/**511* Formats a double to produce a string.512* @param number The double to format513* @param result where the text is to be appended514* @param fieldPosition On input: an alignment field, if desired.515* On output: the offsets of the alignment field.516* @exception ArithmeticException if rounding is needed with rounding517* mode being set to RoundingMode.UNNECESSARY518* @return The formatted number string519* @see java.text.FieldPosition520*/521@Override522public StringBuffer format(double number, StringBuffer result,523FieldPosition fieldPosition) {524// If fieldPosition is a DontCareFieldPosition instance we can525// try to go to fast-path code.526boolean tryFastPath = false;527if (fieldPosition == DontCareFieldPosition.INSTANCE)528tryFastPath = true;529else {530fieldPosition.setBeginIndex(0);531fieldPosition.setEndIndex(0);532}533534if (tryFastPath) {535String tempResult = fastFormat(number);536if (tempResult != null) {537result.append(tempResult);538return result;539}540}541542// if fast-path could not work, we fallback to standard code.543return format(number, result, fieldPosition.getFieldDelegate());544}545546/**547* Formats a double to produce a string.548* @param number The double to format549* @param result where the text is to be appended550* @param delegate notified of locations of sub fields551* @exception ArithmeticException if rounding is needed with rounding552* mode being set to RoundingMode.UNNECESSARY553* @return The formatted number string554*/555private StringBuffer format(double number, StringBuffer result,556FieldDelegate delegate) {557if (Double.isNaN(number) ||558(Double.isInfinite(number) && multiplier == 0)) {559int iFieldStart = result.length();560result.append(symbols.getNaN());561delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,562iFieldStart, result.length(), result);563return result;564}565566/* Detecting whether a double is negative is easy with the exception of567* the value -0.0. This is a double which has a zero mantissa (and568* exponent), but a negative sign bit. It is semantically distinct from569* a zero with a positive sign bit, and this distinction is important570* to certain kinds of computations. However, it's a little tricky to571* detect, since (-0.0 == 0.0) and !(-0.0 < 0.0). How then, you may572* ask, does it behave distinctly from +0.0? Well, 1/(-0.0) ==573* -Infinity. Proper detection of -0.0 is needed to deal with the574* issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98.575*/576boolean isNegative = ((number < 0.0) || (number == 0.0 && 1/number < 0.0)) ^ (multiplier < 0);577578if (multiplier != 1) {579number *= multiplier;580}581582if (Double.isInfinite(number)) {583if (isNegative) {584append(result, negativePrefix, delegate,585getNegativePrefixFieldPositions(), Field.SIGN);586} else {587append(result, positivePrefix, delegate,588getPositivePrefixFieldPositions(), Field.SIGN);589}590591int iFieldStart = result.length();592result.append(symbols.getInfinity());593delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,594iFieldStart, result.length(), result);595596if (isNegative) {597append(result, negativeSuffix, delegate,598getNegativeSuffixFieldPositions(), Field.SIGN);599} else {600append(result, positiveSuffix, delegate,601getPositiveSuffixFieldPositions(), Field.SIGN);602}603604return result;605}606607if (isNegative) {608number = -number;609}610611// at this point we are guaranteed a nonnegative finite number.612assert(number >= 0 && !Double.isInfinite(number));613614synchronized(digitList) {615int maxIntDigits = super.getMaximumIntegerDigits();616int minIntDigits = super.getMinimumIntegerDigits();617int maxFraDigits = super.getMaximumFractionDigits();618int minFraDigits = super.getMinimumFractionDigits();619620digitList.set(isNegative, number, useExponentialNotation ?621maxIntDigits + maxFraDigits : maxFraDigits,622!useExponentialNotation);623return subformat(result, delegate, isNegative, false,624maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);625}626}627628/**629* Format a long to produce a string.630* @param number The long to format631* @param result where the text is to be appended632* @param fieldPosition On input: an alignment field, if desired.633* On output: the offsets of the alignment field.634* @exception ArithmeticException if rounding is needed with rounding635* mode being set to RoundingMode.UNNECESSARY636* @return The formatted number string637* @see java.text.FieldPosition638*/639@Override640public StringBuffer format(long number, StringBuffer result,641FieldPosition fieldPosition) {642fieldPosition.setBeginIndex(0);643fieldPosition.setEndIndex(0);644645return format(number, result, fieldPosition.getFieldDelegate());646}647648/**649* Format a long to produce a string.650* @param number The long to format651* @param result where the text is to be appended652* @param delegate notified of locations of sub fields653* @return The formatted number string654* @exception ArithmeticException if rounding is needed with rounding655* mode being set to RoundingMode.UNNECESSARY656* @see java.text.FieldPosition657*/658private StringBuffer format(long number, StringBuffer result,659FieldDelegate delegate) {660boolean isNegative = (number < 0);661if (isNegative) {662number = -number;663}664665// In general, long values always represent real finite numbers, so666// we don't have to check for +/- Infinity or NaN. However, there667// is one case we have to be careful of: The multiplier can push668// a number near MIN_VALUE or MAX_VALUE outside the legal range. We669// check for this before multiplying, and if it happens we use670// BigInteger instead.671boolean useBigInteger = false;672if (number < 0) { // This can only happen if number == Long.MIN_VALUE.673if (multiplier != 0) {674useBigInteger = true;675}676} else if (multiplier != 1 && multiplier != 0) {677long cutoff = Long.MAX_VALUE / multiplier;678if (cutoff < 0) {679cutoff = -cutoff;680}681useBigInteger = (number > cutoff);682}683684if (useBigInteger) {685if (isNegative) {686number = -number;687}688BigInteger bigIntegerValue = BigInteger.valueOf(number);689return format(bigIntegerValue, result, delegate, true);690}691692number *= multiplier;693if (number == 0) {694isNegative = false;695} else {696if (multiplier < 0) {697number = -number;698isNegative = !isNegative;699}700}701702synchronized(digitList) {703int maxIntDigits = super.getMaximumIntegerDigits();704int minIntDigits = super.getMinimumIntegerDigits();705int maxFraDigits = super.getMaximumFractionDigits();706int minFraDigits = super.getMinimumFractionDigits();707708digitList.set(isNegative, number,709useExponentialNotation ? maxIntDigits + maxFraDigits : 0);710711return subformat(result, delegate, isNegative, true,712maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);713}714}715716/**717* Formats a BigDecimal to produce a string.718* @param number The BigDecimal to format719* @param result where the text is to be appended720* @param fieldPosition On input: an alignment field, if desired.721* On output: the offsets of the alignment field.722* @return The formatted number string723* @exception ArithmeticException if rounding is needed with rounding724* mode being set to RoundingMode.UNNECESSARY725* @see java.text.FieldPosition726*/727private StringBuffer format(BigDecimal number, StringBuffer result,728FieldPosition fieldPosition) {729fieldPosition.setBeginIndex(0);730fieldPosition.setEndIndex(0);731return format(number, result, fieldPosition.getFieldDelegate());732}733734/**735* Formats a BigDecimal to produce a string.736* @param number The BigDecimal to format737* @param result where the text is to be appended738* @param delegate notified of locations of sub fields739* @exception ArithmeticException if rounding is needed with rounding740* mode being set to RoundingMode.UNNECESSARY741* @return The formatted number string742*/743private StringBuffer format(BigDecimal number, StringBuffer result,744FieldDelegate delegate) {745if (multiplier != 1) {746number = number.multiply(getBigDecimalMultiplier());747}748boolean isNegative = number.signum() == -1;749if (isNegative) {750number = number.negate();751}752753synchronized(digitList) {754int maxIntDigits = getMaximumIntegerDigits();755int minIntDigits = getMinimumIntegerDigits();756int maxFraDigits = getMaximumFractionDigits();757int minFraDigits = getMinimumFractionDigits();758int maximumDigits = maxIntDigits + maxFraDigits;759760digitList.set(isNegative, number, useExponentialNotation ?761((maximumDigits < 0) ? Integer.MAX_VALUE : maximumDigits) :762maxFraDigits, !useExponentialNotation);763764return subformat(result, delegate, isNegative, false,765maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);766}767}768769/**770* Format a BigInteger to produce a string.771* @param number The BigInteger to format772* @param result where the text is to be appended773* @param fieldPosition On input: an alignment field, if desired.774* On output: the offsets of the alignment field.775* @return The formatted number string776* @exception ArithmeticException if rounding is needed with rounding777* mode being set to RoundingMode.UNNECESSARY778* @see java.text.FieldPosition779*/780private StringBuffer format(BigInteger number, StringBuffer result,781FieldPosition fieldPosition) {782fieldPosition.setBeginIndex(0);783fieldPosition.setEndIndex(0);784785return format(number, result, fieldPosition.getFieldDelegate(), false);786}787788/**789* Format a BigInteger to produce a string.790* @param number The BigInteger to format791* @param result where the text is to be appended792* @param delegate notified of locations of sub fields793* @return The formatted number string794* @exception ArithmeticException if rounding is needed with rounding795* mode being set to RoundingMode.UNNECESSARY796* @see java.text.FieldPosition797*/798private StringBuffer format(BigInteger number, StringBuffer result,799FieldDelegate delegate, boolean formatLong) {800if (multiplier != 1) {801number = number.multiply(getBigIntegerMultiplier());802}803boolean isNegative = number.signum() == -1;804if (isNegative) {805number = number.negate();806}807808synchronized(digitList) {809int maxIntDigits, minIntDigits, maxFraDigits, minFraDigits, maximumDigits;810if (formatLong) {811maxIntDigits = super.getMaximumIntegerDigits();812minIntDigits = super.getMinimumIntegerDigits();813maxFraDigits = super.getMaximumFractionDigits();814minFraDigits = super.getMinimumFractionDigits();815maximumDigits = maxIntDigits + maxFraDigits;816} else {817maxIntDigits = getMaximumIntegerDigits();818minIntDigits = getMinimumIntegerDigits();819maxFraDigits = getMaximumFractionDigits();820minFraDigits = getMinimumFractionDigits();821maximumDigits = maxIntDigits + maxFraDigits;822if (maximumDigits < 0) {823maximumDigits = Integer.MAX_VALUE;824}825}826827digitList.set(isNegative, number,828useExponentialNotation ? maximumDigits : 0);829830return subformat(result, delegate, isNegative, true,831maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);832}833}834835/**836* Formats an Object producing an <code>AttributedCharacterIterator</code>.837* You can use the returned <code>AttributedCharacterIterator</code>838* to build the resulting String, as well as to determine information839* about the resulting String.840* <p>841* Each attribute key of the AttributedCharacterIterator will be of type842* <code>NumberFormat.Field</code>, with the attribute value being the843* same as the attribute key.844*845* @exception NullPointerException if obj is null.846* @exception IllegalArgumentException when the Format cannot format the847* given object.848* @exception ArithmeticException if rounding is needed with rounding849* mode being set to RoundingMode.UNNECESSARY850* @param obj The object to format851* @return AttributedCharacterIterator describing the formatted value.852* @since 1.4853*/854@Override855public AttributedCharacterIterator formatToCharacterIterator(Object obj) {856CharacterIteratorFieldDelegate delegate =857new CharacterIteratorFieldDelegate();858StringBuffer sb = new StringBuffer();859860if (obj instanceof Double || obj instanceof Float) {861format(((Number)obj).doubleValue(), sb, delegate);862} else if (obj instanceof Long || obj instanceof Integer ||863obj instanceof Short || obj instanceof Byte ||864obj instanceof AtomicInteger || obj instanceof AtomicLong) {865format(((Number)obj).longValue(), sb, delegate);866} else if (obj instanceof BigDecimal) {867format((BigDecimal)obj, sb, delegate);868} else if (obj instanceof BigInteger) {869format((BigInteger)obj, sb, delegate, false);870} else if (obj == null) {871throw new NullPointerException(872"formatToCharacterIterator must be passed non-null object");873} else {874throw new IllegalArgumentException(875"Cannot format given Object as a Number");876}877return delegate.getIterator(sb.toString());878}879880// ==== Begin fast-path formating logic for double =========================881882/* Fast-path formatting will be used for format(double ...) methods iff a883* number of conditions are met (see checkAndSetFastPathStatus()):884* - Only if instance properties meet the right predefined conditions.885* - The abs value of the double to format is <= Integer.MAX_VALUE.886*887* The basic approach is to split the binary to decimal conversion of a888* double value into two phases:889* * The conversion of the integer portion of the double.890* * The conversion of the fractional portion of the double891* (limited to two or three digits).892*893* The isolation and conversion of the integer portion of the double is894* straightforward. The conversion of the fraction is more subtle and relies895* on some rounding properties of double to the decimal precisions in896* question. Using the terminology of BigDecimal, this fast-path algorithm897* is applied when a double value has a magnitude less than Integer.MAX_VALUE898* and rounding is to nearest even and the destination format has two or899* three digits of *scale* (digits after the decimal point).900*901* Under a rounding to nearest even policy, the returned result is a digit902* string of a number in the (in this case decimal) destination format903* closest to the exact numerical value of the (in this case binary) input904* value. If two destination format numbers are equally distant, the one905* with the last digit even is returned. To compute such a correctly rounded906* value, some information about digits beyond the smallest returned digit907* position needs to be consulted.908*909* In general, a guard digit, a round digit, and a sticky *bit* are needed910* beyond the returned digit position. If the discarded portion of the input911* is sufficiently large, the returned digit string is incremented. In round912* to nearest even, this threshold to increment occurs near the half-way913* point between digits. The sticky bit records if there are any remaining914* trailing digits of the exact input value in the new format; the sticky bit915* is consulted only in close to half-way rounding cases.916*917* Given the computation of the digit and bit values, rounding is then918* reduced to a table lookup problem. For decimal, the even/odd cases look919* like this:920*921* Last Round Sticky922* 6 5 0 => 6 // exactly halfway, return even digit.923* 6 5 1 => 7 // a little bit more than halfway, round up.924* 7 5 0 => 8 // exactly halfway, round up to even.925* 7 5 1 => 8 // a little bit more than halfway, round up.926* With analogous entries for other even and odd last-returned digits.927*928* However, decimal negative powers of 5 smaller than 0.5 are *not* exactly929* representable as binary fraction. In particular, 0.005 (the round limit930* for a two-digit scale) and 0.0005 (the round limit for a three-digit931* scale) are not representable. Therefore, for input values near these cases932* the sticky bit is known to be set which reduces the rounding logic to:933*934* Last Round Sticky935* 6 5 1 => 7 // a little bit more than halfway, round up.936* 7 5 1 => 8 // a little bit more than halfway, round up.937*938* In other words, if the round digit is 5, the sticky bit is known to be939* set. If the round digit is something other than 5, the sticky bit is not940* relevant. Therefore, some of the logic about whether or not to increment941* the destination *decimal* value can occur based on tests of *binary*942* computations of the binary input number.943*/944945/**946* Check validity of using fast-path for this instance. If fast-path is valid947* for this instance, sets fast-path state as true and initializes fast-path948* utility fields as needed.949*950* This method is supposed to be called rarely, otherwise that will break the951* fast-path performance. That means avoiding frequent changes of the952* properties of the instance, since for most properties, each time a change953* happens, a call to this method is needed at the next format call.954*955* FAST-PATH RULES:956* Similar to the default DecimalFormat instantiation case.957* More precisely:958* - HALF_EVEN rounding mode,959* - isGroupingUsed() is true,960* - groupingSize of 3,961* - multiplier is 1,962* - Decimal separator not mandatory,963* - No use of exponential notation,964* - minimumIntegerDigits is exactly 1 and maximumIntegerDigits at least 10965* - For number of fractional digits, the exact values found in the default case:966* Currency : min = max = 2.967* Decimal : min = 0. max = 3.968*969*/970private boolean checkAndSetFastPathStatus() {971972boolean fastPathWasOn = isFastPath;973974if ((roundingMode == RoundingMode.HALF_EVEN) &&975(isGroupingUsed()) &&976(groupingSize == 3) &&977(multiplier == 1) &&978(!decimalSeparatorAlwaysShown) &&979(!useExponentialNotation)) {980981// The fast-path algorithm is semi-hardcoded against982// minimumIntegerDigits and maximumIntegerDigits.983isFastPath = ((minimumIntegerDigits == 1) &&984(maximumIntegerDigits >= 10));985986// The fast-path algorithm is hardcoded against987// minimumFractionDigits and maximumFractionDigits.988if (isFastPath) {989if (isCurrencyFormat) {990if ((minimumFractionDigits != 2) ||991(maximumFractionDigits != 2))992isFastPath = false;993} else if ((minimumFractionDigits != 0) ||994(maximumFractionDigits != 3))995isFastPath = false;996}997} else998isFastPath = false;9991000resetFastPathData(fastPathWasOn);1001fastPathCheckNeeded = false;10021003/*1004* Returns true after successfully checking the fast path condition and1005* setting the fast path data. The return value is used by the1006* fastFormat() method to decide whether to call the resetFastPathData1007* method to reinitialize fast path data or is it already initialized1008* in this method.1009*/1010return true;1011}10121013private void resetFastPathData(boolean fastPathWasOn) {1014// Since some instance properties may have changed while still falling1015// in the fast-path case, we need to reinitialize fastPathData anyway.1016if (isFastPath) {1017// We need to instantiate fastPathData if not already done.1018if (fastPathData == null) {1019fastPathData = new FastPathData();1020}10211022// Sets up the locale specific constants used when formatting.1023// '0' is our default representation of zero.1024fastPathData.zeroDelta = symbols.getZeroDigit() - '0';1025fastPathData.groupingChar = symbols.getGroupingSeparator();10261027// Sets up fractional constants related to currency/decimal pattern.1028fastPathData.fractionalMaxIntBound = (isCurrencyFormat)1029? 99 : 999;1030fastPathData.fractionalScaleFactor = (isCurrencyFormat)1031? 100.0d : 1000.0d;10321033// Records the need for adding prefix or suffix1034fastPathData.positiveAffixesRequired1035= (positivePrefix.length() != 0)1036|| (positiveSuffix.length() != 0);1037fastPathData.negativeAffixesRequired1038= (negativePrefix.length() != 0)1039|| (negativeSuffix.length() != 0);10401041// Creates a cached char container for result, with max possible size.1042int maxNbIntegralDigits = 10;1043int maxNbGroups = 3;1044int containerSize1045= Math.max(positivePrefix.length(), negativePrefix.length())1046+ maxNbIntegralDigits + maxNbGroups + 11047+ maximumFractionDigits1048+ Math.max(positiveSuffix.length(), negativeSuffix.length());10491050fastPathData.fastPathContainer = new char[containerSize];10511052// Sets up prefix and suffix char arrays constants.1053fastPathData.charsPositiveSuffix = positiveSuffix.toCharArray();1054fastPathData.charsNegativeSuffix = negativeSuffix.toCharArray();1055fastPathData.charsPositivePrefix = positivePrefix.toCharArray();1056fastPathData.charsNegativePrefix = negativePrefix.toCharArray();10571058// Sets up fixed index positions for integral and fractional digits.1059// Sets up decimal point in cached result container.1060int longestPrefixLength1061= Math.max(positivePrefix.length(),1062negativePrefix.length());1063int decimalPointIndex1064= maxNbIntegralDigits + maxNbGroups + longestPrefixLength;10651066fastPathData.integralLastIndex = decimalPointIndex - 1;1067fastPathData.fractionalFirstIndex = decimalPointIndex + 1;1068fastPathData.fastPathContainer[decimalPointIndex]1069= isCurrencyFormat1070? symbols.getMonetaryDecimalSeparator()1071: symbols.getDecimalSeparator();10721073} else if (fastPathWasOn) {1074// Previous state was fast-path and is no more.1075// Resets cached array constants.1076fastPathData.fastPathContainer = null;1077fastPathData.charsPositiveSuffix = null;1078fastPathData.charsNegativeSuffix = null;1079fastPathData.charsPositivePrefix = null;1080fastPathData.charsNegativePrefix = null;1081}1082}10831084/**1085* Returns true if rounding-up must be done on {@code scaledFractionalPartAsInt},1086* false otherwise.1087*1088* This is a utility method that takes correct half-even rounding decision on1089* passed fractional value at the scaled decimal point (2 digits for currency1090* case and 3 for decimal case), when the approximated fractional part after1091* scaled decimal point is exactly 0.5d. This is done by means of exact1092* calculations on the {@code fractionalPart} floating-point value.1093*1094* This method is supposed to be called by private {@code fastDoubleFormat}1095* method only.1096*1097* The algorithms used for the exact calculations are :1098*1099* The <b><i>FastTwoSum</i></b> algorithm, from T.J.Dekker, described in the1100* papers "<i>A Floating-Point Technique for Extending the Available1101* Precision</i>" by Dekker, and in "<i>Adaptive Precision Floating-Point1102* Arithmetic and Fast Robust Geometric Predicates</i>" from J.Shewchuk.1103*1104* A modified version of <b><i>Sum2S</i></b> cascaded summation described in1105* "<i>Accurate Sum and Dot Product</i>" from Takeshi Ogita and All. As1106* Ogita says in this paper this is an equivalent of the Kahan-Babuska's1107* summation algorithm because we order the terms by magnitude before summing1108* them. For this reason we can use the <i>FastTwoSum</i> algorithm rather1109* than the more expensive Knuth's <i>TwoSum</i>.1110*1111* We do this to avoid a more expensive exact "<i>TwoProduct</i>" algorithm,1112* like those described in Shewchuk's paper above. See comments in the code1113* below.1114*1115* @param fractionalPart The fractional value on which we take rounding1116* decision.1117* @param scaledFractionalPartAsInt The integral part of the scaled1118* fractional value.1119*1120* @return the decision that must be taken regarding half-even rounding.1121*/1122private boolean exactRoundUp(double fractionalPart,1123int scaledFractionalPartAsInt) {11241125/* exactRoundUp() method is called by fastDoubleFormat() only.1126* The precondition expected to be verified by the passed parameters is :1127* scaledFractionalPartAsInt ==1128* (int) (fractionalPart * fastPathData.fractionalScaleFactor).1129* This is ensured by fastDoubleFormat() code.1130*/11311132/* We first calculate roundoff error made by fastDoubleFormat() on1133* the scaled fractional part. We do this with exact calculation on the1134* passed fractionalPart. Rounding decision will then be taken from roundoff.1135*/11361137/* ---- TwoProduct(fractionalPart, scale factor (i.e. 1000.0d or 100.0d)).1138*1139* The below is an optimized exact "TwoProduct" calculation of passed1140* fractional part with scale factor, using Ogita's Sum2S cascaded1141* summation adapted as Kahan-Babuska equivalent by using FastTwoSum1142* (much faster) rather than Knuth's TwoSum.1143*1144* We can do this because we order the summation from smallest to1145* greatest, so that FastTwoSum can be used without any additional error.1146*1147* The "TwoProduct" exact calculation needs 17 flops. We replace this by1148* a cascaded summation of FastTwoSum calculations, each involving an1149* exact multiply by a power of 2.1150*1151* Doing so saves overall 4 multiplications and 1 addition compared to1152* using traditional "TwoProduct".1153*1154* The scale factor is either 100 (currency case) or 1000 (decimal case).1155* - when 1000, we replace it by (1024 - 16 - 8) = 1000.1156* - when 100, we replace it by (128 - 32 + 4) = 100.1157* Every multiplication by a power of 2 (1024, 128, 32, 16, 8, 4) is exact.1158*1159*/1160double approxMax; // Will always be positive.1161double approxMedium; // Will always be negative.1162double approxMin;11631164double fastTwoSumApproximation = 0.0d;1165double fastTwoSumRoundOff = 0.0d;1166double bVirtual = 0.0d;11671168if (isCurrencyFormat) {1169// Scale is 100 = 128 - 32 + 4.1170// Multiply by 2**n is a shift. No roundoff. No error.1171approxMax = fractionalPart * 128.00d;1172approxMedium = - (fractionalPart * 32.00d);1173approxMin = fractionalPart * 4.00d;1174} else {1175// Scale is 1000 = 1024 - 16 - 8.1176// Multiply by 2**n is a shift. No roundoff. No error.1177approxMax = fractionalPart * 1024.00d;1178approxMedium = - (fractionalPart * 16.00d);1179approxMin = - (fractionalPart * 8.00d);1180}11811182// Shewchuk/Dekker's FastTwoSum(approxMedium, approxMin).1183assert(-approxMedium >= Math.abs(approxMin));1184fastTwoSumApproximation = approxMedium + approxMin;1185bVirtual = fastTwoSumApproximation - approxMedium;1186fastTwoSumRoundOff = approxMin - bVirtual;1187double approxS1 = fastTwoSumApproximation;1188double roundoffS1 = fastTwoSumRoundOff;11891190// Shewchuk/Dekker's FastTwoSum(approxMax, approxS1);1191assert(approxMax >= Math.abs(approxS1));1192fastTwoSumApproximation = approxMax + approxS1;1193bVirtual = fastTwoSumApproximation - approxMax;1194fastTwoSumRoundOff = approxS1 - bVirtual;1195double roundoff1000 = fastTwoSumRoundOff;1196double approx1000 = fastTwoSumApproximation;1197double roundoffTotal = roundoffS1 + roundoff1000;11981199// Shewchuk/Dekker's FastTwoSum(approx1000, roundoffTotal);1200assert(approx1000 >= Math.abs(roundoffTotal));1201fastTwoSumApproximation = approx1000 + roundoffTotal;1202bVirtual = fastTwoSumApproximation - approx1000;12031204// Now we have got the roundoff for the scaled fractional1205double scaledFractionalRoundoff = roundoffTotal - bVirtual;12061207// ---- TwoProduct(fractionalPart, scale (i.e. 1000.0d or 100.0d)) end.12081209/* ---- Taking the rounding decision1210*1211* We take rounding decision based on roundoff and half-even rounding1212* rule.1213*1214* The above TwoProduct gives us the exact roundoff on the approximated1215* scaled fractional, and we know that this approximation is exactly1216* 0.5d, since that has already been tested by the caller1217* (fastDoubleFormat).1218*1219* Decision comes first from the sign of the calculated exact roundoff.1220* - Since being exact roundoff, it cannot be positive with a scaled1221* fractional less than 0.5d, as well as negative with a scaled1222* fractional greater than 0.5d. That leaves us with following 3 cases.1223* - positive, thus scaled fractional == 0.500....0fff ==> round-up.1224* - negative, thus scaled fractional == 0.499....9fff ==> don't round-up.1225* - is zero, thus scaled fractioanl == 0.5 ==> half-even rounding applies :1226* we round-up only if the integral part of the scaled fractional is odd.1227*1228*/1229if (scaledFractionalRoundoff > 0.0) {1230return true;1231} else if (scaledFractionalRoundoff < 0.0) {1232return false;1233} else if ((scaledFractionalPartAsInt & 1) != 0) {1234return true;1235}12361237return false;12381239// ---- Taking the rounding decision end1240}12411242/**1243* Collects integral digits from passed {@code number}, while setting1244* grouping chars as needed. Updates {@code firstUsedIndex} accordingly.1245*1246* Loops downward starting from {@code backwardIndex} position (inclusive).1247*1248* @param number The int value from which we collect digits.1249* @param digitsBuffer The char array container where digits and grouping chars1250* are stored.1251* @param backwardIndex the position from which we start storing digits in1252* digitsBuffer.1253*1254*/1255private void collectIntegralDigits(int number,1256char[] digitsBuffer,1257int backwardIndex) {1258int index = backwardIndex;1259int q;1260int r;1261while (number > 999) {1262// Generates 3 digits per iteration.1263q = number / 1000;1264r = number - (q << 10) + (q << 4) + (q << 3); // -1024 +16 +8 = 1000.1265number = q;12661267digitsBuffer[index--] = DigitArrays.DigitOnes1000[r];1268digitsBuffer[index--] = DigitArrays.DigitTens1000[r];1269digitsBuffer[index--] = DigitArrays.DigitHundreds1000[r];1270digitsBuffer[index--] = fastPathData.groupingChar;1271}12721273// Collects last 3 or less digits.1274digitsBuffer[index] = DigitArrays.DigitOnes1000[number];1275if (number > 9) {1276digitsBuffer[--index] = DigitArrays.DigitTens1000[number];1277if (number > 99)1278digitsBuffer[--index] = DigitArrays.DigitHundreds1000[number];1279}12801281fastPathData.firstUsedIndex = index;1282}12831284/**1285* Collects the 2 (currency) or 3 (decimal) fractional digits from passed1286* {@code number}, starting at {@code startIndex} position1287* inclusive. There is no punctuation to set here (no grouping chars).1288* Updates {@code fastPathData.lastFreeIndex} accordingly.1289*1290*1291* @param number The int value from which we collect digits.1292* @param digitsBuffer The char array container where digits are stored.1293* @param startIndex the position from which we start storing digits in1294* digitsBuffer.1295*1296*/1297private void collectFractionalDigits(int number,1298char[] digitsBuffer,1299int startIndex) {1300int index = startIndex;13011302char digitOnes = DigitArrays.DigitOnes1000[number];1303char digitTens = DigitArrays.DigitTens1000[number];13041305if (isCurrencyFormat) {1306// Currency case. Always collects fractional digits.1307digitsBuffer[index++] = digitTens;1308digitsBuffer[index++] = digitOnes;1309} else if (number != 0) {1310// Decimal case. Hundreds will always be collected1311digitsBuffer[index++] = DigitArrays.DigitHundreds1000[number];13121313// Ending zeros won't be collected.1314if (digitOnes != '0') {1315digitsBuffer[index++] = digitTens;1316digitsBuffer[index++] = digitOnes;1317} else if (digitTens != '0')1318digitsBuffer[index++] = digitTens;13191320} else1321// This is decimal pattern and fractional part is zero.1322// We must remove decimal point from result.1323index--;13241325fastPathData.lastFreeIndex = index;1326}13271328/**1329* Internal utility.1330* Adds the passed {@code prefix} and {@code suffix} to {@code container}.1331*1332* @param container Char array container which to prepend/append the1333* prefix/suffix.1334* @param prefix Char sequence to prepend as a prefix.1335* @param suffix Char sequence to append as a suffix.1336*1337*/1338// private void addAffixes(boolean isNegative, char[] container) {1339private void addAffixes(char[] container, char[] prefix, char[] suffix) {13401341// We add affixes only if needed (affix length > 0).1342int pl = prefix.length;1343int sl = suffix.length;1344if (pl != 0) prependPrefix(prefix, pl, container);1345if (sl != 0) appendSuffix(suffix, sl, container);13461347}13481349/**1350* Prepends the passed {@code prefix} chars to given result1351* {@code container}. Updates {@code fastPathData.firstUsedIndex}1352* accordingly.1353*1354* @param prefix The prefix characters to prepend to result.1355* @param len The number of chars to prepend.1356* @param container Char array container which to prepend the prefix1357*/1358private void prependPrefix(char[] prefix,1359int len,1360char[] container) {13611362fastPathData.firstUsedIndex -= len;1363int startIndex = fastPathData.firstUsedIndex;13641365// If prefix to prepend is only 1 char long, just assigns this char.1366// If prefix is less or equal 4, we use a dedicated algorithm that1367// has shown to run faster than System.arraycopy.1368// If more than 4, we use System.arraycopy.1369if (len == 1)1370container[startIndex] = prefix[0];1371else if (len <= 4) {1372int dstLower = startIndex;1373int dstUpper = dstLower + len - 1;1374int srcUpper = len - 1;1375container[dstLower] = prefix[0];1376container[dstUpper] = prefix[srcUpper];13771378if (len > 2)1379container[++dstLower] = prefix[1];1380if (len == 4)1381container[--dstUpper] = prefix[2];1382} else1383System.arraycopy(prefix, 0, container, startIndex, len);1384}13851386/**1387* Appends the passed {@code suffix} chars to given result1388* {@code container}. Updates {@code fastPathData.lastFreeIndex}1389* accordingly.1390*1391* @param suffix The suffix characters to append to result.1392* @param len The number of chars to append.1393* @param container Char array container which to append the suffix1394*/1395private void appendSuffix(char[] suffix,1396int len,1397char[] container) {13981399int startIndex = fastPathData.lastFreeIndex;14001401// If suffix to append is only 1 char long, just assigns this char.1402// If suffix is less or equal 4, we use a dedicated algorithm that1403// has shown to run faster than System.arraycopy.1404// If more than 4, we use System.arraycopy.1405if (len == 1)1406container[startIndex] = suffix[0];1407else if (len <= 4) {1408int dstLower = startIndex;1409int dstUpper = dstLower + len - 1;1410int srcUpper = len - 1;1411container[dstLower] = suffix[0];1412container[dstUpper] = suffix[srcUpper];14131414if (len > 2)1415container[++dstLower] = suffix[1];1416if (len == 4)1417container[--dstUpper] = suffix[2];1418} else1419System.arraycopy(suffix, 0, container, startIndex, len);14201421fastPathData.lastFreeIndex += len;1422}14231424/**1425* Converts digit chars from {@code digitsBuffer} to current locale.1426*1427* Must be called before adding affixes since we refer to1428* {@code fastPathData.firstUsedIndex} and {@code fastPathData.lastFreeIndex},1429* and do not support affixes (for speed reason).1430*1431* We loop backward starting from last used index in {@code fastPathData}.1432*1433* @param digitsBuffer The char array container where the digits are stored.1434*/1435private void localizeDigits(char[] digitsBuffer) {14361437// We will localize only the digits, using the groupingSize,1438// and taking into account fractional part.14391440// First take into account fractional part.1441int digitsCounter =1442fastPathData.lastFreeIndex - fastPathData.fractionalFirstIndex;14431444// The case when there is no fractional digits.1445if (digitsCounter < 0)1446digitsCounter = groupingSize;14471448// Only the digits remains to localize.1449for (int cursor = fastPathData.lastFreeIndex - 1;1450cursor >= fastPathData.firstUsedIndex;1451cursor--) {1452if (digitsCounter != 0) {1453// This is a digit char, we must localize it.1454digitsBuffer[cursor] += fastPathData.zeroDelta;1455digitsCounter--;1456} else {1457// Decimal separator or grouping char. Reinit counter only.1458digitsCounter = groupingSize;1459}1460}1461}14621463/**1464* This is the main entry point for the fast-path format algorithm.1465*1466* At this point we are sure to be in the expected conditions to run it.1467* This algorithm builds the formatted result and puts it in the dedicated1468* {@code fastPathData.fastPathContainer}.1469*1470* @param d the double value to be formatted.1471* @param negative Flag precising if {@code d} is negative.1472*/1473private void fastDoubleFormat(double d,1474boolean negative) {14751476char[] container = fastPathData.fastPathContainer;14771478/*1479* The principle of the algorithm is to :1480* - Break the passed double into its integral and fractional parts1481* converted into integers.1482* - Then decide if rounding up must be applied or not by following1483* the half-even rounding rule, first using approximated scaled1484* fractional part.1485* - For the difficult cases (approximated scaled fractional part1486* being exactly 0.5d), we refine the rounding decision by calling1487* exactRoundUp utility method that both calculates the exact roundoff1488* on the approximation and takes correct rounding decision.1489* - We round-up the fractional part if needed, possibly propagating the1490* rounding to integral part if we meet a "all-nine" case for the1491* scaled fractional part.1492* - We then collect digits from the resulting integral and fractional1493* parts, also setting the required grouping chars on the fly.1494* - Then we localize the collected digits if needed, and1495* - Finally prepend/append prefix/suffix if any is needed.1496*/14971498// Exact integral part of d.1499int integralPartAsInt = (int) d;15001501// Exact fractional part of d (since we subtract it's integral part).1502double exactFractionalPart = d - (double) integralPartAsInt;15031504// Approximated scaled fractional part of d (due to multiplication).1505double scaledFractional =1506exactFractionalPart * fastPathData.fractionalScaleFactor;15071508// Exact integral part of scaled fractional above.1509int fractionalPartAsInt = (int) scaledFractional;15101511// Exact fractional part of scaled fractional above.1512scaledFractional = scaledFractional - (double) fractionalPartAsInt;15131514// Only when scaledFractional is exactly 0.5d do we have to do exact1515// calculations and take fine-grained rounding decision, since1516// approximated results above may lead to incorrect decision.1517// Otherwise comparing against 0.5d (strictly greater or less) is ok.1518boolean roundItUp = false;1519if (scaledFractional >= 0.5d) {1520if (scaledFractional == 0.5d)1521// Rounding need fine-grained decision.1522roundItUp = exactRoundUp(exactFractionalPart, fractionalPartAsInt);1523else1524roundItUp = true;15251526if (roundItUp) {1527// Rounds up both fractional part (and also integral if needed).1528if (fractionalPartAsInt < fastPathData.fractionalMaxIntBound) {1529fractionalPartAsInt++;1530} else {1531// Propagates rounding to integral part since "all nines" case.1532fractionalPartAsInt = 0;1533integralPartAsInt++;1534}1535}1536}15371538// Collecting digits.1539collectFractionalDigits(fractionalPartAsInt, container,1540fastPathData.fractionalFirstIndex);1541collectIntegralDigits(integralPartAsInt, container,1542fastPathData.integralLastIndex);15431544// Localizing digits.1545if (fastPathData.zeroDelta != 0)1546localizeDigits(container);15471548// Adding prefix and suffix.1549if (negative) {1550if (fastPathData.negativeAffixesRequired)1551addAffixes(container,1552fastPathData.charsNegativePrefix,1553fastPathData.charsNegativeSuffix);1554} else if (fastPathData.positiveAffixesRequired)1555addAffixes(container,1556fastPathData.charsPositivePrefix,1557fastPathData.charsPositiveSuffix);1558}15591560/**1561* A fast-path shortcut of format(double) to be called by NumberFormat, or by1562* format(double, ...) public methods.1563*1564* If instance can be applied fast-path and passed double is not NaN or1565* Infinity, is in the integer range, we call {@code fastDoubleFormat}1566* after changing {@code d} to its positive value if necessary.1567*1568* Otherwise returns null by convention since fast-path can't be exercized.1569*1570* @param d The double value to be formatted1571*1572* @return the formatted result for {@code d} as a string.1573*/1574String fastFormat(double d) {1575boolean isDataSet = false;1576// (Re-)Evaluates fast-path status if needed.1577if (fastPathCheckNeeded) {1578isDataSet = checkAndSetFastPathStatus();1579}15801581if (!isFastPath )1582// DecimalFormat instance is not in a fast-path state.1583return null;15841585if (!Double.isFinite(d))1586// Should not use fast-path for Infinity and NaN.1587return null;15881589// Extracts and records sign of double value, possibly changing it1590// to a positive one, before calling fastDoubleFormat().1591boolean negative = false;1592if (d < 0.0d) {1593negative = true;1594d = -d;1595} else if (d == 0.0d) {1596negative = (Math.copySign(1.0d, d) == -1.0d);1597d = +0.0d;1598}15991600if (d > MAX_INT_AS_DOUBLE)1601// Filters out values that are outside expected fast-path range1602return null;1603else {1604if (!isDataSet) {1605/*1606* If the fast path data is not set through1607* checkAndSetFastPathStatus() and fulfil the1608* fast path conditions then reset the data1609* directly through resetFastPathData()1610*/1611resetFastPathData(isFastPath);1612}1613fastDoubleFormat(d, negative);16141615}161616171618// Returns a new string from updated fastPathContainer.1619return new String(fastPathData.fastPathContainer,1620fastPathData.firstUsedIndex,1621fastPathData.lastFreeIndex - fastPathData.firstUsedIndex);16221623}16241625// ======== End fast-path formating logic for double =========================16261627/**1628* Complete the formatting of a finite number. On entry, the digitList must1629* be filled in with the correct digits.1630*/1631private StringBuffer subformat(StringBuffer result, FieldDelegate delegate,1632boolean isNegative, boolean isInteger,1633int maxIntDigits, int minIntDigits,1634int maxFraDigits, int minFraDigits) {1635// NOTE: This isn't required anymore because DigitList takes care of this.1636//1637// // The negative of the exponent represents the number of leading1638// // zeros between the decimal and the first non-zero digit, for1639// // a value < 0.1 (e.g., for 0.00123, -fExponent == 2). If this1640// // is more than the maximum fraction digits, then we have an underflow1641// // for the printed representation. We recognize this here and set1642// // the DigitList representation to zero in this situation.1643//1644// if (-digitList.decimalAt >= getMaximumFractionDigits())1645// {1646// digitList.count = 0;1647// }16481649char zero = symbols.getZeroDigit();1650int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero1651char grouping = symbols.getGroupingSeparator();1652char decimal = isCurrencyFormat ?1653symbols.getMonetaryDecimalSeparator() :1654symbols.getDecimalSeparator();16551656/* Per bug 4147706, DecimalFormat must respect the sign of numbers which1657* format as zero. This allows sensible computations and preserves1658* relations such as signum(1/x) = signum(x), where x is +Infinity or1659* -Infinity. Prior to this fix, we always formatted zero values as if1660* they were positive. Liu 7/6/98.1661*/1662if (digitList.isZero()) {1663digitList.decimalAt = 0; // Normalize1664}16651666if (isNegative) {1667append(result, negativePrefix, delegate,1668getNegativePrefixFieldPositions(), Field.SIGN);1669} else {1670append(result, positivePrefix, delegate,1671getPositivePrefixFieldPositions(), Field.SIGN);1672}16731674if (useExponentialNotation) {1675int iFieldStart = result.length();1676int iFieldEnd = -1;1677int fFieldStart = -1;16781679// Minimum integer digits are handled in exponential format by1680// adjusting the exponent. For example, 0.01234 with 3 minimum1681// integer digits is "123.4E-4".16821683// Maximum integer digits are interpreted as indicating the1684// repeating range. This is useful for engineering notation, in1685// which the exponent is restricted to a multiple of 3. For1686// example, 0.01234 with 3 maximum integer digits is "12.34e-3".1687// If maximum integer digits are > 1 and are larger than1688// minimum integer digits, then minimum integer digits are1689// ignored.1690int exponent = digitList.decimalAt;1691int repeat = maxIntDigits;1692int minimumIntegerDigits = minIntDigits;1693if (repeat > 1 && repeat > minIntDigits) {1694// A repeating range is defined; adjust to it as follows.1695// If repeat == 3, we have 6,5,4=>3; 3,2,1=>0; 0,-1,-2=>-3;1696// -3,-4,-5=>-6, etc. This takes into account that the1697// exponent we have here is off by one from what we expect;1698// it is for the format 0.MMMMMx10^n.1699if (exponent >= 1) {1700exponent = ((exponent - 1) / repeat) * repeat;1701} else {1702// integer division rounds towards 01703exponent = ((exponent - repeat) / repeat) * repeat;1704}1705minimumIntegerDigits = 1;1706} else {1707// No repeating range is defined; use minimum integer digits.1708exponent -= minimumIntegerDigits;1709}17101711// We now output a minimum number of digits, and more if there1712// are more digits, up to the maximum number of digits. We1713// place the decimal point after the "integer" digits, which1714// are the first (decimalAt - exponent) digits.1715int minimumDigits = minIntDigits + minFraDigits;1716if (minimumDigits < 0) { // overflow?1717minimumDigits = Integer.MAX_VALUE;1718}17191720// The number of integer digits is handled specially if the number1721// is zero, since then there may be no digits.1722int integerDigits = digitList.isZero() ? minimumIntegerDigits :1723digitList.decimalAt - exponent;1724if (minimumDigits < integerDigits) {1725minimumDigits = integerDigits;1726}1727int totalDigits = digitList.count;1728if (minimumDigits > totalDigits) {1729totalDigits = minimumDigits;1730}1731boolean addedDecimalSeparator = false;17321733for (int i=0; i<totalDigits; ++i) {1734if (i == integerDigits) {1735// Record field information for caller.1736iFieldEnd = result.length();17371738result.append(decimal);1739addedDecimalSeparator = true;17401741// Record field information for caller.1742fFieldStart = result.length();1743}1744result.append((i < digitList.count) ?1745(char)(digitList.digits[i] + zeroDelta) :1746zero);1747}17481749if (decimalSeparatorAlwaysShown && totalDigits == integerDigits) {1750// Record field information for caller.1751iFieldEnd = result.length();17521753result.append(decimal);1754addedDecimalSeparator = true;17551756// Record field information for caller.1757fFieldStart = result.length();1758}17591760// Record field information1761if (iFieldEnd == -1) {1762iFieldEnd = result.length();1763}1764delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,1765iFieldStart, iFieldEnd, result);1766if (addedDecimalSeparator) {1767delegate.formatted(Field.DECIMAL_SEPARATOR,1768Field.DECIMAL_SEPARATOR,1769iFieldEnd, fFieldStart, result);1770}1771if (fFieldStart == -1) {1772fFieldStart = result.length();1773}1774delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,1775fFieldStart, result.length(), result);17761777// The exponent is output using the pattern-specified minimum1778// exponent digits. There is no maximum limit to the exponent1779// digits, since truncating the exponent would result in an1780// unacceptable inaccuracy.1781int fieldStart = result.length();17821783result.append(symbols.getExponentSeparator());17841785delegate.formatted(Field.EXPONENT_SYMBOL, Field.EXPONENT_SYMBOL,1786fieldStart, result.length(), result);17871788// For zero values, we force the exponent to zero. We1789// must do this here, and not earlier, because the value1790// is used to determine integer digit count above.1791if (digitList.isZero()) {1792exponent = 0;1793}17941795boolean negativeExponent = exponent < 0;1796if (negativeExponent) {1797exponent = -exponent;1798fieldStart = result.length();1799result.append(symbols.getMinusSign());1800delegate.formatted(Field.EXPONENT_SIGN, Field.EXPONENT_SIGN,1801fieldStart, result.length(), result);1802}1803digitList.set(negativeExponent, exponent);18041805int eFieldStart = result.length();18061807for (int i=digitList.decimalAt; i<minExponentDigits; ++i) {1808result.append(zero);1809}1810for (int i=0; i<digitList.decimalAt; ++i) {1811result.append((i < digitList.count) ?1812(char)(digitList.digits[i] + zeroDelta) : zero);1813}1814delegate.formatted(Field.EXPONENT, Field.EXPONENT, eFieldStart,1815result.length(), result);1816} else {1817int iFieldStart = result.length();18181819// Output the integer portion. Here 'count' is the total1820// number of integer digits we will display, including both1821// leading zeros required to satisfy getMinimumIntegerDigits,1822// and actual digits present in the number.1823int count = minIntDigits;1824int digitIndex = 0; // Index into digitList.fDigits[]1825if (digitList.decimalAt > 0 && count < digitList.decimalAt) {1826count = digitList.decimalAt;1827}18281829// Handle the case where getMaximumIntegerDigits() is smaller1830// than the real number of integer digits. If this is so, we1831// output the least significant max integer digits. For example,1832// the value 1997 printed with 2 max integer digits is just "97".1833if (count > maxIntDigits) {1834count = maxIntDigits;1835digitIndex = digitList.decimalAt - count;1836}18371838int sizeBeforeIntegerPart = result.length();1839for (int i=count-1; i>=0; --i) {1840if (i < digitList.decimalAt && digitIndex < digitList.count) {1841// Output a real digit1842result.append((char)(digitList.digits[digitIndex++] + zeroDelta));1843} else {1844// Output a leading zero1845result.append(zero);1846}18471848// Output grouping separator if necessary. Don't output a1849// grouping separator if i==0 though; that's at the end of1850// the integer part.1851if (isGroupingUsed() && i>0 && (groupingSize != 0) &&1852(i % groupingSize == 0)) {1853int gStart = result.length();1854result.append(grouping);1855delegate.formatted(Field.GROUPING_SEPARATOR,1856Field.GROUPING_SEPARATOR, gStart,1857result.length(), result);1858}1859}18601861// Determine whether or not there are any printable fractional1862// digits. If we've used up the digits we know there aren't.1863boolean fractionPresent = (minFraDigits > 0) ||1864(!isInteger && digitIndex < digitList.count);18651866// If there is no fraction present, and we haven't printed any1867// integer digits, then print a zero. Otherwise we won't print1868// _any_ digits, and we won't be able to parse this string.1869if (!fractionPresent && result.length() == sizeBeforeIntegerPart) {1870result.append(zero);1871}18721873delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,1874iFieldStart, result.length(), result);18751876// Output the decimal separator if we always do so.1877int sStart = result.length();1878if (decimalSeparatorAlwaysShown || fractionPresent) {1879result.append(decimal);1880}18811882if (sStart != result.length()) {1883delegate.formatted(Field.DECIMAL_SEPARATOR,1884Field.DECIMAL_SEPARATOR,1885sStart, result.length(), result);1886}1887int fFieldStart = result.length();18881889for (int i=0; i < maxFraDigits; ++i) {1890// Here is where we escape from the loop. We escape if we've1891// output the maximum fraction digits (specified in the for1892// expression above).1893// We also stop when we've output the minimum digits and either:1894// we have an integer, so there is no fractional stuff to1895// display, or we're out of significant digits.1896if (i >= minFraDigits &&1897(isInteger || digitIndex >= digitList.count)) {1898break;1899}19001901// Output leading fractional zeros. These are zeros that come1902// after the decimal but before any significant digits. These1903// are only output if abs(number being formatted) < 1.0.1904if (-1-i > (digitList.decimalAt-1)) {1905result.append(zero);1906continue;1907}19081909// Output a digit, if we have any precision left, or a1910// zero if we don't. We don't want to output noise digits.1911if (!isInteger && digitIndex < digitList.count) {1912result.append((char)(digitList.digits[digitIndex++] + zeroDelta));1913} else {1914result.append(zero);1915}1916}19171918// Record field information for caller.1919delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,1920fFieldStart, result.length(), result);1921}19221923if (isNegative) {1924append(result, negativeSuffix, delegate,1925getNegativeSuffixFieldPositions(), Field.SIGN);1926} else {1927append(result, positiveSuffix, delegate,1928getPositiveSuffixFieldPositions(), Field.SIGN);1929}19301931return result;1932}19331934/**1935* Appends the String <code>string</code> to <code>result</code>.1936* <code>delegate</code> is notified of all the1937* <code>FieldPosition</code>s in <code>positions</code>.1938* <p>1939* If one of the <code>FieldPosition</code>s in <code>positions</code>1940* identifies a <code>SIGN</code> attribute, it is mapped to1941* <code>signAttribute</code>. This is used1942* to map the <code>SIGN</code> attribute to the <code>EXPONENT</code>1943* attribute as necessary.1944* <p>1945* This is used by <code>subformat</code> to add the prefix/suffix.1946*/1947private void append(StringBuffer result, String string,1948FieldDelegate delegate,1949FieldPosition[] positions,1950Format.Field signAttribute) {1951int start = result.length();19521953if (string.length() > 0) {1954result.append(string);1955for (int counter = 0, max = positions.length; counter < max;1956counter++) {1957FieldPosition fp = positions[counter];1958Format.Field attribute = fp.getFieldAttribute();19591960if (attribute == Field.SIGN) {1961attribute = signAttribute;1962}1963delegate.formatted(attribute, attribute,1964start + fp.getBeginIndex(),1965start + fp.getEndIndex(), result);1966}1967}1968}19691970/**1971* Parses text from a string to produce a <code>Number</code>.1972* <p>1973* The method attempts to parse text starting at the index given by1974* <code>pos</code>.1975* If parsing succeeds, then the index of <code>pos</code> is updated1976* to the index after the last character used (parsing does not necessarily1977* use all characters up to the end of the string), and the parsed1978* number is returned. The updated <code>pos</code> can be used to1979* indicate the starting point for the next call to this method.1980* If an error occurs, then the index of <code>pos</code> is not1981* changed, the error index of <code>pos</code> is set to the index of1982* the character where the error occurred, and null is returned.1983* <p>1984* The subclass returned depends on the value of {@link #isParseBigDecimal}1985* as well as on the string being parsed.1986* <ul>1987* <li>If <code>isParseBigDecimal()</code> is false (the default),1988* most integer values are returned as <code>Long</code>1989* objects, no matter how they are written: <code>"17"</code> and1990* <code>"17.000"</code> both parse to <code>Long(17)</code>.1991* Values that cannot fit into a <code>Long</code> are returned as1992* <code>Double</code>s. This includes values with a fractional part,1993* infinite values, <code>NaN</code>, and the value -0.0.1994* <code>DecimalFormat</code> does <em>not</em> decide whether to1995* return a <code>Double</code> or a <code>Long</code> based on the1996* presence of a decimal separator in the source string. Doing so1997* would prevent integers that overflow the mantissa of a double,1998* such as <code>"-9,223,372,036,854,775,808.00"</code>, from being1999* parsed accurately.2000* <p>2001* Callers may use the <code>Number</code> methods2002* <code>doubleValue</code>, <code>longValue</code>, etc., to obtain2003* the type they want.2004* <li>If <code>isParseBigDecimal()</code> is true, values are returned2005* as <code>BigDecimal</code> objects. The values are the ones2006* constructed by {@link java.math.BigDecimal#BigDecimal(String)}2007* for corresponding strings in locale-independent format. The2008* special cases negative and positive infinity and NaN are returned2009* as <code>Double</code> instances holding the values of the2010* corresponding <code>Double</code> constants.2011* </ul>2012* <p>2013* <code>DecimalFormat</code> parses all Unicode characters that represent2014* decimal digits, as defined by <code>Character.digit()</code>. In2015* addition, <code>DecimalFormat</code> also recognizes as digits the ten2016* consecutive characters starting with the localized zero digit defined in2017* the <code>DecimalFormatSymbols</code> object.2018*2019* @param text the string to be parsed2020* @param pos A <code>ParsePosition</code> object with index and error2021* index information as described above.2022* @return the parsed value, or <code>null</code> if the parse fails2023* @exception NullPointerException if <code>text</code> or2024* <code>pos</code> is null.2025*/2026@Override2027public Number parse(String text, ParsePosition pos) {2028// special case NaN2029if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) {2030pos.index = pos.index + symbols.getNaN().length();2031return new Double(Double.NaN);2032}20332034boolean[] status = new boolean[STATUS_LENGTH];2035if (!subparse(text, pos, positivePrefix, negativePrefix, digitList, false, status)) {2036return null;2037}20382039// special case INFINITY2040if (status[STATUS_INFINITE]) {2041if (status[STATUS_POSITIVE] == (multiplier >= 0)) {2042return new Double(Double.POSITIVE_INFINITY);2043} else {2044return new Double(Double.NEGATIVE_INFINITY);2045}2046}20472048if (multiplier == 0) {2049if (digitList.isZero()) {2050return new Double(Double.NaN);2051} else if (status[STATUS_POSITIVE]) {2052return new Double(Double.POSITIVE_INFINITY);2053} else {2054return new Double(Double.NEGATIVE_INFINITY);2055}2056}20572058if (isParseBigDecimal()) {2059BigDecimal bigDecimalResult = digitList.getBigDecimal();20602061if (multiplier != 1) {2062try {2063bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier());2064}2065catch (ArithmeticException e) { // non-terminating decimal expansion2066bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier(), roundingMode);2067}2068}20692070if (!status[STATUS_POSITIVE]) {2071bigDecimalResult = bigDecimalResult.negate();2072}2073return bigDecimalResult;2074} else {2075boolean gotDouble = true;2076boolean gotLongMinimum = false;2077double doubleResult = 0.0;2078long longResult = 0;20792080// Finally, have DigitList parse the digits into a value.2081if (digitList.fitsIntoLong(status[STATUS_POSITIVE], isParseIntegerOnly())) {2082gotDouble = false;2083longResult = digitList.getLong();2084if (longResult < 0) { // got Long.MIN_VALUE2085gotLongMinimum = true;2086}2087} else {2088doubleResult = digitList.getDouble();2089}20902091// Divide by multiplier. We have to be careful here not to do2092// unneeded conversions between double and long.2093if (multiplier != 1) {2094if (gotDouble) {2095doubleResult /= multiplier;2096} else {2097// Avoid converting to double if we can2098if (longResult % multiplier == 0) {2099longResult /= multiplier;2100} else {2101doubleResult = ((double)longResult) / multiplier;2102gotDouble = true;2103}2104}2105}21062107if (!status[STATUS_POSITIVE] && !gotLongMinimum) {2108doubleResult = -doubleResult;2109longResult = -longResult;2110}21112112// At this point, if we divided the result by the multiplier, the2113// result may fit into a long. We check for this case and return2114// a long if possible.2115// We must do this AFTER applying the negative (if appropriate)2116// in order to handle the case of LONG_MIN; otherwise, if we do2117// this with a positive value -LONG_MIN, the double is > 0, but2118// the long is < 0. We also must retain a double in the case of2119// -0.0, which will compare as == to a long 0 cast to a double2120// (bug 4162852).2121if (multiplier != 1 && gotDouble) {2122longResult = (long)doubleResult;2123gotDouble = ((doubleResult != (double)longResult) ||2124(doubleResult == 0.0 && 1/doubleResult < 0.0)) &&2125!isParseIntegerOnly();2126}21272128return gotDouble ?2129(Number)new Double(doubleResult) : (Number)new Long(longResult);2130}2131}21322133/**2134* Return a BigInteger multiplier.2135*/2136private BigInteger getBigIntegerMultiplier() {2137if (bigIntegerMultiplier == null) {2138bigIntegerMultiplier = BigInteger.valueOf(multiplier);2139}2140return bigIntegerMultiplier;2141}2142private transient BigInteger bigIntegerMultiplier;21432144/**2145* Return a BigDecimal multiplier.2146*/2147private BigDecimal getBigDecimalMultiplier() {2148if (bigDecimalMultiplier == null) {2149bigDecimalMultiplier = new BigDecimal(multiplier);2150}2151return bigDecimalMultiplier;2152}2153private transient BigDecimal bigDecimalMultiplier;21542155private static final int STATUS_INFINITE = 0;2156private static final int STATUS_POSITIVE = 1;2157private static final int STATUS_LENGTH = 2;21582159/**2160* Parse the given text into a number. The text is parsed beginning at2161* parsePosition, until an unparseable character is seen.2162* @param text The string to parse.2163* @param parsePosition The position at which to being parsing. Upon2164* return, the first unparseable character.2165* @param digits The DigitList to set to the parsed value.2166* @param isExponent If true, parse an exponent. This means no2167* infinite values and integer only.2168* @param status Upon return contains boolean status flags indicating2169* whether the value was infinite and whether it was positive.2170*/2171private final boolean subparse(String text, ParsePosition parsePosition,2172String positivePrefix, String negativePrefix,2173DigitList digits, boolean isExponent,2174boolean status[]) {2175int position = parsePosition.index;2176int oldStart = parsePosition.index;2177int backup;2178boolean gotPositive, gotNegative;21792180// check for positivePrefix; take longest2181gotPositive = text.regionMatches(position, positivePrefix, 0,2182positivePrefix.length());2183gotNegative = text.regionMatches(position, negativePrefix, 0,2184negativePrefix.length());21852186if (gotPositive && gotNegative) {2187if (positivePrefix.length() > negativePrefix.length()) {2188gotNegative = false;2189} else if (positivePrefix.length() < negativePrefix.length()) {2190gotPositive = false;2191}2192}21932194if (gotPositive) {2195position += positivePrefix.length();2196} else if (gotNegative) {2197position += negativePrefix.length();2198} else {2199parsePosition.errorIndex = position;2200return false;2201}22022203// process digits or Inf, find decimal position2204status[STATUS_INFINITE] = false;2205if (!isExponent && text.regionMatches(position,symbols.getInfinity(),0,2206symbols.getInfinity().length())) {2207position += symbols.getInfinity().length();2208status[STATUS_INFINITE] = true;2209} else {2210// We now have a string of digits, possibly with grouping symbols,2211// and decimal points. We want to process these into a DigitList.2212// We don't want to put a bunch of leading zeros into the DigitList2213// though, so we keep track of the location of the decimal point,2214// put only significant digits into the DigitList, and adjust the2215// exponent as needed.22162217digits.decimalAt = digits.count = 0;2218char zero = symbols.getZeroDigit();2219char decimal = isCurrencyFormat ?2220symbols.getMonetaryDecimalSeparator() :2221symbols.getDecimalSeparator();2222char grouping = symbols.getGroupingSeparator();2223String exponentString = symbols.getExponentSeparator();2224boolean sawDecimal = false;2225boolean sawExponent = false;2226boolean sawDigit = false;2227int exponent = 0; // Set to the exponent value, if any22282229// We have to track digitCount ourselves, because digits.count will2230// pin when the maximum allowable digits is reached.2231int digitCount = 0;22322233backup = -1;2234for (; position < text.length(); ++position) {2235char ch = text.charAt(position);22362237/* We recognize all digit ranges, not only the Latin digit range2238* '0'..'9'. We do so by using the Character.digit() method,2239* which converts a valid Unicode digit to the range 0..9.2240*2241* The character 'ch' may be a digit. If so, place its value2242* from 0 to 9 in 'digit'. First try using the locale digit,2243* which may or MAY NOT be a standard Unicode digit range. If2244* this fails, try using the standard Unicode digit ranges by2245* calling Character.digit(). If this also fails, digit will2246* have a value outside the range 0..9.2247*/2248int digit = ch - zero;2249if (digit < 0 || digit > 9) {2250digit = Character.digit(ch, 10);2251}22522253if (digit == 0) {2254// Cancel out backup setting (see grouping handler below)2255backup = -1; // Do this BEFORE continue statement below!!!2256sawDigit = true;22572258// Handle leading zeros2259if (digits.count == 0) {2260// Ignore leading zeros in integer part of number.2261if (!sawDecimal) {2262continue;2263}22642265// If we have seen the decimal, but no significant2266// digits yet, then we account for leading zeros by2267// decrementing the digits.decimalAt into negative2268// values.2269--digits.decimalAt;2270} else {2271++digitCount;2272digits.append((char)(digit + '0'));2273}2274} else if (digit > 0 && digit <= 9) { // [sic] digit==0 handled above2275sawDigit = true;2276++digitCount;2277digits.append((char)(digit + '0'));22782279// Cancel out backup setting (see grouping handler below)2280backup = -1;2281} else if (!isExponent && ch == decimal) {2282// If we're only parsing integers, or if we ALREADY saw the2283// decimal, then don't parse this one.2284if (isParseIntegerOnly() || sawDecimal) {2285break;2286}2287digits.decimalAt = digitCount; // Not digits.count!2288sawDecimal = true;2289} else if (!isExponent && ch == grouping && isGroupingUsed()) {2290if (sawDecimal) {2291break;2292}2293// Ignore grouping characters, if we are using them, but2294// require that they be followed by a digit. Otherwise2295// we backup and reprocess them.2296backup = position;2297} else if (!isExponent && text.regionMatches(position, exponentString, 0, exponentString.length())2298&& !sawExponent) {2299// Process the exponent by recursively calling this method.2300ParsePosition pos = new ParsePosition(position + exponentString.length());2301boolean[] stat = new boolean[STATUS_LENGTH];2302DigitList exponentDigits = new DigitList();23032304if (subparse(text, pos, "", Character.toString(symbols.getMinusSign()), exponentDigits, true, stat) &&2305exponentDigits.fitsIntoLong(stat[STATUS_POSITIVE], true)) {2306position = pos.index; // Advance past the exponent2307exponent = (int)exponentDigits.getLong();2308if (!stat[STATUS_POSITIVE]) {2309exponent = -exponent;2310}2311sawExponent = true;2312}2313break; // Whether we fail or succeed, we exit this loop2314} else {2315break;2316}2317}23182319if (backup != -1) {2320position = backup;2321}23222323// If there was no decimal point we have an integer2324if (!sawDecimal) {2325digits.decimalAt = digitCount; // Not digits.count!2326}23272328// Adjust for exponent, if any2329digits.decimalAt += exponent;23302331// If none of the text string was recognized. For example, parse2332// "x" with pattern "#0.00" (return index and error index both 0)2333// parse "$" with pattern "$#0.00". (return index 0 and error2334// index 1).2335if (!sawDigit && digitCount == 0) {2336parsePosition.index = oldStart;2337parsePosition.errorIndex = oldStart;2338return false;2339}2340}23412342// check for suffix2343if (!isExponent) {2344if (gotPositive) {2345gotPositive = text.regionMatches(position,positiveSuffix,0,2346positiveSuffix.length());2347}2348if (gotNegative) {2349gotNegative = text.regionMatches(position,negativeSuffix,0,2350negativeSuffix.length());2351}23522353// if both match, take longest2354if (gotPositive && gotNegative) {2355if (positiveSuffix.length() > negativeSuffix.length()) {2356gotNegative = false;2357} else if (positiveSuffix.length() < negativeSuffix.length()) {2358gotPositive = false;2359}2360}23612362// fail if neither or both2363if (gotPositive == gotNegative) {2364parsePosition.errorIndex = position;2365return false;2366}23672368parsePosition.index = position +2369(gotPositive ? positiveSuffix.length() : negativeSuffix.length()); // mark success!2370} else {2371parsePosition.index = position;2372}23732374status[STATUS_POSITIVE] = gotPositive;2375if (parsePosition.index == oldStart) {2376parsePosition.errorIndex = position;2377return false;2378}2379return true;2380}23812382/**2383* Returns a copy of the decimal format symbols, which is generally not2384* changed by the programmer or user.2385* @return a copy of the desired DecimalFormatSymbols2386* @see java.text.DecimalFormatSymbols2387*/2388public DecimalFormatSymbols getDecimalFormatSymbols() {2389try {2390// don't allow multiple references2391return (DecimalFormatSymbols) symbols.clone();2392} catch (Exception foo) {2393return null; // should never happen2394}2395}239623972398/**2399* Sets the decimal format symbols, which is generally not changed2400* by the programmer or user.2401* @param newSymbols desired DecimalFormatSymbols2402* @see java.text.DecimalFormatSymbols2403*/2404public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {2405try {2406// don't allow multiple references2407symbols = (DecimalFormatSymbols) newSymbols.clone();2408expandAffixes();2409fastPathCheckNeeded = true;2410} catch (Exception foo) {2411// should never happen2412}2413}24142415/**2416* Get the positive prefix.2417* <P>Examples: +123, $123, sFr1232418*2419* @return the positive prefix2420*/2421public String getPositivePrefix () {2422return positivePrefix;2423}24242425/**2426* Set the positive prefix.2427* <P>Examples: +123, $123, sFr1232428*2429* @param newValue the new positive prefix2430*/2431public void setPositivePrefix (String newValue) {2432positivePrefix = newValue;2433posPrefixPattern = null;2434positivePrefixFieldPositions = null;2435fastPathCheckNeeded = true;2436}24372438/**2439* Returns the FieldPositions of the fields in the prefix used for2440* positive numbers. This is not used if the user has explicitly set2441* a positive prefix via <code>setPositivePrefix</code>. This is2442* lazily created.2443*2444* @return FieldPositions in positive prefix2445*/2446private FieldPosition[] getPositivePrefixFieldPositions() {2447if (positivePrefixFieldPositions == null) {2448if (posPrefixPattern != null) {2449positivePrefixFieldPositions = expandAffix(posPrefixPattern);2450} else {2451positivePrefixFieldPositions = EmptyFieldPositionArray;2452}2453}2454return positivePrefixFieldPositions;2455}24562457/**2458* Get the negative prefix.2459* <P>Examples: -123, ($123) (with negative suffix), sFr-1232460*2461* @return the negative prefix2462*/2463public String getNegativePrefix () {2464return negativePrefix;2465}24662467/**2468* Set the negative prefix.2469* <P>Examples: -123, ($123) (with negative suffix), sFr-1232470*2471* @param newValue the new negative prefix2472*/2473public void setNegativePrefix (String newValue) {2474negativePrefix = newValue;2475negPrefixPattern = null;2476fastPathCheckNeeded = true;2477}24782479/**2480* Returns the FieldPositions of the fields in the prefix used for2481* negative numbers. This is not used if the user has explicitly set2482* a negative prefix via <code>setNegativePrefix</code>. This is2483* lazily created.2484*2485* @return FieldPositions in positive prefix2486*/2487private FieldPosition[] getNegativePrefixFieldPositions() {2488if (negativePrefixFieldPositions == null) {2489if (negPrefixPattern != null) {2490negativePrefixFieldPositions = expandAffix(negPrefixPattern);2491} else {2492negativePrefixFieldPositions = EmptyFieldPositionArray;2493}2494}2495return negativePrefixFieldPositions;2496}24972498/**2499* Get the positive suffix.2500* <P>Example: 123%2501*2502* @return the positive suffix2503*/2504public String getPositiveSuffix () {2505return positiveSuffix;2506}25072508/**2509* Set the positive suffix.2510* <P>Example: 123%2511*2512* @param newValue the new positive suffix2513*/2514public void setPositiveSuffix (String newValue) {2515positiveSuffix = newValue;2516posSuffixPattern = null;2517fastPathCheckNeeded = true;2518}25192520/**2521* Returns the FieldPositions of the fields in the suffix used for2522* positive numbers. This is not used if the user has explicitly set2523* a positive suffix via <code>setPositiveSuffix</code>. This is2524* lazily created.2525*2526* @return FieldPositions in positive prefix2527*/2528private FieldPosition[] getPositiveSuffixFieldPositions() {2529if (positiveSuffixFieldPositions == null) {2530if (posSuffixPattern != null) {2531positiveSuffixFieldPositions = expandAffix(posSuffixPattern);2532} else {2533positiveSuffixFieldPositions = EmptyFieldPositionArray;2534}2535}2536return positiveSuffixFieldPositions;2537}25382539/**2540* Get the negative suffix.2541* <P>Examples: -123%, ($123) (with positive suffixes)2542*2543* @return the negative suffix2544*/2545public String getNegativeSuffix () {2546return negativeSuffix;2547}25482549/**2550* Set the negative suffix.2551* <P>Examples: 123%2552*2553* @param newValue the new negative suffix2554*/2555public void setNegativeSuffix (String newValue) {2556negativeSuffix = newValue;2557negSuffixPattern = null;2558fastPathCheckNeeded = true;2559}25602561/**2562* Returns the FieldPositions of the fields in the suffix used for2563* negative numbers. This is not used if the user has explicitly set2564* a negative suffix via <code>setNegativeSuffix</code>. This is2565* lazily created.2566*2567* @return FieldPositions in positive prefix2568*/2569private FieldPosition[] getNegativeSuffixFieldPositions() {2570if (negativeSuffixFieldPositions == null) {2571if (negSuffixPattern != null) {2572negativeSuffixFieldPositions = expandAffix(negSuffixPattern);2573} else {2574negativeSuffixFieldPositions = EmptyFieldPositionArray;2575}2576}2577return negativeSuffixFieldPositions;2578}25792580/**2581* Gets the multiplier for use in percent, per mille, and similar2582* formats.2583*2584* @return the multiplier2585* @see #setMultiplier(int)2586*/2587public int getMultiplier () {2588return multiplier;2589}25902591/**2592* Sets the multiplier for use in percent, per mille, and similar2593* formats.2594* For a percent format, set the multiplier to 100 and the suffixes to2595* have '%' (for Arabic, use the Arabic percent sign).2596* For a per mille format, set the multiplier to 1000 and the suffixes to2597* have '\u2030'.2598*2599* <P>Example: with multiplier 100, 1.23 is formatted as "123", and2600* "123" is parsed into 1.23.2601*2602* @param newValue the new multiplier2603* @see #getMultiplier2604*/2605public void setMultiplier (int newValue) {2606multiplier = newValue;2607bigDecimalMultiplier = null;2608bigIntegerMultiplier = null;2609fastPathCheckNeeded = true;2610}26112612/**2613* {@inheritDoc}2614*/2615@Override2616public void setGroupingUsed(boolean newValue) {2617super.setGroupingUsed(newValue);2618fastPathCheckNeeded = true;2619}26202621/**2622* Return the grouping size. Grouping size is the number of digits between2623* grouping separators in the integer portion of a number. For example,2624* in the number "123,456.78", the grouping size is 3.2625*2626* @return the grouping size2627* @see #setGroupingSize2628* @see java.text.NumberFormat#isGroupingUsed2629* @see java.text.DecimalFormatSymbols#getGroupingSeparator2630*/2631public int getGroupingSize () {2632return groupingSize;2633}26342635/**2636* Set the grouping size. Grouping size is the number of digits between2637* grouping separators in the integer portion of a number. For example,2638* in the number "123,456.78", the grouping size is 3.2639* <br>2640* The value passed in is converted to a byte, which may lose information.2641*2642* @param newValue the new grouping size2643* @see #getGroupingSize2644* @see java.text.NumberFormat#setGroupingUsed2645* @see java.text.DecimalFormatSymbols#setGroupingSeparator2646*/2647public void setGroupingSize (int newValue) {2648groupingSize = (byte)newValue;2649fastPathCheckNeeded = true;2650}26512652/**2653* Allows you to get the behavior of the decimal separator with integers.2654* (The decimal separator will always appear with decimals.)2655* <P>Example: Decimal ON: 12345 → 12345.; OFF: 12345 → 123452656*2657* @return {@code true} if the decimal separator is always shown;2658* {@code false} otherwise2659*/2660public boolean isDecimalSeparatorAlwaysShown() {2661return decimalSeparatorAlwaysShown;2662}26632664/**2665* Allows you to set the behavior of the decimal separator with integers.2666* (The decimal separator will always appear with decimals.)2667* <P>Example: Decimal ON: 12345 → 12345.; OFF: 12345 → 123452668*2669* @param newValue {@code true} if the decimal separator is always shown;2670* {@code false} otherwise2671*/2672public void setDecimalSeparatorAlwaysShown(boolean newValue) {2673decimalSeparatorAlwaysShown = newValue;2674fastPathCheckNeeded = true;2675}26762677/**2678* Returns whether the {@link #parse(java.lang.String, java.text.ParsePosition)}2679* method returns <code>BigDecimal</code>. The default value is false.2680*2681* @return {@code true} if the parse method returns BigDecimal;2682* {@code false} otherwise2683* @see #setParseBigDecimal2684* @since 1.52685*/2686public boolean isParseBigDecimal() {2687return parseBigDecimal;2688}26892690/**2691* Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)}2692* method returns <code>BigDecimal</code>.2693*2694* @param newValue {@code true} if the parse method returns BigDecimal;2695* {@code false} otherwise2696* @see #isParseBigDecimal2697* @since 1.52698*/2699public void setParseBigDecimal(boolean newValue) {2700parseBigDecimal = newValue;2701}27022703/**2704* Standard override; no change in semantics.2705*/2706@Override2707public Object clone() {2708DecimalFormat other = (DecimalFormat) super.clone();2709other.symbols = (DecimalFormatSymbols) symbols.clone();2710other.digitList = (DigitList) digitList.clone();27112712// Fast-path is almost stateless algorithm. The only logical state is the2713// isFastPath flag. In addition fastPathCheckNeeded is a sentinel flag2714// that forces recalculation of all fast-path fields when set to true.2715//2716// There is thus no need to clone all the fast-path fields.2717// We just only need to set fastPathCheckNeeded to true when cloning,2718// and init fastPathData to null as if it were a truly new instance.2719// Every fast-path field will be recalculated (only once) at next usage of2720// fast-path algorithm.2721other.fastPathCheckNeeded = true;2722other.isFastPath = false;2723other.fastPathData = null;27242725return other;2726}27272728/**2729* Overrides equals2730*/2731@Override2732public boolean equals(Object obj)2733{2734if (obj == null)2735return false;2736if (!super.equals(obj))2737return false; // super does class check2738DecimalFormat other = (DecimalFormat) obj;2739return ((posPrefixPattern == other.posPrefixPattern &&2740positivePrefix.equals(other.positivePrefix))2741|| (posPrefixPattern != null &&2742posPrefixPattern.equals(other.posPrefixPattern)))2743&& ((posSuffixPattern == other.posSuffixPattern &&2744positiveSuffix.equals(other.positiveSuffix))2745|| (posSuffixPattern != null &&2746posSuffixPattern.equals(other.posSuffixPattern)))2747&& ((negPrefixPattern == other.negPrefixPattern &&2748negativePrefix.equals(other.negativePrefix))2749|| (negPrefixPattern != null &&2750negPrefixPattern.equals(other.negPrefixPattern)))2751&& ((negSuffixPattern == other.negSuffixPattern &&2752negativeSuffix.equals(other.negativeSuffix))2753|| (negSuffixPattern != null &&2754negSuffixPattern.equals(other.negSuffixPattern)))2755&& multiplier == other.multiplier2756&& groupingSize == other.groupingSize2757&& decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown2758&& parseBigDecimal == other.parseBigDecimal2759&& useExponentialNotation == other.useExponentialNotation2760&& (!useExponentialNotation ||2761minExponentDigits == other.minExponentDigits)2762&& maximumIntegerDigits == other.maximumIntegerDigits2763&& minimumIntegerDigits == other.minimumIntegerDigits2764&& maximumFractionDigits == other.maximumFractionDigits2765&& minimumFractionDigits == other.minimumFractionDigits2766&& roundingMode == other.roundingMode2767&& symbols.equals(other.symbols);2768}27692770/**2771* Overrides hashCode2772*/2773@Override2774public int hashCode() {2775return super.hashCode() * 37 + positivePrefix.hashCode();2776// just enough fields for a reasonable distribution2777}27782779/**2780* Synthesizes a pattern string that represents the current state2781* of this Format object.2782*2783* @return a pattern string2784* @see #applyPattern2785*/2786public String toPattern() {2787return toPattern( false );2788}27892790/**2791* Synthesizes a localized pattern string that represents the current2792* state of this Format object.2793*2794* @return a localized pattern string2795* @see #applyPattern2796*/2797public String toLocalizedPattern() {2798return toPattern( true );2799}28002801/**2802* Expand the affix pattern strings into the expanded affix strings. If any2803* affix pattern string is null, do not expand it. This method should be2804* called any time the symbols or the affix patterns change in order to keep2805* the expanded affix strings up to date.2806*/2807private void expandAffixes() {2808// Reuse one StringBuffer for better performance2809StringBuffer buffer = new StringBuffer();2810if (posPrefixPattern != null) {2811positivePrefix = expandAffix(posPrefixPattern, buffer);2812positivePrefixFieldPositions = null;2813}2814if (posSuffixPattern != null) {2815positiveSuffix = expandAffix(posSuffixPattern, buffer);2816positiveSuffixFieldPositions = null;2817}2818if (negPrefixPattern != null) {2819negativePrefix = expandAffix(negPrefixPattern, buffer);2820negativePrefixFieldPositions = null;2821}2822if (negSuffixPattern != null) {2823negativeSuffix = expandAffix(negSuffixPattern, buffer);2824negativeSuffixFieldPositions = null;2825}2826}28272828/**2829* Expand an affix pattern into an affix string. All characters in the2830* pattern are literal unless prefixed by QUOTE. The following characters2831* after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,2832* PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE +2833* CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 42172834* currency code. Any other character after a QUOTE represents itself.2835* QUOTE must be followed by another character; QUOTE may not occur by2836* itself at the end of the pattern.2837*2838* @param pattern the non-null, possibly empty pattern2839* @param buffer a scratch StringBuffer; its contents will be lost2840* @return the expanded equivalent of pattern2841*/2842private String expandAffix(String pattern, StringBuffer buffer) {2843buffer.setLength(0);2844for (int i=0; i<pattern.length(); ) {2845char c = pattern.charAt(i++);2846if (c == QUOTE) {2847c = pattern.charAt(i++);2848switch (c) {2849case CURRENCY_SIGN:2850if (i<pattern.length() &&2851pattern.charAt(i) == CURRENCY_SIGN) {2852++i;2853buffer.append(symbols.getInternationalCurrencySymbol());2854} else {2855buffer.append(symbols.getCurrencySymbol());2856}2857continue;2858case PATTERN_PERCENT:2859c = symbols.getPercent();2860break;2861case PATTERN_PER_MILLE:2862c = symbols.getPerMill();2863break;2864case PATTERN_MINUS:2865c = symbols.getMinusSign();2866break;2867}2868}2869buffer.append(c);2870}2871return buffer.toString();2872}28732874/**2875* Expand an affix pattern into an array of FieldPositions describing2876* how the pattern would be expanded.2877* All characters in the2878* pattern are literal unless prefixed by QUOTE. The following characters2879* after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,2880* PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE +2881* CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 42172882* currency code. Any other character after a QUOTE represents itself.2883* QUOTE must be followed by another character; QUOTE may not occur by2884* itself at the end of the pattern.2885*2886* @param pattern the non-null, possibly empty pattern2887* @return FieldPosition array of the resulting fields.2888*/2889private FieldPosition[] expandAffix(String pattern) {2890ArrayList<FieldPosition> positions = null;2891int stringIndex = 0;2892for (int i=0; i<pattern.length(); ) {2893char c = pattern.charAt(i++);2894if (c == QUOTE) {2895int field = -1;2896Format.Field fieldID = null;2897c = pattern.charAt(i++);2898switch (c) {2899case CURRENCY_SIGN:2900String string;2901if (i<pattern.length() &&2902pattern.charAt(i) == CURRENCY_SIGN) {2903++i;2904string = symbols.getInternationalCurrencySymbol();2905} else {2906string = symbols.getCurrencySymbol();2907}2908if (string.length() > 0) {2909if (positions == null) {2910positions = new ArrayList<>(2);2911}2912FieldPosition fp = new FieldPosition(Field.CURRENCY);2913fp.setBeginIndex(stringIndex);2914fp.setEndIndex(stringIndex + string.length());2915positions.add(fp);2916stringIndex += string.length();2917}2918continue;2919case PATTERN_PERCENT:2920c = symbols.getPercent();2921field = -1;2922fieldID = Field.PERCENT;2923break;2924case PATTERN_PER_MILLE:2925c = symbols.getPerMill();2926field = -1;2927fieldID = Field.PERMILLE;2928break;2929case PATTERN_MINUS:2930c = symbols.getMinusSign();2931field = -1;2932fieldID = Field.SIGN;2933break;2934}2935if (fieldID != null) {2936if (positions == null) {2937positions = new ArrayList<>(2);2938}2939FieldPosition fp = new FieldPosition(fieldID, field);2940fp.setBeginIndex(stringIndex);2941fp.setEndIndex(stringIndex + 1);2942positions.add(fp);2943}2944}2945stringIndex++;2946}2947if (positions != null) {2948return positions.toArray(EmptyFieldPositionArray);2949}2950return EmptyFieldPositionArray;2951}29522953/**2954* Appends an affix pattern to the given StringBuffer, quoting special2955* characters as needed. Uses the internal affix pattern, if that exists,2956* or the literal affix, if the internal affix pattern is null. The2957* appended string will generate the same affix pattern (or literal affix)2958* when passed to toPattern().2959*2960* @param buffer the affix string is appended to this2961* @param affixPattern a pattern such as posPrefixPattern; may be null2962* @param expAffix a corresponding expanded affix, such as positivePrefix.2963* Ignored unless affixPattern is null. If affixPattern is null, then2964* expAffix is appended as a literal affix.2965* @param localized true if the appended pattern should contain localized2966* pattern characters; otherwise, non-localized pattern chars are appended2967*/2968private void appendAffix(StringBuffer buffer, String affixPattern,2969String expAffix, boolean localized) {2970if (affixPattern == null) {2971appendAffix(buffer, expAffix, localized);2972} else {2973int i;2974for (int pos=0; pos<affixPattern.length(); pos=i) {2975i = affixPattern.indexOf(QUOTE, pos);2976if (i < 0) {2977appendAffix(buffer, affixPattern.substring(pos), localized);2978break;2979}2980if (i > pos) {2981appendAffix(buffer, affixPattern.substring(pos, i), localized);2982}2983char c = affixPattern.charAt(++i);2984++i;2985if (c == QUOTE) {2986buffer.append(c);2987// Fall through and append another QUOTE below2988} else if (c == CURRENCY_SIGN &&2989i<affixPattern.length() &&2990affixPattern.charAt(i) == CURRENCY_SIGN) {2991++i;2992buffer.append(c);2993// Fall through and append another CURRENCY_SIGN below2994} else if (localized) {2995switch (c) {2996case PATTERN_PERCENT:2997c = symbols.getPercent();2998break;2999case PATTERN_PER_MILLE:3000c = symbols.getPerMill();3001break;3002case PATTERN_MINUS:3003c = symbols.getMinusSign();3004break;3005}3006}3007buffer.append(c);3008}3009}3010}30113012/**3013* Append an affix to the given StringBuffer, using quotes if3014* there are special characters. Single quotes themselves must be3015* escaped in either case.3016*/3017private void appendAffix(StringBuffer buffer, String affix, boolean localized) {3018boolean needQuote;3019if (localized) {3020needQuote = affix.indexOf(symbols.getZeroDigit()) >= 03021|| affix.indexOf(symbols.getGroupingSeparator()) >= 03022|| affix.indexOf(symbols.getDecimalSeparator()) >= 03023|| affix.indexOf(symbols.getPercent()) >= 03024|| affix.indexOf(symbols.getPerMill()) >= 03025|| affix.indexOf(symbols.getDigit()) >= 03026|| affix.indexOf(symbols.getPatternSeparator()) >= 03027|| affix.indexOf(symbols.getMinusSign()) >= 03028|| affix.indexOf(CURRENCY_SIGN) >= 0;3029} else {3030needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 03031|| affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 03032|| affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 03033|| affix.indexOf(PATTERN_PERCENT) >= 03034|| affix.indexOf(PATTERN_PER_MILLE) >= 03035|| affix.indexOf(PATTERN_DIGIT) >= 03036|| affix.indexOf(PATTERN_SEPARATOR) >= 03037|| affix.indexOf(PATTERN_MINUS) >= 03038|| affix.indexOf(CURRENCY_SIGN) >= 0;3039}3040if (needQuote) buffer.append('\'');3041if (affix.indexOf('\'') < 0) buffer.append(affix);3042else {3043for (int j=0; j<affix.length(); ++j) {3044char c = affix.charAt(j);3045buffer.append(c);3046if (c == '\'') buffer.append(c);3047}3048}3049if (needQuote) buffer.append('\'');3050}30513052/**3053* Does the real work of generating a pattern. */3054private String toPattern(boolean localized) {3055StringBuffer result = new StringBuffer();3056for (int j = 1; j >= 0; --j) {3057if (j == 1)3058appendAffix(result, posPrefixPattern, positivePrefix, localized);3059else appendAffix(result, negPrefixPattern, negativePrefix, localized);3060int i;3061int digitCount = useExponentialNotation3062? getMaximumIntegerDigits()3063: Math.max(groupingSize, getMinimumIntegerDigits())+1;3064for (i = digitCount; i > 0; --i) {3065if (i != digitCount && isGroupingUsed() && groupingSize != 0 &&3066i % groupingSize == 0) {3067result.append(localized ? symbols.getGroupingSeparator() :3068PATTERN_GROUPING_SEPARATOR);3069}3070result.append(i <= getMinimumIntegerDigits()3071? (localized ? symbols.getZeroDigit() : PATTERN_ZERO_DIGIT)3072: (localized ? symbols.getDigit() : PATTERN_DIGIT));3073}3074if (getMaximumFractionDigits() > 0 || decimalSeparatorAlwaysShown)3075result.append(localized ? symbols.getDecimalSeparator() :3076PATTERN_DECIMAL_SEPARATOR);3077for (i = 0; i < getMaximumFractionDigits(); ++i) {3078if (i < getMinimumFractionDigits()) {3079result.append(localized ? symbols.getZeroDigit() :3080PATTERN_ZERO_DIGIT);3081} else {3082result.append(localized ? symbols.getDigit() :3083PATTERN_DIGIT);3084}3085}3086if (useExponentialNotation)3087{3088result.append(localized ? symbols.getExponentSeparator() :3089PATTERN_EXPONENT);3090for (i=0; i<minExponentDigits; ++i)3091result.append(localized ? symbols.getZeroDigit() :3092PATTERN_ZERO_DIGIT);3093}3094if (j == 1) {3095appendAffix(result, posSuffixPattern, positiveSuffix, localized);3096if ((negSuffixPattern == posSuffixPattern && // n == p == null3097negativeSuffix.equals(positiveSuffix))3098|| (negSuffixPattern != null &&3099negSuffixPattern.equals(posSuffixPattern))) {3100if ((negPrefixPattern != null && posPrefixPattern != null &&3101negPrefixPattern.equals("'-" + posPrefixPattern)) ||3102(negPrefixPattern == posPrefixPattern && // n == p == null3103negativePrefix.equals(symbols.getMinusSign() + positivePrefix)))3104break;3105}3106result.append(localized ? symbols.getPatternSeparator() :3107PATTERN_SEPARATOR);3108} else appendAffix(result, negSuffixPattern, negativeSuffix, localized);3109}3110return result.toString();3111}31123113/**3114* Apply the given pattern to this Format object. A pattern is a3115* short-hand specification for the various formatting properties.3116* These properties can also be changed individually through the3117* various setter methods.3118* <p>3119* There is no limit to integer digits set3120* by this routine, since that is the typical end-user desire;3121* use setMaximumInteger if you want to set a real value.3122* For negative numbers, use a second pattern, separated by a semicolon3123* <P>Example <code>"#,#00.0#"</code> → 1,234.563124* <P>This means a minimum of 2 integer digits, 1 fraction digit, and3125* a maximum of 2 fraction digits.3126* <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in3127* parentheses.3128* <p>In negative patterns, the minimum and maximum counts are ignored;3129* these are presumed to be set in the positive pattern.3130*3131* @param pattern a new pattern3132* @exception NullPointerException if <code>pattern</code> is null3133* @exception IllegalArgumentException if the given pattern is invalid.3134*/3135public void applyPattern(String pattern) {3136applyPattern(pattern, false);3137}31383139/**3140* Apply the given pattern to this Format object. The pattern3141* is assumed to be in a localized notation. A pattern is a3142* short-hand specification for the various formatting properties.3143* These properties can also be changed individually through the3144* various setter methods.3145* <p>3146* There is no limit to integer digits set3147* by this routine, since that is the typical end-user desire;3148* use setMaximumInteger if you want to set a real value.3149* For negative numbers, use a second pattern, separated by a semicolon3150* <P>Example <code>"#,#00.0#"</code> → 1,234.563151* <P>This means a minimum of 2 integer digits, 1 fraction digit, and3152* a maximum of 2 fraction digits.3153* <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in3154* parentheses.3155* <p>In negative patterns, the minimum and maximum counts are ignored;3156* these are presumed to be set in the positive pattern.3157*3158* @param pattern a new pattern3159* @exception NullPointerException if <code>pattern</code> is null3160* @exception IllegalArgumentException if the given pattern is invalid.3161*/3162public void applyLocalizedPattern(String pattern) {3163applyPattern(pattern, true);3164}31653166/**3167* Does the real work of applying a pattern.3168*/3169private void applyPattern(String pattern, boolean localized) {3170char zeroDigit = PATTERN_ZERO_DIGIT;3171char groupingSeparator = PATTERN_GROUPING_SEPARATOR;3172char decimalSeparator = PATTERN_DECIMAL_SEPARATOR;3173char percent = PATTERN_PERCENT;3174char perMill = PATTERN_PER_MILLE;3175char digit = PATTERN_DIGIT;3176char separator = PATTERN_SEPARATOR;3177String exponent = PATTERN_EXPONENT;3178char minus = PATTERN_MINUS;3179if (localized) {3180zeroDigit = symbols.getZeroDigit();3181groupingSeparator = symbols.getGroupingSeparator();3182decimalSeparator = symbols.getDecimalSeparator();3183percent = symbols.getPercent();3184perMill = symbols.getPerMill();3185digit = symbols.getDigit();3186separator = symbols.getPatternSeparator();3187exponent = symbols.getExponentSeparator();3188minus = symbols.getMinusSign();3189}3190boolean gotNegative = false;3191decimalSeparatorAlwaysShown = false;3192isCurrencyFormat = false;3193useExponentialNotation = false;31943195// Two variables are used to record the subrange of the pattern3196// occupied by phase 1. This is used during the processing of the3197// second pattern (the one representing negative numbers) to ensure3198// that no deviation exists in phase 1 between the two patterns.3199int phaseOneStart = 0;3200int phaseOneLength = 0;32013202int start = 0;3203for (int j = 1; j >= 0 && start < pattern.length(); --j) {3204boolean inQuote = false;3205StringBuffer prefix = new StringBuffer();3206StringBuffer suffix = new StringBuffer();3207int decimalPos = -1;3208int multiplier = 1;3209int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0;3210byte groupingCount = -1;32113212// The phase ranges from 0 to 2. Phase 0 is the prefix. Phase 1 is3213// the section of the pattern with digits, decimal separator,3214// grouping characters. Phase 2 is the suffix. In phases 0 and 2,3215// percent, per mille, and currency symbols are recognized and3216// translated. The separation of the characters into phases is3217// strictly enforced; if phase 1 characters are to appear in the3218// suffix, for example, they must be quoted.3219int phase = 0;32203221// The affix is either the prefix or the suffix.3222StringBuffer affix = prefix;32233224for (int pos = start; pos < pattern.length(); ++pos) {3225char ch = pattern.charAt(pos);3226switch (phase) {3227case 0:3228case 2:3229// Process the prefix / suffix characters3230if (inQuote) {3231// A quote within quotes indicates either the closing3232// quote or two quotes, which is a quote literal. That3233// is, we have the second quote in 'do' or 'don''t'.3234if (ch == QUOTE) {3235if ((pos+1) < pattern.length() &&3236pattern.charAt(pos+1) == QUOTE) {3237++pos;3238affix.append("''"); // 'don''t'3239} else {3240inQuote = false; // 'do'3241}3242continue;3243}3244} else {3245// Process unquoted characters seen in prefix or suffix3246// phase.3247if (ch == digit ||3248ch == zeroDigit ||3249ch == groupingSeparator ||3250ch == decimalSeparator) {3251phase = 1;3252if (j == 1) {3253phaseOneStart = pos;3254}3255--pos; // Reprocess this character3256continue;3257} else if (ch == CURRENCY_SIGN) {3258// Use lookahead to determine if the currency sign3259// is doubled or not.3260boolean doubled = (pos + 1) < pattern.length() &&3261pattern.charAt(pos + 1) == CURRENCY_SIGN;3262if (doubled) { // Skip over the doubled character3263++pos;3264}3265isCurrencyFormat = true;3266affix.append(doubled ? "'\u00A4\u00A4" : "'\u00A4");3267continue;3268} else if (ch == QUOTE) {3269// A quote outside quotes indicates either the3270// opening quote or two quotes, which is a quote3271// literal. That is, we have the first quote in 'do'3272// or o''clock.3273if (ch == QUOTE) {3274if ((pos+1) < pattern.length() &&3275pattern.charAt(pos+1) == QUOTE) {3276++pos;3277affix.append("''"); // o''clock3278} else {3279inQuote = true; // 'do'3280}3281continue;3282}3283} else if (ch == separator) {3284// Don't allow separators before we see digit3285// characters of phase 1, and don't allow separators3286// in the second pattern (j == 0).3287if (phase == 0 || j == 0) {3288throw new IllegalArgumentException("Unquoted special character '" +3289ch + "' in pattern \"" + pattern + '"');3290}3291start = pos + 1;3292pos = pattern.length();3293continue;3294}32953296// Next handle characters which are appended directly.3297else if (ch == percent) {3298if (multiplier != 1) {3299throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +3300pattern + '"');3301}3302multiplier = 100;3303affix.append("'%");3304continue;3305} else if (ch == perMill) {3306if (multiplier != 1) {3307throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +3308pattern + '"');3309}3310multiplier = 1000;3311affix.append("'\u2030");3312continue;3313} else if (ch == minus) {3314affix.append("'-");3315continue;3316}3317}3318// Note that if we are within quotes, or if this is an3319// unquoted, non-special character, then we usually fall3320// through to here.3321affix.append(ch);3322break;33233324case 1:3325// Phase one must be identical in the two sub-patterns. We3326// enforce this by doing a direct comparison. While3327// processing the first sub-pattern, we just record its3328// length. While processing the second, we compare3329// characters.3330if (j == 1) {3331++phaseOneLength;3332} else {3333if (--phaseOneLength == 0) {3334phase = 2;3335affix = suffix;3336}3337continue;3338}33393340// Process the digits, decimal, and grouping characters. We3341// record five pieces of information. We expect the digits3342// to occur in the pattern ####0000.####, and we record the3343// number of left digits, zero (central) digits, and right3344// digits. The position of the last grouping character is3345// recorded (should be somewhere within the first two blocks3346// of characters), as is the position of the decimal point,3347// if any (should be in the zero digits). If there is no3348// decimal point, then there should be no right digits.3349if (ch == digit) {3350if (zeroDigitCount > 0) {3351++digitRightCount;3352} else {3353++digitLeftCount;3354}3355if (groupingCount >= 0 && decimalPos < 0) {3356++groupingCount;3357}3358} else if (ch == zeroDigit) {3359if (digitRightCount > 0) {3360throw new IllegalArgumentException("Unexpected '0' in pattern \"" +3361pattern + '"');3362}3363++zeroDigitCount;3364if (groupingCount >= 0 && decimalPos < 0) {3365++groupingCount;3366}3367} else if (ch == groupingSeparator) {3368groupingCount = 0;3369} else if (ch == decimalSeparator) {3370if (decimalPos >= 0) {3371throw new IllegalArgumentException("Multiple decimal separators in pattern \"" +3372pattern + '"');3373}3374decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;3375} else if (pattern.regionMatches(pos, exponent, 0, exponent.length())){3376if (useExponentialNotation) {3377throw new IllegalArgumentException("Multiple exponential " +3378"symbols in pattern \"" + pattern + '"');3379}3380useExponentialNotation = true;3381minExponentDigits = 0;33823383// Use lookahead to parse out the exponential part3384// of the pattern, then jump into phase 2.3385pos = pos+exponent.length();3386while (pos < pattern.length() &&3387pattern.charAt(pos) == zeroDigit) {3388++minExponentDigits;3389++phaseOneLength;3390++pos;3391}33923393if ((digitLeftCount + zeroDigitCount) < 1 ||3394minExponentDigits < 1) {3395throw new IllegalArgumentException("Malformed exponential " +3396"pattern \"" + pattern + '"');3397}33983399// Transition to phase 23400phase = 2;3401affix = suffix;3402--pos;3403continue;3404} else {3405phase = 2;3406affix = suffix;3407--pos;3408--phaseOneLength;3409continue;3410}3411break;3412}3413}34143415// Handle patterns with no '0' pattern character. These patterns3416// are legal, but must be interpreted. "##.###" -> "#0.###".3417// ".###" -> ".0##".3418/* We allow patterns of the form "####" to produce a zeroDigitCount3419* of zero (got that?); although this seems like it might make it3420* possible for format() to produce empty strings, format() checks3421* for this condition and outputs a zero digit in this situation.3422* Having a zeroDigitCount of zero yields a minimum integer digits3423* of zero, which allows proper round-trip patterns. That is, we3424* don't want "#" to become "#0" when toPattern() is called (even3425* though that's what it really is, semantically).3426*/3427if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {3428// Handle "###.###" and "###." and ".###"3429int n = decimalPos;3430if (n == 0) { // Handle ".###"3431++n;3432}3433digitRightCount = digitLeftCount - n;3434digitLeftCount = n - 1;3435zeroDigitCount = 1;3436}34373438// Do syntax checking on the digits.3439if ((decimalPos < 0 && digitRightCount > 0) ||3440(decimalPos >= 0 && (decimalPos < digitLeftCount ||3441decimalPos > (digitLeftCount + zeroDigitCount))) ||3442groupingCount == 0 || inQuote) {3443throw new IllegalArgumentException("Malformed pattern \"" +3444pattern + '"');3445}34463447if (j == 1) {3448posPrefixPattern = prefix.toString();3449posSuffixPattern = suffix.toString();3450negPrefixPattern = posPrefixPattern; // assume these for now3451negSuffixPattern = posSuffixPattern;3452int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;3453/* The effectiveDecimalPos is the position the decimal is at or3454* would be at if there is no decimal. Note that if decimalPos<0,3455* then digitTotalCount == digitLeftCount + zeroDigitCount.3456*/3457int effectiveDecimalPos = decimalPos >= 0 ?3458decimalPos : digitTotalCount;3459setMinimumIntegerDigits(effectiveDecimalPos - digitLeftCount);3460setMaximumIntegerDigits(useExponentialNotation ?3461digitLeftCount + getMinimumIntegerDigits() :3462MAXIMUM_INTEGER_DIGITS);3463setMaximumFractionDigits(decimalPos >= 0 ?3464(digitTotalCount - decimalPos) : 0);3465setMinimumFractionDigits(decimalPos >= 0 ?3466(digitLeftCount + zeroDigitCount - decimalPos) : 0);3467setGroupingUsed(groupingCount > 0);3468this.groupingSize = (groupingCount > 0) ? groupingCount : 0;3469this.multiplier = multiplier;3470setDecimalSeparatorAlwaysShown(decimalPos == 0 ||3471decimalPos == digitTotalCount);3472} else {3473negPrefixPattern = prefix.toString();3474negSuffixPattern = suffix.toString();3475gotNegative = true;3476}3477}34783479if (pattern.length() == 0) {3480posPrefixPattern = posSuffixPattern = "";3481setMinimumIntegerDigits(0);3482setMaximumIntegerDigits(MAXIMUM_INTEGER_DIGITS);3483setMinimumFractionDigits(0);3484setMaximumFractionDigits(MAXIMUM_FRACTION_DIGITS);3485}34863487// If there was no negative pattern, or if the negative pattern is3488// identical to the positive pattern, then prepend the minus sign to3489// the positive pattern to form the negative pattern.3490if (!gotNegative ||3491(negPrefixPattern.equals(posPrefixPattern)3492&& negSuffixPattern.equals(posSuffixPattern))) {3493negSuffixPattern = posSuffixPattern;3494negPrefixPattern = "'-" + posPrefixPattern;3495}34963497expandAffixes();3498}34993500/**3501* Sets the maximum number of digits allowed in the integer portion of a3502* number.3503* For formatting numbers other than <code>BigInteger</code> and3504* <code>BigDecimal</code> objects, the lower of <code>newValue</code> and3505* 309 is used. Negative input values are replaced with 0.3506* @see NumberFormat#setMaximumIntegerDigits3507*/3508@Override3509public void setMaximumIntegerDigits(int newValue) {3510maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);3511super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?3512DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);3513if (minimumIntegerDigits > maximumIntegerDigits) {3514minimumIntegerDigits = maximumIntegerDigits;3515super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?3516DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);3517}3518fastPathCheckNeeded = true;3519}35203521/**3522* Sets the minimum number of digits allowed in the integer portion of a3523* number.3524* For formatting numbers other than <code>BigInteger</code> and3525* <code>BigDecimal</code> objects, the lower of <code>newValue</code> and3526* 309 is used. Negative input values are replaced with 0.3527* @see NumberFormat#setMinimumIntegerDigits3528*/3529@Override3530public void setMinimumIntegerDigits(int newValue) {3531minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);3532super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?3533DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);3534if (minimumIntegerDigits > maximumIntegerDigits) {3535maximumIntegerDigits = minimumIntegerDigits;3536super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?3537DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);3538}3539fastPathCheckNeeded = true;3540}35413542/**3543* Sets the maximum number of digits allowed in the fraction portion of a3544* number.3545* For formatting numbers other than <code>BigInteger</code> and3546* <code>BigDecimal</code> objects, the lower of <code>newValue</code> and3547* 340 is used. Negative input values are replaced with 0.3548* @see NumberFormat#setMaximumFractionDigits3549*/3550@Override3551public void setMaximumFractionDigits(int newValue) {3552maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);3553super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?3554DOUBLE_FRACTION_DIGITS : maximumFractionDigits);3555if (minimumFractionDigits > maximumFractionDigits) {3556minimumFractionDigits = maximumFractionDigits;3557super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?3558DOUBLE_FRACTION_DIGITS : minimumFractionDigits);3559}3560fastPathCheckNeeded = true;3561}35623563/**3564* Sets the minimum number of digits allowed in the fraction portion of a3565* number.3566* For formatting numbers other than <code>BigInteger</code> and3567* <code>BigDecimal</code> objects, the lower of <code>newValue</code> and3568* 340 is used. Negative input values are replaced with 0.3569* @see NumberFormat#setMinimumFractionDigits3570*/3571@Override3572public void setMinimumFractionDigits(int newValue) {3573minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);3574super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?3575DOUBLE_FRACTION_DIGITS : minimumFractionDigits);3576if (minimumFractionDigits > maximumFractionDigits) {3577maximumFractionDigits = minimumFractionDigits;3578super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?3579DOUBLE_FRACTION_DIGITS : maximumFractionDigits);3580}3581fastPathCheckNeeded = true;3582}35833584/**3585* Gets the maximum number of digits allowed in the integer portion of a3586* number.3587* For formatting numbers other than <code>BigInteger</code> and3588* <code>BigDecimal</code> objects, the lower of the return value and3589* 309 is used.3590* @see #setMaximumIntegerDigits3591*/3592@Override3593public int getMaximumIntegerDigits() {3594return maximumIntegerDigits;3595}35963597/**3598* Gets the minimum number of digits allowed in the integer portion of a3599* number.3600* For formatting numbers other than <code>BigInteger</code> and3601* <code>BigDecimal</code> objects, the lower of the return value and3602* 309 is used.3603* @see #setMinimumIntegerDigits3604*/3605@Override3606public int getMinimumIntegerDigits() {3607return minimumIntegerDigits;3608}36093610/**3611* Gets the maximum number of digits allowed in the fraction portion of a3612* number.3613* For formatting numbers other than <code>BigInteger</code> and3614* <code>BigDecimal</code> objects, the lower of the return value and3615* 340 is used.3616* @see #setMaximumFractionDigits3617*/3618@Override3619public int getMaximumFractionDigits() {3620return maximumFractionDigits;3621}36223623/**3624* Gets the minimum number of digits allowed in the fraction portion of a3625* number.3626* For formatting numbers other than <code>BigInteger</code> and3627* <code>BigDecimal</code> objects, the lower of the return value and3628* 340 is used.3629* @see #setMinimumFractionDigits3630*/3631@Override3632public int getMinimumFractionDigits() {3633return minimumFractionDigits;3634}36353636/**3637* Gets the currency used by this decimal format when formatting3638* currency values.3639* The currency is obtained by calling3640* {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency}3641* on this number format's symbols.3642*3643* @return the currency used by this decimal format, or <code>null</code>3644* @since 1.43645*/3646@Override3647public Currency getCurrency() {3648return symbols.getCurrency();3649}36503651/**3652* Sets the currency used by this number format when formatting3653* currency values. This does not update the minimum or maximum3654* number of fraction digits used by the number format.3655* The currency is set by calling3656* {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency}3657* on this number format's symbols.3658*3659* @param currency the new currency to be used by this decimal format3660* @exception NullPointerException if <code>currency</code> is null3661* @since 1.43662*/3663@Override3664public void setCurrency(Currency currency) {3665if (currency != symbols.getCurrency()) {3666symbols.setCurrency(currency);3667if (isCurrencyFormat) {3668expandAffixes();3669}3670}3671fastPathCheckNeeded = true;3672}36733674/**3675* Gets the {@link java.math.RoundingMode} used in this DecimalFormat.3676*3677* @return The <code>RoundingMode</code> used for this DecimalFormat.3678* @see #setRoundingMode(RoundingMode)3679* @since 1.63680*/3681@Override3682public RoundingMode getRoundingMode() {3683return roundingMode;3684}36853686/**3687* Sets the {@link java.math.RoundingMode} used in this DecimalFormat.3688*3689* @param roundingMode The <code>RoundingMode</code> to be used3690* @see #getRoundingMode()3691* @exception NullPointerException if <code>roundingMode</code> is null.3692* @since 1.63693*/3694@Override3695public void setRoundingMode(RoundingMode roundingMode) {3696if (roundingMode == null) {3697throw new NullPointerException();3698}36993700this.roundingMode = roundingMode;3701digitList.setRoundingMode(roundingMode);3702fastPathCheckNeeded = true;3703}37043705/**3706* Reads the default serializable fields from the stream and performs3707* validations and adjustments for older serialized versions. The3708* validations and adjustments are:3709* <ol>3710* <li>3711* Verify that the superclass's digit count fields correctly reflect3712* the limits imposed on formatting numbers other than3713* <code>BigInteger</code> and <code>BigDecimal</code> objects. These3714* limits are stored in the superclass for serialization compatibility3715* with older versions, while the limits for <code>BigInteger</code> and3716* <code>BigDecimal</code> objects are kept in this class.3717* If, in the superclass, the minimum or maximum integer digit count is3718* larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or3719* maximum fraction digit count is larger than3720* <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid3721* and this method throws an <code>InvalidObjectException</code>.3722* <li>3723* If <code>serialVersionOnStream</code> is less than 4, initialize3724* <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN3725* RoundingMode.HALF_EVEN}. This field is new with version 4.3726* <li>3727* If <code>serialVersionOnStream</code> is less than 3, then call3728* the setters for the minimum and maximum integer and fraction digits with3729* the values of the corresponding superclass getters to initialize the3730* fields in this class. The fields in this class are new with version 3.3731* <li>3732* If <code>serialVersionOnStream</code> is less than 1, indicating that3733* the stream was written by JDK 1.1, initialize3734* <code>useExponentialNotation</code>3735* to false, since it was not present in JDK 1.1.3736* <li>3737* Set <code>serialVersionOnStream</code> to the maximum allowed value so3738* that default serialization will work properly if this object is streamed3739* out again.3740* </ol>3741*3742* <p>Stream versions older than 2 will not have the affix pattern variables3743* <code>posPrefixPattern</code> etc. As a result, they will be initialized3744* to <code>null</code>, which means the affix strings will be taken as3745* literal values. This is exactly what we want, since that corresponds to3746* the pre-version-2 behavior.3747*/3748private void readObject(ObjectInputStream stream)3749throws IOException, ClassNotFoundException3750{3751stream.defaultReadObject();3752digitList = new DigitList();37533754// We force complete fast-path reinitialization when the instance is3755// deserialized. See clone() comment on fastPathCheckNeeded.3756fastPathCheckNeeded = true;3757isFastPath = false;3758fastPathData = null;37593760if (serialVersionOnStream < 4) {3761setRoundingMode(RoundingMode.HALF_EVEN);3762} else {3763setRoundingMode(getRoundingMode());3764}37653766// We only need to check the maximum counts because NumberFormat3767// .readObject has already ensured that the maximum is greater than the3768// minimum count.3769if (super.getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS ||3770super.getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {3771throw new InvalidObjectException("Digit count out of range");3772}3773if (serialVersionOnStream < 3) {3774setMaximumIntegerDigits(super.getMaximumIntegerDigits());3775setMinimumIntegerDigits(super.getMinimumIntegerDigits());3776setMaximumFractionDigits(super.getMaximumFractionDigits());3777setMinimumFractionDigits(super.getMinimumFractionDigits());3778}3779if (serialVersionOnStream < 1) {3780// Didn't have exponential fields3781useExponentialNotation = false;3782}3783serialVersionOnStream = currentSerialVersion;3784}37853786//----------------------------------------------------------------------3787// INSTANCE VARIABLES3788//----------------------------------------------------------------------37893790private transient DigitList digitList = new DigitList();37913792/**3793* The symbol used as a prefix when formatting positive numbers, e.g. "+".3794*3795* @serial3796* @see #getPositivePrefix3797*/3798private String positivePrefix = "";37993800/**3801* The symbol used as a suffix when formatting positive numbers.3802* This is often an empty string.3803*3804* @serial3805* @see #getPositiveSuffix3806*/3807private String positiveSuffix = "";38083809/**3810* The symbol used as a prefix when formatting negative numbers, e.g. "-".3811*3812* @serial3813* @see #getNegativePrefix3814*/3815private String negativePrefix = "-";38163817/**3818* The symbol used as a suffix when formatting negative numbers.3819* This is often an empty string.3820*3821* @serial3822* @see #getNegativeSuffix3823*/3824private String negativeSuffix = "";38253826/**3827* The prefix pattern for non-negative numbers. This variable corresponds3828* to <code>positivePrefix</code>.3829*3830* <p>This pattern is expanded by the method <code>expandAffix()</code> to3831* <code>positivePrefix</code> to update the latter to reflect changes in3832* <code>symbols</code>. If this variable is <code>null</code> then3833* <code>positivePrefix</code> is taken as a literal value that does not3834* change when <code>symbols</code> changes. This variable is always3835* <code>null</code> for <code>DecimalFormat</code> objects older than3836* stream version 2 restored from stream.3837*3838* @serial3839* @since 1.33840*/3841private String posPrefixPattern;38423843/**3844* The suffix pattern for non-negative numbers. This variable corresponds3845* to <code>positiveSuffix</code>. This variable is analogous to3846* <code>posPrefixPattern</code>; see that variable for further3847* documentation.3848*3849* @serial3850* @since 1.33851*/3852private String posSuffixPattern;38533854/**3855* The prefix pattern for negative numbers. This variable corresponds3856* to <code>negativePrefix</code>. This variable is analogous to3857* <code>posPrefixPattern</code>; see that variable for further3858* documentation.3859*3860* @serial3861* @since 1.33862*/3863private String negPrefixPattern;38643865/**3866* The suffix pattern for negative numbers. This variable corresponds3867* to <code>negativeSuffix</code>. This variable is analogous to3868* <code>posPrefixPattern</code>; see that variable for further3869* documentation.3870*3871* @serial3872* @since 1.33873*/3874private String negSuffixPattern;38753876/**3877* The multiplier for use in percent, per mille, etc.3878*3879* @serial3880* @see #getMultiplier3881*/3882private int multiplier = 1;38833884/**3885* The number of digits between grouping separators in the integer3886* portion of a number. Must be greater than 0 if3887* <code>NumberFormat.groupingUsed</code> is true.3888*3889* @serial3890* @see #getGroupingSize3891* @see java.text.NumberFormat#isGroupingUsed3892*/3893private byte groupingSize = 3; // invariant, > 0 if useThousands38943895/**3896* If true, forces the decimal separator to always appear in a formatted3897* number, even if the fractional part of the number is zero.3898*3899* @serial3900* @see #isDecimalSeparatorAlwaysShown3901*/3902private boolean decimalSeparatorAlwaysShown = false;39033904/**3905* If true, parse returns BigDecimal wherever possible.3906*3907* @serial3908* @see #isParseBigDecimal3909* @since 1.53910*/3911private boolean parseBigDecimal = false;391239133914/**3915* True if this object represents a currency format. This determines3916* whether the monetary decimal separator is used instead of the normal one.3917*/3918private transient boolean isCurrencyFormat = false;39193920/**3921* The <code>DecimalFormatSymbols</code> object used by this format.3922* It contains the symbols used to format numbers, e.g. the grouping separator,3923* decimal separator, and so on.3924*3925* @serial3926* @see #setDecimalFormatSymbols3927* @see java.text.DecimalFormatSymbols3928*/3929private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols();39303931/**3932* True to force the use of exponential (i.e. scientific) notation when formatting3933* numbers.3934*3935* @serial3936* @since 1.23937*/3938private boolean useExponentialNotation; // Newly persistent in the Java 2 platform v.1.239393940/**3941* FieldPositions describing the positive prefix String. This is3942* lazily created. Use <code>getPositivePrefixFieldPositions</code>3943* when needed.3944*/3945private transient FieldPosition[] positivePrefixFieldPositions;39463947/**3948* FieldPositions describing the positive suffix String. This is3949* lazily created. Use <code>getPositiveSuffixFieldPositions</code>3950* when needed.3951*/3952private transient FieldPosition[] positiveSuffixFieldPositions;39533954/**3955* FieldPositions describing the negative prefix String. This is3956* lazily created. Use <code>getNegativePrefixFieldPositions</code>3957* when needed.3958*/3959private transient FieldPosition[] negativePrefixFieldPositions;39603961/**3962* FieldPositions describing the negative suffix String. This is3963* lazily created. Use <code>getNegativeSuffixFieldPositions</code>3964* when needed.3965*/3966private transient FieldPosition[] negativeSuffixFieldPositions;39673968/**3969* The minimum number of digits used to display the exponent when a number is3970* formatted in exponential notation. This field is ignored if3971* <code>useExponentialNotation</code> is not true.3972*3973* @serial3974* @since 1.23975*/3976private byte minExponentDigits; // Newly persistent in the Java 2 platform v.1.239773978/**3979* The maximum number of digits allowed in the integer portion of a3980* <code>BigInteger</code> or <code>BigDecimal</code> number.3981* <code>maximumIntegerDigits</code> must be greater than or equal to3982* <code>minimumIntegerDigits</code>.3983*3984* @serial3985* @see #getMaximumIntegerDigits3986* @since 1.53987*/3988private int maximumIntegerDigits = super.getMaximumIntegerDigits();39893990/**3991* The minimum number of digits allowed in the integer portion of a3992* <code>BigInteger</code> or <code>BigDecimal</code> number.3993* <code>minimumIntegerDigits</code> must be less than or equal to3994* <code>maximumIntegerDigits</code>.3995*3996* @serial3997* @see #getMinimumIntegerDigits3998* @since 1.53999*/4000private int minimumIntegerDigits = super.getMinimumIntegerDigits();40014002/**4003* The maximum number of digits allowed in the fractional portion of a4004* <code>BigInteger</code> or <code>BigDecimal</code> number.4005* <code>maximumFractionDigits</code> must be greater than or equal to4006* <code>minimumFractionDigits</code>.4007*4008* @serial4009* @see #getMaximumFractionDigits4010* @since 1.54011*/4012private int maximumFractionDigits = super.getMaximumFractionDigits();40134014/**4015* The minimum number of digits allowed in the fractional portion of a4016* <code>BigInteger</code> or <code>BigDecimal</code> number.4017* <code>minimumFractionDigits</code> must be less than or equal to4018* <code>maximumFractionDigits</code>.4019*4020* @serial4021* @see #getMinimumFractionDigits4022* @since 1.54023*/4024private int minimumFractionDigits = super.getMinimumFractionDigits();40254026/**4027* The {@link java.math.RoundingMode} used in this DecimalFormat.4028*4029* @serial4030* @since 1.64031*/4032private RoundingMode roundingMode = RoundingMode.HALF_EVEN;40334034// ------ DecimalFormat fields for fast-path for double algorithm ------40354036/**4037* Helper inner utility class for storing the data used in the fast-path4038* algorithm. Almost all fields related to fast-path are encapsulated in4039* this class.4040*4041* Any {@code DecimalFormat} instance has a {@code fastPathData}4042* reference field that is null unless both the properties of the instance4043* are such that the instance is in the "fast-path" state, and a format call4044* has been done at least once while in this state.4045*4046* Almost all fields are related to the "fast-path" state only and don't4047* change until one of the instance properties is changed.4048*4049* {@code firstUsedIndex} and {@code lastFreeIndex} are the only4050* two fields that are used and modified while inside a call to4051* {@code fastDoubleFormat}.4052*4053*/4054private static class FastPathData {4055// --- Temporary fields used in fast-path, shared by several methods.40564057/** The first unused index at the end of the formatted result. */4058int lastFreeIndex;40594060/** The first used index at the beginning of the formatted result */4061int firstUsedIndex;40624063// --- State fields related to fast-path status. Changes due to a4064// property change only. Set by checkAndSetFastPathStatus() only.40654066/** Difference between locale zero and default zero representation. */4067int zeroDelta;40684069/** Locale char for grouping separator. */4070char groupingChar;40714072/** Fixed index position of last integral digit of formatted result */4073int integralLastIndex;40744075/** Fixed index position of first fractional digit of formatted result */4076int fractionalFirstIndex;40774078/** Fractional constants depending on decimal|currency state */4079double fractionalScaleFactor;4080int fractionalMaxIntBound;408140824083/** The char array buffer that will contain the formatted result */4084char[] fastPathContainer;40854086/** Suffixes recorded as char array for efficiency. */4087char[] charsPositivePrefix;4088char[] charsNegativePrefix;4089char[] charsPositiveSuffix;4090char[] charsNegativeSuffix;4091boolean positiveAffixesRequired = true;4092boolean negativeAffixesRequired = true;4093}40944095/** The format fast-path status of the instance. Logical state. */4096private transient boolean isFastPath = false;40974098/** Flag stating need of check and reinit fast-path status on next format call. */4099private transient boolean fastPathCheckNeeded = true;41004101/** DecimalFormat reference to its FastPathData */4102private transient FastPathData fastPathData;410341044105//----------------------------------------------------------------------41064107static final int currentSerialVersion = 4;41084109/**4110* The internal serial version which says which version was written.4111* Possible values are:4112* <ul>4113* <li><b>0</b> (default): versions before the Java 2 platform v1.24114* <li><b>1</b>: version for 1.2, which includes the two new fields4115* <code>useExponentialNotation</code> and4116* <code>minExponentDigits</code>.4117* <li><b>2</b>: version for 1.3 and later, which adds four new fields:4118* <code>posPrefixPattern</code>, <code>posSuffixPattern</code>,4119* <code>negPrefixPattern</code>, and <code>negSuffixPattern</code>.4120* <li><b>3</b>: version for 1.5 and later, which adds five new fields:4121* <code>maximumIntegerDigits</code>,4122* <code>minimumIntegerDigits</code>,4123* <code>maximumFractionDigits</code>,4124* <code>minimumFractionDigits</code>, and4125* <code>parseBigDecimal</code>.4126* <li><b>4</b>: version for 1.6 and later, which adds one new field:4127* <code>roundingMode</code>.4128* </ul>4129* @since 1.24130* @serial4131*/4132private int serialVersionOnStream = currentSerialVersion;41334134//----------------------------------------------------------------------4135// CONSTANTS4136//----------------------------------------------------------------------41374138// ------ Fast-Path for double Constants ------41394140/** Maximum valid integer value for applying fast-path algorithm */4141private static final double MAX_INT_AS_DOUBLE = (double) Integer.MAX_VALUE;41424143/**4144* The digit arrays used in the fast-path methods for collecting digits.4145* Using 3 constants arrays of chars ensures a very fast collection of digits4146*/4147private static class DigitArrays {4148static final char[] DigitOnes1000 = new char[1000];4149static final char[] DigitTens1000 = new char[1000];4150static final char[] DigitHundreds1000 = new char[1000];41514152// initialize on demand holder class idiom for arrays of digits4153static {4154int tenIndex = 0;4155int hundredIndex = 0;4156char digitOne = '0';4157char digitTen = '0';4158char digitHundred = '0';4159for (int i = 0; i < 1000; i++ ) {41604161DigitOnes1000[i] = digitOne;4162if (digitOne == '9')4163digitOne = '0';4164else4165digitOne++;41664167DigitTens1000[i] = digitTen;4168if (i == (tenIndex + 9)) {4169tenIndex += 10;4170if (digitTen == '9')4171digitTen = '0';4172else4173digitTen++;4174}41754176DigitHundreds1000[i] = digitHundred;4177if (i == (hundredIndex + 99)) {4178digitHundred++;4179hundredIndex += 100;4180}4181}4182}4183}4184// ------ Fast-Path for double Constants end ------41854186// Constants for characters used in programmatic (unlocalized) patterns.4187private static final char PATTERN_ZERO_DIGIT = '0';4188private static final char PATTERN_GROUPING_SEPARATOR = ',';4189private static final char PATTERN_DECIMAL_SEPARATOR = '.';4190private static final char PATTERN_PER_MILLE = '\u2030';4191private static final char PATTERN_PERCENT = '%';4192private static final char PATTERN_DIGIT = '#';4193private static final char PATTERN_SEPARATOR = ';';4194private static final String PATTERN_EXPONENT = "E";4195private static final char PATTERN_MINUS = '-';41964197/**4198* The CURRENCY_SIGN is the standard Unicode symbol for currency. It4199* is used in patterns and substituted with either the currency symbol,4200* or if it is doubled, with the international currency symbol. If the4201* CURRENCY_SIGN is seen in a pattern, then the decimal separator is4202* replaced with the monetary decimal separator.4203*4204* The CURRENCY_SIGN is not localized.4205*/4206private static final char CURRENCY_SIGN = '\u00A4';42074208private static final char QUOTE = '\'';42094210private static FieldPosition[] EmptyFieldPositionArray = new FieldPosition[0];42114212// Upper limit on integer and fraction digits for a Java double4213static final int DOUBLE_INTEGER_DIGITS = 309;4214static final int DOUBLE_FRACTION_DIGITS = 340;42154216// Upper limit on integer and fraction digits for BigDecimal and BigInteger4217static final int MAXIMUM_INTEGER_DIGITS = Integer.MAX_VALUE;4218static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE;42194220// Proclaim JDK 1.1 serial compatibility.4221static final long serialVersionUID = 864413376551465018L;4222}422342244225