1 /*
2  * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */

25
26 /*
27  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
28  * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
29  *
30  *   The original version of this source code and documentation is copyrighted
31  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
32  * materials are provided under terms of a License Agreement between Taligent
33  * and Sun. This technology is protected by multiple US and International
34  * patents. This notice and attribution to Taligent may not be removed.
35  *   Taligent is a registered trademark of Taligent, Inc.
36  *
37  */

38
39 package java.text;
40
41 import java.io.IOException;
42 import java.io.InvalidObjectException;
43 import java.io.ObjectInputStream;
44 import java.math.BigDecimal;
45 import java.math.BigInteger;
46 import java.math.RoundingMode;
47 import java.text.spi.NumberFormatProvider;
48 import java.util.ArrayList;
49 import java.util.Currency;
50 import java.util.Locale;
51 import java.util.ResourceBundle;
52 import java.util.concurrent.ConcurrentHashMap;
53 import java.util.concurrent.ConcurrentMap;
54 import java.util.concurrent.atomic.AtomicInteger;
55 import java.util.concurrent.atomic.AtomicLong;
56 import sun.util.locale.provider.LocaleProviderAdapter;
57 import sun.util.locale.provider.ResourceBundleBasedAdapter;
58
59 /**
60  * <code>DecimalFormat</code> is a concrete subclass of
61  * <code>NumberFormat</code> that formats decimal numbers. It has a variety of
62  * features designed to make it possible to parse and format numbers in any
63  * locale, including support for Western, Arabic, and Indic digits.  It also
64  * supports different kinds of numbers, including integers (123), fixed-point
65  * numbers (123.4), scientific notation (1.23E4), percentages (12%), and
66  * currency amounts ($123).  All of these can be localized.
67  *
68  * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the
69  * default locale, call one of <code>NumberFormat</code>'s factory methods, such
70  * as <code>getInstance()</code>.  In general, do not call the
71  * <code>DecimalFormat</code> constructors directly, since the
72  * <code>NumberFormat</code> factory methods may return subclasses other than
73  * <code>DecimalFormat</code>. If you need to customize the format object, do
74  * something like this:
75  *
76  * <blockquote><pre>
77  * NumberFormat f = NumberFormat.getInstance(loc);
78  * if (f instanceof DecimalFormat) {
79  *     ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
80  * }
81  * </pre></blockquote>
82  *
83  * <p>A <code>DecimalFormat</code> comprises a <em>pattern</em> and a set of
84  * <em>symbols</em>.  The pattern may be set directly using
85  * <code>applyPattern()</code>, or indirectly using the API methods.  The
86  * symbols are stored in a <code>DecimalFormatSymbols</code> object.  When using
87  * the <code>NumberFormat</code> factory methods, the pattern and symbols are
88  * read from localized <code>ResourceBundle</code>s.
89  *
90  * <h3>Patterns</h3>
91  *
92  * <code>DecimalFormat</code> patterns have the following syntax:
93  * <blockquote><pre>
94  * <i>Pattern:</i>
95  *         <i>PositivePattern</i>
96  *         <i>PositivePattern</i> ; <i>NegativePattern</i>
97  * <i>PositivePattern:</i>
98  *         <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
99  * <i>NegativePattern:</i>
100  *         <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
101  * <i>Prefix:</i>
102  *         any Unicode characters except &#92;uFFFE, &#92;uFFFF, and special characters
103  * <i>Suffix:</i>
104  *         any Unicode characters except &#92;uFFFE, &#92;uFFFF, and special characters
105  * <i>Number:</i>
106  *         <i>Integer</i> <i>Exponent<sub>opt</sub></i>
107  *         <i>Integer</i> . <i>Fraction</i> <i>Exponent<sub>opt</sub></i>
108  * <i>Integer:</i>
109  *         <i>MinimumInteger</i>
110  *         #
111  *         # <i>Integer</i>
112  *         # , <i>Integer</i>
113  * <i>MinimumInteger:</i>
114  *         0
115  *         0 <i>MinimumInteger</i>
116  *         0 , <i>MinimumInteger</i>
117  * <i>Fraction:</i>
118  *         <i>MinimumFraction<sub>opt</sub></i> <i>OptionalFraction<sub>opt</sub></i>
119  * <i>MinimumFraction:</i>
120  *         0 <i>MinimumFraction<sub>opt</sub></i>
121  * <i>OptionalFraction:</i>
122  *         # <i>OptionalFraction<sub>opt</sub></i>
123  * <i>Exponent:</i>
124  *         E <i>MinimumExponent</i>
125  * <i>MinimumExponent:</i>
126  *         0 <i>MinimumExponent<sub>opt</sub></i>
127  * </pre></blockquote>
128  *
129  * <p>A <code>DecimalFormat</code> pattern contains a positive and negative
130  * subpattern, for example, <code>"#,##0.00;(#,##0.00)"</code>.  Each
131  * subpattern has a prefix, numeric part, and suffix. The negative subpattern
132  * is optional; if absent, then the positive subpattern prefixed with the
133  * localized minus sign (<code>'-'</code> in most locales) is used as the
134  * negative subpattern. That is, <code>"0.00"</code> alone is equivalent to
135  * <code>"0.00;-0.00"</code>.  If there is an explicit negative subpattern, it
136  * serves only to specify the negative prefix and suffix; the number of digits,
137  * minimal digits, and other characteristics are all the same as the positive
138  * pattern. That means that <code>"#,##0.0#;(#)"</code> produces precisely
139  * the same behavior as <code>"#,##0.0#;(#,##0.0#)"</code>.
140  *
141  * <p>The prefixes, suffixes, and various symbols used for infinity, digits,
142  * thousands separators, decimal separators, etc. may be set to arbitrary
143  * values, and they will appear properly during formatting.  However, care must
144  * be taken that the symbols and strings do not conflict, or parsing will be
145  * unreliable.  For example, either the positive and negative prefixes or the
146  * suffixes must be distinct for <code>DecimalFormat.parse()</code> to be able
147  * to distinguish positive from negative values.  (If they are identical, then
148  * <code>DecimalFormat</code> will behave as if no negative subpattern was
149  * specified.)  Another example is that the decimal separator and thousands
150  * separator should be distinct characters, or parsing will be impossible.
151  *
152  * <p>The grouping separator is commonly used for thousands, but in some
153  * countries it separates ten-thousands. The grouping size is a constant number
154  * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for
155  * 1,0000,0000.  If you supply a pattern with multiple grouping characters, the
156  * interval between the last one and the end of the integer is the one that is
157  * used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> ==
158  * <code>"##,####,####"</code>.
159  *
160  * <h4>Special Pattern Characters</h4>
161  *
162  * <p>Many characters in a pattern are taken literally; they are matched during
163  * parsing and output unchanged during formatting.  Special characters, on the
164  * other hand, stand for other characters, strings, or classes of characters.
165  * They must be quoted, unless noted otherwise, if they are to appear in the
166  * prefix or suffix as literals.
167  *
168  * <p>The characters listed here are used in non-localized patterns.  Localized
169  * patterns use the corresponding characters taken from this formatter's
170  * <code>DecimalFormatSymbols</code> object instead, and these characters lose
171  * their special status.  Two exceptions are the currency sign and quote, which
172  * are not localized.
173  *
174  * <blockquote>
175  * <table class="striped">
176  * <caption style="display:none">Chart showing symbol, location, localized, and meaning.</caption>
177  * <thead>
178  *     <tr>
179  *          <th scope="col" style="text-align:left">Symbol
180  *          <th scope="col" style="text-align:left">Location
181  *          <th scope="col" style="text-align:left">Localized?
182  *          <th scope="col" style="text-align:left">Meaning
183  * </thead>
184  * <tbody>
185  *     <tr style="vertical-align:top">
186  *          <th scope="row"><code>0</code>
187  *          <td>Number
188  *          <td>Yes
189  *          <td>Digit
190  *     <tr style="vertical-align: top">
191  *          <th scope="row"><code>#</code>
192  *          <td>Number
193  *          <td>Yes
194  *          <td>Digit, zero shows as absent
195  *     <tr style="vertical-align:top">
196  *          <th scope="row"><code>.</code>
197  *          <td>Number
198  *          <td>Yes
199  *          <td>Decimal separator or monetary decimal separator
200  *     <tr style="vertical-align: top">
201  *          <th scope="row"><code>-</code>
202  *          <td>Number
203  *          <td>Yes
204  *          <td>Minus sign
205  *     <tr style="vertical-align:top">
206  *          <th scope="row"><code>,</code>
207  *          <td>Number
208  *          <td>Yes
209  *          <td>Grouping separator
210  *     <tr style="vertical-align: top">
211  *          <th scope="row"><code>E</code>
212  *          <td>Number
213  *          <td>Yes
214  *          <td>Separates mantissa and exponent in scientific notation.
215  *              <em>Need not be quoted in prefix or suffix.</em>
216  *     <tr style="vertical-align:top">
217  *          <th scope="row"><code>;</code>
218  *          <td>Subpattern boundary
219  *          <td>Yes
220  *          <td>Separates positive and negative subpatterns
221  *     <tr style="vertical-align: top">
222  *          <th scope="row"><code>%</code>
223  *          <td>Prefix or suffix
224  *          <td>Yes
225  *          <td>Multiply by 100 and show as percentage
226  *     <tr style="vertical-align:top">
227  *          <th scope="row"><code>&#92;u2030</code>
228  *          <td>Prefix or suffix
229  *          <td>Yes
230  *          <td>Multiply by 1000 and show as per mille value
231  *     <tr style="vertical-align: top">
232  *          <th scope="row"><code>&#164;</code> (<code>&#92;u00A4</code>)
233  *          <td>Prefix or suffix
234  *          <td>No
235  *          <td>Currency sign, replaced by currency symbol.  If
236  *              doubled, replaced by international currency symbol.
237  *              If present in a pattern, the monetary decimal separator
238  *              is used instead of the decimal separator.
239  *     <tr style="vertical-align:top">
240  *          <th scope="row"><code>'</code>
241  *          <td>Prefix or suffix
242  *          <td>No
243  *          <td>Used to quote special characters in a prefix or suffix,
244  *              for example, <code>"'#'#"</code> formats 123 to
245  *              <code>"#123"</code>.  To create a single quote
246  *              itself, use two in a row: <code>"# o''clock"</code>.
247  * </tbody>
248  * </table>
249  * </blockquote>
250  *
251  * <h4>Scientific Notation</h4>
252  *
253  * <p>Numbers in scientific notation are expressed as the product of a mantissa
254  * and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3.  The
255  * mantissa is often in the range 1.0 &le; x {@literal <} 10.0, but it need not
256  * be.
257  * <code>DecimalFormat</code> can be instructed to format and parse scientific
258  * notation <em>only via a pattern</em>; there is currently no factory method
259  * that creates a scientific notation format.  In a pattern, the exponent
260  * character immediately followed by one or more digit characters indicates
261  * scientific notation.  Example: <code>"0.###E0"</code> formats the number
262  * 1234 as <code>"1.234E3"</code>.
263  *
264  * <ul>
265  * <li>The number of digit characters after the exponent character gives the
266  * minimum exponent digit count.  There is no maximum.  Negative exponents are
267  * formatted using the localized minus sign, <em>not</em> the prefix and suffix
268  * from the pattern.  This allows patterns such as <code>"0.###E0 m/s"</code>.
269  *
270  * <li>The minimum and maximum number of integer digits are interpreted
271  * together:
272  *
273  * <ul>
274  * <li>If the maximum number of integer digits is greater than their minimum number
275  * and greater than 1, it forces the exponent to be a multiple of the maximum
276  * number of integer digits, and the minimum number of integer digits to be
277  * interpreted as 1.  The most common use of this is to generate
278  * <em>engineering notation</em>, in which the exponent is a multiple of three,
279  * e.g., <code>"##0.#####E0"</code>. Using this pattern, the number 12345
280  * formats to <code>"12.345E3"</code>, and 123456 formats to
281  * <code>"123.456E3"</code>.
282  *
283  * <li>Otherwise, the minimum number of integer digits is achieved by adjusting the
284  * exponent.  Example: 0.00123 formatted with <code>"00.###E0"</code> yields
285  * <code>"12.3E-4"</code>.
286  * </ul>
287  *
288  * <li>The number of significant digits in the mantissa is the sum of the
289  * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is
290  * unaffected by the maximum integer digits.  For example, 12345 formatted with
291  * <code>"##0.##E0"</code> is <code>"12.3E3"</code>. To show all digits, set
292  * the significant digits count to zero.  The number of significant digits
293  * does not affect parsing.
294  *
295  * <li>Exponential patterns may not contain grouping separators.
296  * </ul>
297  *
298  * <h4>Rounding</h4>
299  *
300  * <code>DecimalFormat</code> provides rounding modes defined in
301  * {@link java.math.RoundingMode} for formatting.  By default, it uses
302  * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
303  *
304  * <h4>Digits</h4>
305  *
306  * For formatting, <code>DecimalFormat</code> uses the ten consecutive
307  * characters starting with the localized zero digit defined in the
308  * <code>DecimalFormatSymbols</code> object as digits. For parsing, these
309  * digits as well as all Unicode decimal digits, as defined by
310  * {@link Character#digit Character.digit}, are recognized.
311  *
312  * <h4>Special Values</h4>
313  *
314  * <p><code>NaN</code> is formatted as a string, which typically has a single character
315  * <code>&#92;uFFFD</code>.  This string is determined by the
316  * <code>DecimalFormatSymbols</code> object.  This is the only value for which
317  * the prefixes and suffixes are not used.
318  *
319  * <p>Infinity is formatted as a string, which typically has a single character
320  * <code>&#92;u221E</code>, with the positive or negative prefixes and suffixes
321  * applied.  The infinity string is determined by the
322  * <code>DecimalFormatSymbols</code> object.
323  *
324  * <p>Negative zero (<code>"-0"</code>) parses to
325  * <ul>
326  * <li><code>BigDecimal(0)</code> if <code>isParseBigDecimal()</code> is
327  * true,
328  * <li><code>Long(0)</code> if <code>isParseBigDecimal()</code> is false
329  *     and <code>isParseIntegerOnly()</code> is true,
330  * <li><code>Double(-0.0)</code> if both <code>isParseBigDecimal()</code>
331  * and <code>isParseIntegerOnly()</code> are false.
332  * </ul>
333  *
334  * <h4><a id="synchronization">Synchronization</a></h4>
335  *
336  * <p>
337  * Decimal formats are generally not synchronized.
338  * It is recommended to create separate format instances for each thread.
339  * If multiple threads access a format concurrently, it must be synchronized
340  * externally.
341  *
342  * <h4>Example</h4>
343  *
344  * <blockquote><pre>{@code
345  * <strong>// Print out a number using the localized number, integer, currency,
346  * // and percent format for each locale</strong>
347  * Locale[] locales = NumberFormat.getAvailableLocales();
348  * double myNumber = -1234.56;
349  * NumberFormat form;
350  * for (int j = 0; j < 4; ++j) {
351  *     System.out.println("FORMAT");
352  *     for (int i = 0; i < locales.length; ++i) {
353  *         if (locales[i].getCountry().length() == 0) {
354  *            continue// Skip language-only locales
355  *         }
356  *         System.out.print(locales[i].getDisplayName());
357  *         switch (j) {
358  *         case 0:
359  *             form = NumberFormat.getInstance(locales[i]); break;
360  *         case 1:
361  *             form = NumberFormat.getIntegerInstance(locales[i]); break;
362  *         case 2:
363  *             form = NumberFormat.getCurrencyInstance(locales[i]); break;
364  *         default:
365  *             form = NumberFormat.getPercentInstance(locales[i]); break;
366  *         }
367  *         if (form instanceof DecimalFormat) {
368  *             System.out.print(": " + ((DecimalFormat) form).toPattern());
369  *         }
370  *         System.out.print(" -> " + form.format(myNumber));
371  *         try {
372  *             System.out.println(" -> " + form.parse(form.format(myNumber)));
373  *         } catch (ParseException e) {}
374  *     }
375  * }
376  * }</pre></blockquote>
377  *
378  * @see          <a href="http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a>
379  * @see          NumberFormat
380  * @see          DecimalFormatSymbols
381  * @see          ParsePosition
382  * @author       Mark Davis
383  * @author       Alan Liu
384  * @since 1.1
385  */

386 public class DecimalFormat extends NumberFormat {
387
388     /**
389      * Creates a DecimalFormat using the default pattern and symbols
390      * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
391      * This is a convenient way to obtain a
392      * DecimalFormat when internationalization is not the main concern.
393      * <p>
394      * To obtain standard formats for a given locale, use the factory methods
395      * on NumberFormat such as getNumberInstance. These factories will
396      * return the most appropriate sub-class of NumberFormat for a given
397      * locale.
398      *
399      * @see java.text.NumberFormat#getInstance
400      * @see java.text.NumberFormat#getNumberInstance
401      * @see java.text.NumberFormat#getCurrencyInstance
402      * @see java.text.NumberFormat#getPercentInstance
403      */

404     public DecimalFormat() {
405         // Get the pattern for the default locale.
406         Locale def = Locale.getDefault(Locale.Category.FORMAT);
407         LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class, def);
408         if (!(adapter instanceof ResourceBundleBasedAdapter)) {
409             adapter = LocaleProviderAdapter.getResourceBundleBased();
410         }
411         String[] all = adapter.getLocaleResources(def).getNumberPatterns();
412
413         // Always applyPattern after the symbols are set
414         this.symbols = DecimalFormatSymbols.getInstance(def);
415         applyPattern(all[0], false);
416     }
417
418
419     /**
420      * Creates a DecimalFormat using the given pattern and the symbols
421      * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
422      * This is a convenient way to obtain a
423      * DecimalFormat when internationalization is not the main concern.
424      * <p>
425      * To obtain standard formats for a given locale, use the factory methods
426      * on NumberFormat such as getNumberInstance. These factories will
427      * return the most appropriate sub-class of NumberFormat for a given
428      * locale.
429      *
430      * @param pattern a non-localized pattern string.
431      * @exception NullPointerException if <code>pattern</code> is null
432      * @exception IllegalArgumentException if the given pattern is invalid.
433      * @see java.text.NumberFormat#getInstance
434      * @see java.text.NumberFormat#getNumberInstance
435      * @see java.text.NumberFormat#getCurrencyInstance
436      * @see java.text.NumberFormat#getPercentInstance
437      */

438     public DecimalFormat(String pattern) {
439         // Always applyPattern after the symbols are set
440         this.symbols = DecimalFormatSymbols.getInstance(Locale.getDefault(Locale.Category.FORMAT));
441         applyPattern(pattern, false);
442     }
443
444
445     /**
446      * Creates a DecimalFormat using the given pattern and symbols.
447      * Use this constructor when you need to completely customize the
448      * behavior of the format.
449      * <p>
450      * To obtain standard formats for a given
451      * locale, use the factory methods on NumberFormat such as
452      * getInstance or getCurrencyInstance. If you need only minor adjustments
453      * to a standard format, you can modify the format returned by
454      * a NumberFormat factory method.
455      *
456      * @param pattern a non-localized pattern string
457      * @param symbols the set of symbols to be used
458      * @exception NullPointerException if any of the given arguments is null
459      * @exception IllegalArgumentException if the given pattern is invalid
460      * @see java.text.NumberFormat#getInstance
461      * @see java.text.NumberFormat#getNumberInstance
462      * @see java.text.NumberFormat#getCurrencyInstance
463      * @see java.text.NumberFormat#getPercentInstance
464      * @see java.text.DecimalFormatSymbols
465      */

466     public DecimalFormat (String pattern, DecimalFormatSymbols symbols) {
467         // Always applyPattern after the symbols are set
468         this.symbols = (DecimalFormatSymbols)symbols.clone();
469         applyPattern(pattern, false);
470     }
471
472
473     // Overrides
474     /**
475      * Formats a number and appends the resulting text to the given string
476      * buffer.
477      * The number can be of any subclass of {@link java.lang.Number}.
478      * <p>
479      * This implementation uses the maximum precision permitted.
480      * @param number     the number to format
481      * @param toAppendTo the <code>StringBuffer</code> to which the formatted
482      *                   text is to be appended
483      * @param pos        keeps track on the position of the field within the
484      *                   returned string. For example, for formatting a number
485      *                   {@code 1234567.89} in {@code Locale.US} locale,
486      *                   if the given {@code fieldPosition} is
487      *                   {@link NumberFormat#INTEGER_FIELD}, the begin index
488      *                   and end index of {@code fieldPosition} will be set
489      *                   to 0 and 9, respectively for the output string
490      *                   {@code 1,234,567.89}.
491      * @return           the value passed in as <code>toAppendTo</code>
492      * @exception        IllegalArgumentException if <code>number</code> is
493      *                   null or not an instance of <code>Number</code>.
494      * @exception        NullPointerException if <code>toAppendTo</code> or
495      *                   <code>pos</code> is null
496      * @exception        ArithmeticException if rounding is needed with rounding
497      *                   mode being set to RoundingMode.UNNECESSARY
498      * @see              java.text.FieldPosition
499      */

500     @Override
501     public final StringBuffer format(Object number,
502                                      StringBuffer toAppendTo,
503                                      FieldPosition pos) {
504         if (number instanceof Long || number instanceof Integer ||
505                    number instanceof Short || number instanceof Byte ||
506                    number instanceof AtomicInteger ||
507                    number instanceof AtomicLong ||
508                    (number instanceof BigInteger &&
509                     ((BigInteger)number).bitLength () < 64)) {
510             return format(((Number)number).longValue(), toAppendTo, pos);
511         } else if (number instanceof BigDecimal) {
512             return format((BigDecimal)number, toAppendTo, pos);
513         } else if (number instanceof BigInteger) {
514             return format((BigInteger)number, toAppendTo, pos);
515         } else if (number instanceof Number) {
516             return format(((Number)number).doubleValue(), toAppendTo, pos);
517         } else {
518             throw new IllegalArgumentException("Cannot format given Object as a Number");
519         }
520     }
521
522     /**
523      * Formats a double to produce a string.
524      * @param number    The double to format
525      * @param result    where the text is to be appended
526      * @param fieldPosition    keeps track on the position of the field within
527      *                         the returned string. For example, for formatting
528      *                         a number {@code 1234567.89} in {@code Locale.US}
529      *                         locale, if the given {@code fieldPosition} is
530      *                         {@link NumberFormat#INTEGER_FIELD}, the begin index
531      *                         and end index of {@code fieldPosition} will be set
532      *                         to 0 and 9, respectively for the output string
533      *                         {@code 1,234,567.89}.
534      * @exception NullPointerException if {@code result} or
535      *            {@code fieldPosition} is {@code null}
536      * @exception ArithmeticException if rounding is needed with rounding
537      *            mode being set to RoundingMode.UNNECESSARY
538      * @return The formatted number string
539      * @see java.text.FieldPosition
540      */

541     @Override
542     public StringBuffer format(double number, StringBuffer result,
543                                FieldPosition fieldPosition) {
544         // If fieldPosition is a DontCareFieldPosition instance we can
545         // try to go to fast-path code.
546         boolean tryFastPath = false;
547         if (fieldPosition == DontCareFieldPosition.INSTANCE)
548             tryFastPath = true;
549         else {
550             fieldPosition.setBeginIndex(0);
551             fieldPosition.setEndIndex(0);
552         }
553
554         if (tryFastPath) {
555             String tempResult = fastFormat(number);
556             if (tempResult != null) {
557                 result.append(tempResult);
558                 return result;
559             }
560         }
561
562         // if fast-path could not work, we fallback to standard code.
563         return format(number, result, fieldPosition.getFieldDelegate());
564     }
565
566     /**
567      * Formats a double to produce a string.
568      * @param number    The double to format
569      * @param result    where the text is to be appended
570      * @param delegate notified of locations of sub fields
571      * @exception       ArithmeticException if rounding is needed with rounding
572      *                  mode being set to RoundingMode.UNNECESSARY
573      * @return The formatted number string
574      */

575     private StringBuffer format(double number, StringBuffer result,
576                                 FieldDelegate delegate) {
577         if (Double.isNaN(number) ||
578            (Double.isInfinite(number) && multiplier == 0)) {
579             int iFieldStart = result.length();
580             result.append(symbols.getNaN());
581             delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
582                                iFieldStart, result.length(), result);
583             return result;
584         }
585
586         /* Detecting whether a double is negative is easy with the exception of
587          * the value -0.0.  This is a double which has a zero mantissa (and
588          * exponent), but a negative sign bit.  It is semantically distinct from
589          * a zero with a positive sign bit, and this distinction is important
590          * to certain kinds of computations.  However, it's a little tricky to
591          * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0).  How then, you may
592          * ask, does it behave distinctly from +0.0?  Well, 1/(-0.0) ==
593          * -Infinity.  Proper detection of -0.0 is needed to deal with the
594          * issues raised by bugs 4106658, 4106667, and 4147706.  Liu 7/6/98.
595          */

596         boolean isNegative = ((number < 0.0) || (number == 0.0 && 1/number < 0.0)) ^ (multiplier < 0);
597
598         if (multiplier != 1) {
599             number *= multiplier;
600         }
601
602         if (Double.isInfinite(number)) {
603             if (isNegative) {
604                 append(result, negativePrefix, delegate,
605                        getNegativePrefixFieldPositions(), Field.SIGN);
606             } else {
607                 append(result, positivePrefix, delegate,
608                        getPositivePrefixFieldPositions(), Field.SIGN);
609             }
610
611             int iFieldStart = result.length();
612             result.append(symbols.getInfinity());
613             delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
614                                iFieldStart, result.length(), result);
615
616             if (isNegative) {
617                 append(result, negativeSuffix, delegate,
618                        getNegativeSuffixFieldPositions(), Field.SIGN);
619             } else {
620                 append(result, positiveSuffix, delegate,
621                        getPositiveSuffixFieldPositions(), Field.SIGN);
622             }
623
624             return result;
625         }
626
627         if (isNegative) {
628             number = -number;
629         }
630
631         // at this point we are guaranteed a nonnegative finite number.
632         assert(number >= 0 && !Double.isInfinite(number));
633
634         synchronized(digitList) {
635             int maxIntDigits = super.getMaximumIntegerDigits();
636             int minIntDigits = super.getMinimumIntegerDigits();
637             int maxFraDigits = super.getMaximumFractionDigits();
638             int minFraDigits = super.getMinimumFractionDigits();
639
640             digitList.set(isNegative, number, useExponentialNotation ?
641                           maxIntDigits + maxFraDigits : maxFraDigits,
642                           !useExponentialNotation);
643             return subformat(result, delegate, isNegative, false,
644                        maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
645         }
646     }
647
648     /**
649      * Format a long to produce a string.
650      * @param number    The long to format
651      * @param result    where the text is to be appended
652      * @param fieldPosition    keeps track on the position of the field within
653      *                         the returned string. For example, for formatting
654      *                         a number {@code 123456789} in {@code Locale.US}
655      *                         locale, if the given {@code fieldPosition} is
656      *                         {@link NumberFormat#INTEGER_FIELD}, the begin index
657      *                         and end index of {@code fieldPosition} will be set
658      *                         to 0 and 11, respectively for the output string
659      *                         {@code 123,456,789}.
660      * @exception       NullPointerException if {@code result} or
661      *                  {@code fieldPosition} is {@code null}
662      * @exception       ArithmeticException if rounding is needed with rounding
663      *                  mode being set to RoundingMode.UNNECESSARY
664      * @return The formatted number string
665      * @see java.text.FieldPosition
666      */

667     @Override
668     public StringBuffer format(long number, StringBuffer result,
669                                FieldPosition fieldPosition) {
670         fieldPosition.setBeginIndex(0);
671         fieldPosition.setEndIndex(0);
672
673         return format(number, result, fieldPosition.getFieldDelegate());
674     }
675
676     /**
677      * Format a long to produce a string.
678      * @param number    The long to format
679      * @param result    where the text is to be appended
680      * @param delegate notified of locations of sub fields
681      * @return The formatted number string
682      * @exception        ArithmeticException if rounding is needed with rounding
683      *                   mode being set to RoundingMode.UNNECESSARY
684      * @see java.text.FieldPosition
685      */

686     private StringBuffer format(long number, StringBuffer result,
687                                FieldDelegate delegate) {
688         boolean isNegative = (number < 0);
689         if (isNegative) {
690             number = -number;
691         }
692
693         // In general, long values always represent real finite numbers, so
694         // we don't have to check for +/- Infinity or NaN.  However, there
695         // is one case we have to be careful of:  The multiplier can push
696         // a number near MIN_VALUE or MAX_VALUE outside the legal range.  We
697         // check for this before multiplying, and if it happens we use
698         // BigInteger instead.
699         boolean useBigInteger = false;
700         if (number < 0) { // This can only happen if number == Long.MIN_VALUE.
701             if (multiplier != 0) {
702                 useBigInteger = true;
703             }
704         } else if (multiplier != 1 && multiplier != 0) {
705             long cutoff = Long.MAX_VALUE / multiplier;
706             if (cutoff < 0) {
707                 cutoff = -cutoff;
708             }
709             useBigInteger = (number > cutoff);
710         }
711
712         if (useBigInteger) {
713             if (isNegative) {
714                 number = -number;
715             }
716             BigInteger bigIntegerValue = BigInteger.valueOf(number);
717             return format(bigIntegerValue, result, delegate, true);
718         }
719
720         number *= multiplier;
721         if (number == 0) {
722             isNegative = false;
723         } else {
724             if (multiplier < 0) {
725                 number = -number;
726                 isNegative = !isNegative;
727             }
728         }
729
730         synchronized(digitList) {
731             int maxIntDigits = super.getMaximumIntegerDigits();
732             int minIntDigits = super.getMinimumIntegerDigits();
733             int maxFraDigits = super.getMaximumFractionDigits();
734             int minFraDigits = super.getMinimumFractionDigits();
735
736             digitList.set(isNegative, number,
737                      useExponentialNotation ? maxIntDigits + maxFraDigits : 0);
738
739             return subformat(result, delegate, isNegative, true,
740                        maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
741         }
742     }
743
744     /**
745      * Formats a BigDecimal to produce a string.
746      * @param number    The BigDecimal to format
747      * @param result    where the text is to be appended
748      * @param fieldPosition    keeps track on the position of the field within
749      *                         the returned string. For example, for formatting
750      *                         a number {@code 1234567.89} in {@code Locale.US}
751      *                         locale, if the given {@code fieldPosition} is
752      *                         {@link NumberFormat#INTEGER_FIELD}, the begin index
753      *                         and end index of {@code fieldPosition} will be set
754      *                         to 0 and 9, respectively for the output string
755      *                         {@code 1,234,567.89}.
756      * @return The formatted number string
757      * @exception        ArithmeticException if rounding is needed with rounding
758      *                   mode being set to RoundingMode.UNNECESSARY
759      * @see java.text.FieldPosition
760      */

761     private StringBuffer format(BigDecimal number, StringBuffer result,
762                                 FieldPosition fieldPosition) {
763         fieldPosition.setBeginIndex(0);
764         fieldPosition.setEndIndex(0);
765         return format(number, result, fieldPosition.getFieldDelegate());
766     }
767
768     /**
769      * Formats a BigDecimal to produce a string.
770      * @param number    The BigDecimal to format
771      * @param result    where the text is to be appended
772      * @param delegate notified of locations of sub fields
773      * @exception        ArithmeticException if rounding is needed with rounding
774      *                   mode being set to RoundingMode.UNNECESSARY
775      * @return The formatted number string
776      */

777     private StringBuffer format(BigDecimal number, StringBuffer result,
778                                 FieldDelegate delegate) {
779         if (multiplier != 1) {
780             number = number.multiply(getBigDecimalMultiplier());
781         }
782         boolean isNegative = number.signum() == -1;
783         if (isNegative) {
784             number = number.negate();
785         }
786
787         synchronized(digitList) {
788             int maxIntDigits = getMaximumIntegerDigits();
789             int minIntDigits = getMinimumIntegerDigits();
790             int maxFraDigits = getMaximumFractionDigits();
791             int minFraDigits = getMinimumFractionDigits();
792             int maximumDigits = maxIntDigits + maxFraDigits;
793
794             digitList.set(isNegative, number, useExponentialNotation ?
795                 ((maximumDigits < 0) ? Integer.MAX_VALUE : maximumDigits) :
796                 maxFraDigits, !useExponentialNotation);
797
798             return subformat(result, delegate, isNegative, false,
799                 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
800         }
801     }
802
803     /**
804      * Format a BigInteger to produce a string.
805      * @param number    The BigInteger to format
806      * @param result    where the text is to be appended
807      * @param fieldPosition    keeps track on the position of the field within
808      *                         the returned string. For example, for formatting
809      *                         a number {@code 123456789} in {@code Locale.US}
810      *                         locale, if the given {@code fieldPosition} is
811      *                         {@link NumberFormat#INTEGER_FIELD}, the begin index
812      *                         and end index of {@code fieldPosition} will be set
813      *                         to 0 and 11, respectively for the output string
814      *                         {@code 123,456,789}.
815      * @return The formatted number string
816      * @exception        ArithmeticException if rounding is needed with rounding
817      *                   mode being set to RoundingMode.UNNECESSARY
818      * @see java.text.FieldPosition
819      */

820     private StringBuffer format(BigInteger number, StringBuffer result,
821                                FieldPosition fieldPosition) {
822         fieldPosition.setBeginIndex(0);
823         fieldPosition.setEndIndex(0);
824
825         return format(number, result, fieldPosition.getFieldDelegate(), false);
826     }
827
828     /**
829      * Format a BigInteger to produce a string.
830      * @param number    The BigInteger to format
831      * @param result    where the text is to be appended
832      * @param delegate notified of locations of sub fields
833      * @return The formatted number string
834      * @exception        ArithmeticException if rounding is needed with rounding
835      *                   mode being set to RoundingMode.UNNECESSARY
836      * @see java.text.FieldPosition
837      */

838     private StringBuffer format(BigInteger number, StringBuffer result,
839                                FieldDelegate delegate, boolean formatLong) {
840         if (multiplier != 1) {
841             number = number.multiply(getBigIntegerMultiplier());
842         }
843         boolean isNegative = number.signum() == -1;
844         if (isNegative) {
845             number = number.negate();
846         }
847
848         synchronized(digitList) {
849             int maxIntDigits, minIntDigits, maxFraDigits, minFraDigits, maximumDigits;
850             if (formatLong) {
851                 maxIntDigits = super.getMaximumIntegerDigits();
852                 minIntDigits = super.getMinimumIntegerDigits();
853                 maxFraDigits = super.getMaximumFractionDigits();
854                 minFraDigits = super.getMinimumFractionDigits();
855                 maximumDigits = maxIntDigits + maxFraDigits;
856             } else {
857                 maxIntDigits = getMaximumIntegerDigits();
858                 minIntDigits = getMinimumIntegerDigits();
859                 maxFraDigits = getMaximumFractionDigits();
860                 minFraDigits = getMinimumFractionDigits();
861                 maximumDigits = maxIntDigits + maxFraDigits;
862                 if (maximumDigits < 0) {
863                     maximumDigits = Integer.MAX_VALUE;
864                 }
865             }
866
867             digitList.set(isNegative, number,
868                           useExponentialNotation ? maximumDigits : 0);
869
870             return subformat(result, delegate, isNegative, true,
871                 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
872         }
873     }
874
875     /**
876      * Formats an Object producing an <code>AttributedCharacterIterator</code>.
877      * You can use the returned <code>AttributedCharacterIterator</code>
878      * to build the resulting String, as well as to determine information
879      * about the resulting String.
880      * <p>
881      * Each attribute key of the AttributedCharacterIterator will be of type
882      * <code>NumberFormat.Field</code>, with the attribute value being the
883      * same as the attribute key.
884      *
885      * @exception NullPointerException if obj is null.
886      * @exception IllegalArgumentException when the Format cannot format the
887      *            given object.
888      * @exception        ArithmeticException if rounding is needed with rounding
889      *                   mode being set to RoundingMode.UNNECESSARY
890      * @param obj The object to format
891      * @return AttributedCharacterIterator describing the formatted value.
892      * @since 1.4
893      */

894     @Override
895     public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
896         CharacterIteratorFieldDelegate delegate =
897                          new CharacterIteratorFieldDelegate();
898         StringBuffer sb = new StringBuffer();
899
900         if (obj instanceof Double || obj instanceof Float) {
901             format(((Number)obj).doubleValue(), sb, delegate);
902         } else if (obj instanceof Long || obj instanceof Integer ||
903                    obj instanceof Short || obj instanceof Byte ||
904                    obj instanceof AtomicInteger || obj instanceof AtomicLong) {
905             format(((Number)obj).longValue(), sb, delegate);
906         } else if (obj instanceof BigDecimal) {
907             format((BigDecimal)obj, sb, delegate);
908         } else if (obj instanceof BigInteger) {
909             format((BigInteger)obj, sb, delegate, false);
910         } else if (obj == null) {
911             throw new NullPointerException(
912                 "formatToCharacterIterator must be passed non-null object");
913         } else {
914             throw new IllegalArgumentException(
915                 "Cannot format given Object as a Number");
916         }
917         return delegate.getIterator(sb.toString());
918     }
919
920     // ==== Begin fast-path formating logic for double =========================
921
922     /* Fast-path formatting will be used for format(double ...) methods iff a
923      * number of conditions are met (see checkAndSetFastPathStatus()):
924      * - Only if instance properties meet the right predefined conditions.
925      * - The abs value of the double to format is <= Integer.MAX_VALUE.
926      *
927      * The basic approach is to split the binary to decimal conversion of a
928      * double value into two phases:
929      * * The conversion of the integer portion of the double.
930      * * The conversion of the fractional portion of the double
931      *   (limited to two or three digits).
932      *
933      * The isolation and conversion of the integer portion of the double is
934      * straightforward. The conversion of the fraction is more subtle and relies
935      * on some rounding properties of double to the decimal precisions in
936      * question.  Using the terminology of BigDecimal, this fast-path algorithm
937      * is applied when a double value has a magnitude less than Integer.MAX_VALUE
938      * and rounding is to nearest even and the destination format has two or
939      * three digits of *scale* (digits after the decimal point).
940      *
941      * Under a rounding to nearest even policy, the returned result is a digit
942      * string of a number in the (in this case decimal) destination format
943      * closest to the exact numerical value of the (in this case binary) input
944      * value.  If two destination format numbers are equally distant, the one
945      * with the last digit even is returned.  To compute such a correctly rounded
946      * value, some information about digits beyond the smallest returned digit
947      * position needs to be consulted.
948      *
949      * In general, a guard digit, a round digit, and a sticky *bit* are needed
950      * beyond the returned digit position.  If the discarded portion of the input
951      * is sufficiently large, the returned digit string is incremented.  In round
952      * to nearest even, this threshold to increment occurs near the half-way
953      * point between digits.  The sticky bit records if there are any remaining
954      * trailing digits of the exact input value in the new format; the sticky bit
955      * is consulted only in close to half-way rounding cases.
956      *
957      * Given the computation of the digit and bit values, rounding is then
958      * reduced to a table lookup problem.  For decimal, the even/odd cases look
959      * like this:
960      *
961      * Last   Round   Sticky
962      * 6      5       0      => 6   // exactly halfway, return even digit.
963      * 6      5       1      => 7   // a little bit more than halfway, round up.
964      * 7      5       0      => 8   // exactly halfway, round up to even.
965      * 7      5       1      => 8   // a little bit more than halfway, round up.
966      * With analogous entries for other even and odd last-returned digits.
967      *
968      * However, decimal negative powers of 5 smaller than 0.5 are *not* exactly
969      * representable as binary fraction.  In particular, 0.005 (the round limit
970      * for a two-digit scale) and 0.0005 (the round limit for a three-digit
971      * scale) are not representable. Therefore, for input values near these cases
972      * the sticky bit is known to be set which reduces the rounding logic to:
973      *
974      * Last   Round   Sticky
975      * 6      5       1      => 7   // a little bit more than halfway, round up.
976      * 7      5       1      => 8   // a little bit more than halfway, round up.
977      *
978      * In other words, if the round digit is 5, the sticky bit is known to be
979      * set.  If the round digit is something other than 5, the sticky bit is not
980      * relevant.  Therefore, some of the logic about whether or not to increment
981      * the destination *decimal* value can occur based on tests of *binary*
982      * computations of the binary input number.
983      */

984
985     /**
986      * Check validity of using fast-path for this instance. If fast-path is valid
987      * for this instance, sets fast-path state as true and initializes fast-path
988      * utility fields as needed.
989      *
990      * This method is supposed to be called rarely, otherwise that will break the
991      * fast-path performance. That means avoiding frequent changes of the
992      * properties of the instance, since for most properties, each time a change
993      * happens, a call to this method is needed at the next format call.
994      *
995      * FAST-PATH RULES:
996      *  Similar to the default DecimalFormat instantiation case.
997      *  More precisely:
998      *  - HALF_EVEN rounding mode,
999      *  - isGroupingUsed() is true,
1000      *  - groupingSize of 3,
1001      *  - multiplier is 1,
1002      *  - Decimal separator not mandatory,
1003      *  - No use of exponential notation,
1004      *  - minimumIntegerDigits is exactly 1 and maximumIntegerDigits at least 10
1005      *  - For number of fractional digits, the exact values found in the default case:
1006      *     Currency : min = max = 2.
1007      *     Decimal  : min = 0. max = 3.
1008      *
1009      */

1010     private boolean checkAndSetFastPathStatus() {
1011
1012         boolean fastPathWasOn = isFastPath;
1013
1014         if ((roundingMode == RoundingMode.HALF_EVEN) &&
1015             (isGroupingUsed()) &&
1016             (groupingSize == 3) &&
1017             (multiplier == 1) &&
1018             (!decimalSeparatorAlwaysShown) &&
1019             (!useExponentialNotation)) {
1020
1021             // The fast-path algorithm is semi-hardcoded against
1022             //  minimumIntegerDigits and maximumIntegerDigits.
1023             isFastPath = ((minimumIntegerDigits == 1) &&
1024                           (maximumIntegerDigits >= 10));
1025
1026             // The fast-path algorithm is hardcoded against
1027             //  minimumFractionDigits and maximumFractionDigits.
1028             if (isFastPath) {
1029                 if (isCurrencyFormat) {
1030                     if ((minimumFractionDigits != 2) ||
1031                         (maximumFractionDigits != 2))
1032                         isFastPath = false;
1033                 } else if ((minimumFractionDigits != 0) ||
1034                            (maximumFractionDigits != 3))
1035                     isFastPath = false;
1036             }
1037         } else
1038             isFastPath = false;
1039
1040         resetFastPathData(fastPathWasOn);
1041         fastPathCheckNeeded = false;
1042
1043         /*
1044          * Returns true after successfully checking the fast path condition and
1045          * setting the fast path data. The return value is used by the
1046          * fastFormat() method to decide whether to call the resetFastPathData
1047          * method to reinitialize fast path data or is it already initialized
1048          * in this method.
1049          */

1050         return true;
1051     }
1052
1053     private void resetFastPathData(boolean fastPathWasOn) {
1054         // Since some instance properties may have changed while still falling
1055         // in the fast-path case, we need to reinitialize fastPathData anyway.
1056         if (isFastPath) {
1057             // We need to instantiate fastPathData if not already done.
1058             if (fastPathData == null) {
1059                 fastPathData = new FastPathData();
1060             }
1061
1062             // Sets up the locale specific constants used when formatting.
1063             // '0' is our default representation of zero.
1064             fastPathData.zeroDelta = symbols.getZeroDigit() - '0';
1065             fastPathData.groupingChar = symbols.getGroupingSeparator();
1066
1067             // Sets up fractional constants related to currency/decimal pattern.
1068             fastPathData.fractionalMaxIntBound = (isCurrencyFormat)
1069                     ? 99 : 999;
1070             fastPathData.fractionalScaleFactor = (isCurrencyFormat)
1071                     ? 100.0d : 1000.0d;
1072
1073             // Records the need for adding prefix or suffix
1074             fastPathData.positiveAffixesRequired
1075                     = !positivePrefix.isEmpty() || !positiveSuffix.isEmpty();
1076             fastPathData.negativeAffixesRequired
1077                     = !negativePrefix.isEmpty() || !negativeSuffix.isEmpty();
1078
1079             // Creates a cached char container for result, with max possible size.
1080             int maxNbIntegralDigits = 10;
1081             int maxNbGroups = 3;
1082             int containerSize
1083                     = Math.max(positivePrefix.length(), negativePrefix.length())
1084                     + maxNbIntegralDigits + maxNbGroups + 1
1085                     + maximumFractionDigits
1086                     + Math.max(positiveSuffix.length(), negativeSuffix.length());
1087
1088             fastPathData.fastPathContainer = new char[containerSize];
1089
1090             // Sets up prefix and suffix char arrays constants.
1091             fastPathData.charsPositiveSuffix = positiveSuffix.toCharArray();
1092             fastPathData.charsNegativeSuffix = negativeSuffix.toCharArray();
1093             fastPathData.charsPositivePrefix = positivePrefix.toCharArray();
1094             fastPathData.charsNegativePrefix = negativePrefix.toCharArray();
1095
1096             // Sets up fixed index positions for integral and fractional digits.
1097             // Sets up decimal point in cached result container.
1098             int longestPrefixLength
1099                     = Math.max(positivePrefix.length(),
1100                             negativePrefix.length());
1101             int decimalPointIndex
1102                     = maxNbIntegralDigits + maxNbGroups + longestPrefixLength;
1103
1104             fastPathData.integralLastIndex = decimalPointIndex - 1;
1105             fastPathData.fractionalFirstIndex = decimalPointIndex + 1;
1106             fastPathData.fastPathContainer[decimalPointIndex]
1107                     = isCurrencyFormat
1108                             ? symbols.getMonetaryDecimalSeparator()
1109                             : symbols.getDecimalSeparator();
1110
1111         } else if (fastPathWasOn) {
1112             // Previous state was fast-path and is no more.
1113             // Resets cached array constants.
1114             fastPathData.fastPathContainer = null;
1115             fastPathData.charsPositiveSuffix = null;
1116             fastPathData.charsNegativeSuffix = null;
1117             fastPathData.charsPositivePrefix = null;
1118             fastPathData.charsNegativePrefix = null;
1119         }
1120     }
1121
1122     /**
1123      * Returns true if rounding-up must be done on {@code scaledFractionalPartAsInt},
1124      * false otherwise.
1125      *
1126      * This is a utility method that takes correct half-even rounding decision on
1127      * passed fractional value at the scaled decimal point (2 digits for currency
1128      * case and 3 for decimal case), when the approximated fractional part after
1129      * scaled decimal point is exactly 0.5d.  This is done by means of exact
1130      * calculations on the {@code fractionalPart} floating-point value.
1131      *
1132      * This method is supposed to be called by private {@code fastDoubleFormat}
1133      * method only.
1134      *
1135      * The algorithms used for the exact calculations are :
1136      *
1137      * The <b><i>FastTwoSum</i></b> algorithm, from T.J.Dekker, described in the
1138      * papers  "<i>A  Floating-Point   Technique  for  Extending  the  Available
1139      * Precision</i>"  by Dekker, and  in "<i>Adaptive  Precision Floating-Point
1140      * Arithmetic and Fast Robust Geometric Predicates</i>" from J.Shewchuk.
1141      *
1142      * A modified version of <b><i>Sum2S</i></b> cascaded summation described in
1143      * "<i>Accurate Sum and Dot Product</i>" from Takeshi Ogita and All.  As
1144      * Ogita says in this paper this is an equivalent of the Kahan-Babuska's
1145      * summation algorithm because we order the terms by magnitude before summing
1146      * them. For this reason we can use the <i>FastTwoSum</i> algorithm rather
1147      * than the more expensive Knuth's <i>TwoSum</i>.
1148      *
1149      * We do this to avoid a more expensive exact "<i>TwoProduct</i>" algorithm,
1150      * like those described in Shewchuk's paper above. See comments in the code
1151      * below.
1152      *
1153      * @param  fractionalPart The  fractional value  on which  we  take rounding
1154      * decision.
1155      * @param scaledFractionalPartAsInt The integral part of the scaled
1156      * fractional value.
1157      *
1158      * @return the decision that must be taken regarding half-even rounding.
1159      */

1160     private boolean exactRoundUp(double fractionalPart,
1161                                  int scaledFractionalPartAsInt) {
1162
1163         /* exactRoundUp() method is called by fastDoubleFormat() only.
1164          * The precondition expected to be verified by the passed parameters is :
1165          * scaledFractionalPartAsInt ==
1166          *     (int) (fractionalPart * fastPathData.fractionalScaleFactor).
1167          * This is ensured by fastDoubleFormat() code.
1168          */

1169
1170         /* We first calculate roundoff error made by fastDoubleFormat() on
1171          * the scaled fractional part. We do this with exact calculation on the
1172          * passed fractionalPart. Rounding decision will then be taken from roundoff.
1173          */

1174
1175         /* ---- TwoProduct(fractionalPart, scale factor (i.e. 1000.0d or 100.0d)).
1176          *
1177          * The below is an optimized exact "TwoProduct" calculation of passed
1178          * fractional part with scale factor, using Ogita's Sum2S cascaded
1179          * summation adapted as Kahan-Babuska equivalent by using FastTwoSum
1180          * (much faster) rather than Knuth's TwoSum.
1181          *
1182          * We can do this because we order the summation from smallest to
1183          * greatest, so that FastTwoSum can be used without any additional error.
1184          *
1185          * The "TwoProduct" exact calculation needs 17 flops. We replace this by
1186          * a cascaded summation of FastTwoSum calculations, each involving an
1187          * exact multiply by a power of 2.
1188          *
1189          * Doing so saves overall 4 multiplications and 1 addition compared to
1190          * using traditional "TwoProduct".
1191          *
1192          * The scale factor is either 100 (currency case) or 1000 (decimal case).
1193          * - when 1000, we replace it by (1024 - 16 - 8) = 1000.
1194          * - when 100,  we replace it by (128  - 32 + 4) =  100.
1195          * Every multiplication by a power of 2 (1024, 128, 32, 16, 8, 4) is exact.
1196          *
1197          */

1198         double approxMax;    // Will always be positive.
1199         double approxMedium; // Will always be negative.
1200         double approxMin;
1201
1202         double fastTwoSumApproximation = 0.0d;
1203         double fastTwoSumRoundOff = 0.0d;
1204         double bVirtual = 0.0d;
1205
1206         if (isCurrencyFormat) {
1207             // Scale is 100 = 128 - 32 + 4.
1208             // Multiply by 2**n is a shift. No roundoff. No error.
1209             approxMax    = fractionalPart * 128.00d;
1210             approxMedium = - (fractionalPart * 32.00d);
1211             approxMin    = fractionalPart * 4.00d;
1212         } else {
1213             // Scale is 1000 = 1024 - 16 - 8.
1214             // Multiply by 2**n is a shift. No roundoff. No error.
1215             approxMax    = fractionalPart * 1024.00d;
1216             approxMedium = - (fractionalPart * 16.00d);
1217             approxMin    = - (fractionalPart * 8.00d);
1218         }
1219
1220         // Shewchuk/Dekker's FastTwoSum(approxMedium, approxMin).
1221         assert(-approxMedium >= Math.abs(approxMin));
1222         fastTwoSumApproximation = approxMedium + approxMin;
1223         bVirtual = fastTwoSumApproximation - approxMedium;
1224         fastTwoSumRoundOff = approxMin - bVirtual;
1225         double approxS1 = fastTwoSumApproximation;
1226         double roundoffS1 = fastTwoSumRoundOff;
1227
1228         // Shewchuk/Dekker's FastTwoSum(approxMax, approxS1);
1229         assert(approxMax >= Math.abs(approxS1));
1230         fastTwoSumApproximation = approxMax + approxS1;
1231         bVirtual = fastTwoSumApproximation - approxMax;
1232         fastTwoSumRoundOff = approxS1 - bVirtual;
1233         double roundoff1000 = fastTwoSumRoundOff;
1234         double approx1000 = fastTwoSumApproximation;
1235         double roundoffTotal = roundoffS1 + roundoff1000;
1236
1237         // Shewchuk/Dekker's FastTwoSum(approx1000, roundoffTotal);
1238         assert(approx1000 >= Math.abs(roundoffTotal));
1239         fastTwoSumApproximation = approx1000 + roundoffTotal;
1240         bVirtual = fastTwoSumApproximation - approx1000;
1241
1242         // Now we have got the roundoff for the scaled fractional
1243         double scaledFractionalRoundoff = roundoffTotal - bVirtual;
1244
1245         // ---- TwoProduct(fractionalPart, scale (i.e. 1000.0d or 100.0d)) end.
1246
1247         /* ---- Taking the rounding decision
1248          *
1249          * We take rounding decision based on roundoff and half-even rounding
1250          * rule.
1251          *
1252          * The above TwoProduct gives us the exact roundoff on the approximated
1253          * scaled fractional, and we know that this approximation is exactly
1254          * 0.5d, since that has already been tested by the caller
1255          * (fastDoubleFormat).
1256          *
1257          * Decision comes first from the sign of the calculated exact roundoff.
1258          * - Since being exact roundoff, it cannot be positive with a scaled
1259          *   fractional less than 0.5d, as well as negative with a scaled
1260          *   fractional greater than 0.5d. That leaves us with following 3 cases.
1261          * - positive, thus scaled fractional == 0.500....0fff ==> round-up.
1262          * - negative, thus scaled fractional == 0.499....9fff ==> don't round-up.
1263          * - is zero,  thus scaled fractioanl == 0.5 ==> half-even rounding applies :
1264          *    we round-up only if the integral part of the scaled fractional is odd.
1265          *
1266          */

1267         if (scaledFractionalRoundoff > 0.0) {
1268             return true;
1269         } else if (scaledFractionalRoundoff < 0.0) {
1270             return false;
1271         } else if ((scaledFractionalPartAsInt & 1) != 0) {
1272             return true;
1273         }
1274
1275         return false;
1276
1277         // ---- Taking the rounding decision end
1278     }
1279
1280     /**
1281      * Collects integral digits from passed {@code number}, while setting
1282      * grouping chars as needed. Updates {@code firstUsedIndex} accordingly.
1283      *
1284      * Loops downward starting from {@code backwardIndex} position (inclusive).
1285      *
1286      * @param number  The int value from which we collect digits.
1287      * @param digitsBuffer The char array container where digits and grouping chars
1288      *  are stored.
1289      * @param backwardIndex the position from which we start storing digits in
1290      *  digitsBuffer.
1291      *
1292      */

1293     private void collectIntegralDigits(int number,
1294                                        char[] digitsBuffer,
1295                                        int backwardIndex) {
1296         int index = backwardIndex;
1297         int q;
1298         int r;
1299         while (number > 999) {
1300             // Generates 3 digits per iteration.
1301             q = number / 1000;
1302             r = number - (q << 10) + (q << 4) + (q << 3); // -1024 +16 +8 = 1000.
1303             number = q;
1304
1305             digitsBuffer[index--] = DigitArrays.DigitOnes1000[r];
1306             digitsBuffer[index--] = DigitArrays.DigitTens1000[r];
1307             digitsBuffer[index--] = DigitArrays.DigitHundreds1000[r];
1308             digitsBuffer[index--] = fastPathData.groupingChar;
1309         }
1310
1311         // Collects last 3 or less digits.
1312         digitsBuffer[index] = DigitArrays.DigitOnes1000[number];
1313         if (number > 9) {
1314             digitsBuffer[--index]  = DigitArrays.DigitTens1000[number];
1315             if (number > 99)
1316                 digitsBuffer[--index]   = DigitArrays.DigitHundreds1000[number];
1317         }
1318
1319         fastPathData.firstUsedIndex = index;
1320     }
1321
1322     /**
1323      * Collects the 2 (currency) or 3 (decimal) fractional digits from passed
1324      * {@code number}, starting at {@code startIndex} position
1325      * inclusive.  There is no punctuation to set here (no grouping chars).
1326      * Updates {@code fastPathData.lastFreeIndex} accordingly.
1327      *
1328      *
1329      * @param number  The int value from which we collect digits.
1330      * @param digitsBuffer The char array container where digits are stored.
1331      * @param startIndex the position from which we start storing digits in
1332      *  digitsBuffer.
1333      *
1334      */

1335     private void collectFractionalDigits(int number,
1336                                          char[] digitsBuffer,
1337                                          int startIndex) {
1338         int index = startIndex;
1339
1340         char digitOnes = DigitArrays.DigitOnes1000[number];
1341         char digitTens = DigitArrays.DigitTens1000[number];
1342
1343         if (isCurrencyFormat) {
1344             // Currency case. Always collects fractional digits.
1345             digitsBuffer[index++] = digitTens;
1346             digitsBuffer[index++] = digitOnes;
1347         } else if (number != 0) {
1348             // Decimal case. Hundreds will always be collected
1349             digitsBuffer[index++] = DigitArrays.DigitHundreds1000[number];
1350
1351             // Ending zeros won't be collected.
1352             if (digitOnes != '0') {
1353                 digitsBuffer[index++] = digitTens;
1354                 digitsBuffer[index++] = digitOnes;
1355             } else if (digitTens != '0')
1356                 digitsBuffer[index++] = digitTens;
1357
1358         } else
1359             // This is decimal pattern and fractional part is zero.
1360             // We must remove decimal point from result.
1361             index--;
1362
1363         fastPathData.lastFreeIndex = index;
1364     }
1365
1366     /**
1367      * Internal utility.
1368      * Adds the passed {@code prefix} and {@code suffix} to {@code container}.
1369      *
1370      * @param container  Char array container which to prepend/append the
1371      *  prefix/suffix.
1372      * @param prefix     Char sequence to prepend as a prefix.
1373      * @param suffix     Char sequence to append as a suffix.
1374      *
1375      */

1376     //    private void addAffixes(boolean isNegative, char[] container) {
1377     private void addAffixes(char[] container, char[] prefix, char[] suffix) {
1378
1379         // We add affixes only if needed (affix length > 0).
1380         int pl = prefix.length;
1381         int sl = suffix.length;
1382         if (pl != 0) prependPrefix(prefix, pl, container);
1383         if (sl != 0) appendSuffix(suffix, sl, container);
1384
1385     }
1386
1387     /**
1388      * Prepends the passed {@code prefix} chars to given result
1389      * {@code container}.  Updates {@code fastPathData.firstUsedIndex}
1390      * accordingly.
1391      *
1392      * @param prefix The prefix characters to prepend to result.
1393      * @param len The number of chars to prepend.
1394      * @param container Char array container which to prepend the prefix
1395      */

1396     private void prependPrefix(char[] prefix,
1397                                int len,
1398                                char[] container) {
1399
1400         fastPathData.firstUsedIndex -= len;
1401         int startIndex = fastPathData.firstUsedIndex;
1402
1403         // If prefix to prepend is only 1 char long, just assigns this char.
1404         // If prefix is less or equal 4, we use a dedicated algorithm that
1405         //  has shown to run faster than System.arraycopy.
1406         // If more than 4, we use System.arraycopy.
1407         if (len == 1)
1408             container[startIndex] = prefix[0];
1409         else if (len <= 4) {
1410             int dstLower = startIndex;
1411             int dstUpper = dstLower + len - 1;
1412             int srcUpper = len - 1;
1413             container[dstLower] = prefix[0];
1414             container[dstUpper] = prefix[srcUpper];
1415
1416             if (len > 2)
1417                 container[++dstLower] = prefix[1];
1418             if (len == 4)
1419                 container[--dstUpper] = prefix[2];
1420         } else
1421             System.arraycopy(prefix, 0, container, startIndex, len);
1422     }
1423
1424     /**
1425      * Appends the passed {@code suffix} chars to given result
1426      * {@code container}.  Updates {@code fastPathData.lastFreeIndex}
1427      * accordingly.
1428      *
1429      * @param suffix The suffix characters to append to result.
1430      * @param len The number of chars to append.
1431      * @param container Char array container which to append the suffix
1432      */

1433     private void appendSuffix(char[] suffix,
1434                               int len,
1435                               char[] container) {
1436
1437         int startIndex = fastPathData.lastFreeIndex;
1438
1439         // If suffix to append is only 1 char long, just assigns this char.
1440         // If suffix is less or equal 4, we use a dedicated algorithm that
1441         //  has shown to run faster than System.arraycopy.
1442         // If more than 4, we use System.arraycopy.
1443         if (len == 1)
1444             container[startIndex] = suffix[0];
1445         else if (len <= 4) {
1446             int dstLower = startIndex;
1447             int dstUpper = dstLower + len - 1;
1448             int srcUpper = len - 1;
1449             container[dstLower] = suffix[0];
1450             container[dstUpper] = suffix[srcUpper];
1451
1452             if (len > 2)
1453                 container[++dstLower] = suffix[1];
1454             if (len == 4)
1455                 container[--dstUpper] = suffix[2];
1456         } else
1457             System.arraycopy(suffix, 0, container, startIndex, len);
1458
1459         fastPathData.lastFreeIndex += len;
1460     }
1461
1462     /**
1463      * Converts digit chars from {@code digitsBuffer} to current locale.
1464      *
1465      * Must be called before adding affixes since we refer to
1466      * {@code fastPathData.firstUsedIndex} and {@code fastPathData.lastFreeIndex},
1467      * and do not support affixes (for speed reason).
1468      *
1469      * We loop backward starting from last used index in {@code fastPathData}.
1470      *
1471      * @param digitsBuffer The char array container where the digits are stored.
1472      */

1473     private void localizeDigits(char[] digitsBuffer) {
1474
1475         // We will localize only the digits, using the groupingSize,
1476         // and taking into account fractional part.
1477
1478         // First take into account fractional part.
1479         int digitsCounter =
1480             fastPathData.lastFreeIndex - fastPathData.fractionalFirstIndex;
1481
1482         // The case when there is no fractional digits.
1483         if (digitsCounter < 0)
1484             digitsCounter = groupingSize;
1485
1486         // Only the digits remains to localize.
1487         for (int cursor = fastPathData.lastFreeIndex - 1;
1488              cursor >= fastPathData.firstUsedIndex;
1489              cursor--) {
1490             if (digitsCounter != 0) {
1491                 // This is a digit char, we must localize it.
1492                 digitsBuffer[cursor] += fastPathData.zeroDelta;
1493                 digitsCounter--;
1494             } else {
1495                 // Decimal separator or grouping char. Reinit counter only.
1496                 digitsCounter = groupingSize;
1497             }
1498         }
1499     }
1500
1501     /**
1502      * This is the main entry point for the fast-path format algorithm.
1503      *
1504      * At this point we are sure to be in the expected conditions to run it.
1505      * This algorithm builds the formatted result and puts it in the dedicated
1506      * {@code fastPathData.fastPathContainer}.
1507      *
1508      * @param d the double value to be formatted.
1509      * @param negative Flag precising if {@code d} is negative.
1510      */

1511     private void fastDoubleFormat(double d,
1512                                   boolean negative) {
1513
1514         char[] container = fastPathData.fastPathContainer;
1515
1516         /*
1517          * The principle of the algorithm is to :
1518          * - Break the passed double into its integral and fractional parts
1519          *    converted into integers.
1520          * - Then decide if rounding up must be applied or not by following
1521          *    the half-even rounding rule, first using approximated scaled
1522          *    fractional part.
1523          * - For the difficult cases (approximated scaled fractional part
1524          *    being exactly 0.5d), we refine the rounding decision by calling
1525          *    exactRoundUp utility method that both calculates the exact roundoff
1526          *    on the approximation and takes correct rounding decision.
1527          * - We round-up the fractional part if needed, possibly propagating the
1528          *    rounding to integral part if we meet a "all-nine" case for the
1529          *    scaled fractional part.
1530          * - We then collect digits from the resulting integral and fractional
1531          *   parts, also setting the required grouping chars on the fly.
1532          * - Then we localize the collected digits if needed, and
1533          * - Finally prepend/append prefix/suffix if any is needed.
1534          */

1535
1536         // Exact integral part of d.
1537         int integralPartAsInt = (int) d;
1538
1539         // Exact fractional part of d (since we subtract it's integral part).
1540         double exactFractionalPart = d - (double) integralPartAsInt;
1541
1542         // Approximated scaled fractional part of d (due to multiplication).
1543         double scaledFractional =
1544             exactFractionalPart * fastPathData.fractionalScaleFactor;
1545
1546         // Exact integral part of scaled fractional above.
1547         int fractionalPartAsInt = (int) scaledFractional;
1548
1549         // Exact fractional part of scaled fractional above.
1550         scaledFractional = scaledFractional - (double) fractionalPartAsInt;
1551
1552         // Only when scaledFractional is exactly 0.5d do we have to do exact
1553         // calculations and take fine-grained rounding decision, since
1554         // approximated results above may lead to incorrect decision.
1555         // Otherwise comparing against 0.5d (strictly greater or less) is ok.
1556         boolean roundItUp = false;
1557         if (scaledFractional >= 0.5d) {
1558             if (scaledFractional == 0.5d)
1559                 // Rounding need fine-grained decision.
1560                 roundItUp = exactRoundUp(exactFractionalPart, fractionalPartAsInt);
1561             else
1562                 roundItUp = true;
1563
1564             if (roundItUp) {
1565                 // Rounds up both fractional part (and also integral if needed).
1566                 if (fractionalPartAsInt < fastPathData.fractionalMaxIntBound) {
1567                     fractionalPartAsInt++;
1568                 } else {
1569                     // Propagates rounding to integral part since "all nines" case.
1570                     fractionalPartAsInt = 0;
1571                     integralPartAsInt++;
1572                 }
1573             }
1574         }
1575
1576         // Collecting digits.
1577         collectFractionalDigits(fractionalPartAsInt, container,
1578                                 fastPathData.fractionalFirstIndex);
1579         collectIntegralDigits(integralPartAsInt, container,
1580                               fastPathData.integralLastIndex);
1581
1582         // Localizing digits.
1583         if (fastPathData.zeroDelta != 0)
1584             localizeDigits(container);
1585
1586         // Adding prefix and suffix.
1587         if (negative) {
1588             if (fastPathData.negativeAffixesRequired)
1589                 addAffixes(container,
1590                            fastPathData.charsNegativePrefix,
1591                            fastPathData.charsNegativeSuffix);
1592         } else if (fastPathData.positiveAffixesRequired)
1593             addAffixes(container,
1594                        fastPathData.charsPositivePrefix,
1595                        fastPathData.charsPositiveSuffix);
1596     }
1597
1598     /**
1599      * A fast-path shortcut of format(double) to be called by NumberFormat, or by
1600      * format(double, ...) public methods.
1601      *
1602      * If instance can be applied fast-path and passed double is not NaN or
1603      * Infinity, is in the integer range, we call {@code fastDoubleFormat}
1604      * after changing {@code d} to its positive value if necessary.
1605      *
1606      * Otherwise returns null by convention since fast-path can't be exercized.
1607      *
1608      * @param d The double value to be formatted
1609      *
1610      * @return the formatted result for {@code d} as a string.
1611      */

1612     String fastFormat(double d) {
1613         boolean isDataSet = false;
1614         // (Re-)Evaluates fast-path status if needed.
1615         if (fastPathCheckNeeded) {
1616             isDataSet = checkAndSetFastPathStatus();
1617         }
1618
1619         if (!isFastPath )
1620             // DecimalFormat instance is not in a fast-path state.
1621             return null;
1622
1623         if (!Double.isFinite(d))
1624             // Should not use fast-path for Infinity and NaN.
1625             return null;
1626
1627         // Extracts and records sign of double value, possibly changing it
1628         // to a positive one, before calling fastDoubleFormat().
1629         boolean negative = false;
1630         if (d < 0.0d) {
1631             negative = true;
1632             d = -d;
1633         } else if (d == 0.0d) {
1634             negative = (Math.copySign(1.0d, d) == -1.0d);
1635             d = +0.0d;
1636         }
1637
1638         if (d > MAX_INT_AS_DOUBLE)
1639             // Filters out values that are outside expected fast-path range
1640             return null;
1641         else {
1642             if (!isDataSet) {
1643                 /*
1644                  * If the fast path data is not set through
1645                  * checkAndSetFastPathStatus() and fulfil the
1646                  * fast path conditions then reset the data
1647                  * directly through resetFastPathData()
1648                  */

1649                 resetFastPathData(isFastPath);
1650             }
1651             fastDoubleFormat(d, negative);
1652
1653         }
1654
1655
1656         // Returns a new string from updated fastPathContainer.
1657         return new String(fastPathData.fastPathContainer,
1658                           fastPathData.firstUsedIndex,
1659                           fastPathData.lastFreeIndex - fastPathData.firstUsedIndex);
1660
1661     }
1662
1663     // ======== End fast-path formating logic for double =========================
1664
1665     /**
1666      * Complete the formatting of a finite number.  On entry, the digitList must
1667      * be filled in with the correct digits.
1668      */

1669     private StringBuffer subformat(StringBuffer result, FieldDelegate delegate,
1670                                    boolean isNegative, boolean isInteger,
1671                                    int maxIntDigits, int minIntDigits,
1672                                    int maxFraDigits, int minFraDigits) {
1673         // NOTE: This isn't required anymore because DigitList takes care of this.
1674         //
1675         //  // The negative of the exponent represents the number of leading
1676         //  // zeros between the decimal and the first non-zero digit, for
1677         //  // a value < 0.1 (e.g., for 0.00123, -fExponent == 2).  If this
1678         //  // is more than the maximum fraction digits, then we have an underflow
1679         //  // for the printed representation.  We recognize this here and set
1680         //  // the DigitList representation to zero in this situation.
1681         //
1682         //  if (-digitList.decimalAt >= getMaximumFractionDigits())
1683         //  {
1684         //      digitList.count = 0;
1685         //  }
1686
1687         char zero = symbols.getZeroDigit();
1688         int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
1689         char grouping = symbols.getGroupingSeparator();
1690         char decimal = isCurrencyFormat ?
1691             symbols.getMonetaryDecimalSeparator() :
1692             symbols.getDecimalSeparator();
1693
1694         /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
1695          * format as zero.  This allows sensible computations and preserves
1696          * relations such as signum(1/x) = signum(x), where x is +Infinity or
1697          * -Infinity.  Prior to this fix, we always formatted zero values as if
1698          * they were positive.  Liu 7/6/98.
1699          */

1700         if (digitList.isZero()) {
1701             digitList.decimalAt = 0; // Normalize
1702         }
1703
1704         if (isNegative) {
1705             append(result, negativePrefix, delegate,
1706                    getNegativePrefixFieldPositions(), Field.SIGN);
1707         } else {
1708             append(result, positivePrefix, delegate,
1709                    getPositivePrefixFieldPositions(), Field.SIGN);
1710         }
1711
1712         if (useExponentialNotation) {
1713             int iFieldStart = result.length();
1714             int iFieldEnd = -1;
1715             int fFieldStart = -1;
1716
1717             // Minimum integer digits are handled in exponential format by
1718             // adjusting the exponent.  For example, 0.01234 with 3 minimum
1719             // integer digits is "123.4E-4".
1720
1721             // Maximum integer digits are interpreted as indicating the
1722             // repeating range.  This is useful for engineering notation, in
1723             // which the exponent is restricted to a multiple of 3.  For
1724             // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
1725             // If maximum integer digits are > 1 and are larger than
1726             // minimum integer digits, then minimum integer digits are
1727             // ignored.
1728             int exponent = digitList.decimalAt;
1729             int repeat = maxIntDigits;
1730             int minimumIntegerDigits = minIntDigits;
1731             if (repeat > 1 && repeat > minIntDigits) {
1732                 // A repeating range is defined; adjust to it as follows.
1733                 // If repeat == 3, we have 6,5,4=>3; 3,2,1=>0; 0,-1,-2=>-3;
1734                 // -3,-4,-5=>-6, etc. This takes into account that the
1735                 // exponent we have here is off by one from what we expect;
1736                 // it is for the format 0.MMMMMx10^n.
1737                 if (exponent >= 1) {
1738                     exponent = ((exponent - 1) / repeat) * repeat;
1739                 } else {
1740                     // integer division rounds towards 0
1741                     exponent = ((exponent - repeat) / repeat) * repeat;
1742                 }
1743                 minimumIntegerDigits = 1;
1744             } else {
1745                 // No repeating range is defined; use minimum integer digits.
1746                 exponent -= minimumIntegerDigits;
1747             }
1748
1749             // We now output a minimum number of digits, and more if there
1750             // are more digits, up to the maximum number of digits.  We
1751             // place the decimal point after the "integer" digits, which
1752             // are the first (decimalAt - exponent) digits.
1753             int minimumDigits = minIntDigits + minFraDigits;
1754             if (minimumDigits < 0) {    // overflow?
1755                 minimumDigits = Integer.MAX_VALUE;
1756             }
1757
1758             // The number of integer digits is handled specially if the number
1759             // is zero, since then there may be no digits.
1760             int integerDigits = digitList.isZero() ? minimumIntegerDigits :
1761                     digitList.decimalAt - exponent;
1762             if (minimumDigits < integerDigits) {
1763                 minimumDigits = integerDigits;
1764             }
1765             int totalDigits = digitList.count;
1766             if (minimumDigits > totalDigits) {
1767                 totalDigits = minimumDigits;
1768             }
1769             boolean addedDecimalSeparator = false;
1770
1771             for (int i=0; i<totalDigits; ++i) {
1772                 if (i == integerDigits) {
1773                     // Record field information for caller.
1774                     iFieldEnd = result.length();
1775
1776                     result.append(decimal);
1777                     addedDecimalSeparator = true;
1778
1779                     // Record field information for caller.
1780                     fFieldStart = result.length();
1781                 }
1782                 result.append((i < digitList.count) ?
1783                               (char)(digitList.digits[i] + zeroDelta) :
1784                               zero);
1785             }
1786
1787             if (decimalSeparatorAlwaysShown && totalDigits == integerDigits) {
1788                 // Record field information for caller.
1789                 iFieldEnd = result.length();
1790
1791                 result.append(decimal);
1792                 addedDecimalSeparator = true;
1793
1794                 // Record field information for caller.
1795                 fFieldStart = result.length();
1796             }
1797
1798             // Record field information
1799             if (iFieldEnd == -1) {
1800                 iFieldEnd = result.length();
1801             }
1802             delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
1803                                iFieldStart, iFieldEnd, result);
1804             if (addedDecimalSeparator) {
1805                 delegate.formatted(Field.DECIMAL_SEPARATOR,
1806                                    Field.DECIMAL_SEPARATOR,
1807                                    iFieldEnd, fFieldStart, result);
1808             }
1809             if (fFieldStart == -1) {
1810                 fFieldStart = result.length();
1811             }
1812             delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
1813                                fFieldStart, result.length(), result);
1814
1815             // The exponent is output using the pattern-specified minimum
1816             // exponent digits.  There is no maximum limit to the exponent
1817             // digits, since truncating the exponent would result in an
1818             // unacceptable inaccuracy.
1819             int fieldStart = result.length();
1820
1821             result.append(symbols.getExponentSeparator());
1822
1823             delegate.formatted(Field.EXPONENT_SYMBOL, Field.EXPONENT_SYMBOL,
1824                                fieldStart, result.length(), result);
1825
1826             // For zero values, we force the exponent to zero.  We
1827             // must do this here, and not earlier, because the value
1828             // is used to determine integer digit count above.
1829             if (digitList.isZero()) {
1830                 exponent = 0;
1831             }
1832
1833             boolean negativeExponent = exponent < 0;
1834             if (negativeExponent) {
1835                 exponent = -exponent;
1836                 fieldStart = result.length();
1837                 result.append(symbols.getMinusSign());
1838                 delegate.formatted(Field.EXPONENT_SIGN, Field.EXPONENT_SIGN,
1839                                    fieldStart, result.length(), result);
1840             }
1841             digitList.set(negativeExponent, exponent);
1842
1843             int eFieldStart = result.length();
1844
1845             for (int i=digitList.decimalAt; i<minExponentDigits; ++i) {
1846                 result.append(zero);
1847             }
1848             for (int i=0; i<digitList.decimalAt; ++i) {
1849                 result.append((i < digitList.count) ?
1850                           (char)(digitList.digits[i] + zeroDelta) : zero);
1851             }
1852             delegate.formatted(Field.EXPONENT, Field.EXPONENT, eFieldStart,
1853                                result.length(), result);
1854         } else {
1855             int iFieldStart = result.length();
1856
1857             // Output the integer portion.  Here 'count' is the total
1858             // number of integer digits we will display, including both
1859             // leading zeros required to satisfy getMinimumIntegerDigits,
1860             // and actual digits present in the number.
1861             int count = minIntDigits;
1862             int digitIndex = 0; // Index into digitList.fDigits[]
1863             if (digitList.decimalAt > 0 && count < digitList.decimalAt) {
1864                 count = digitList.decimalAt;
1865             }
1866
1867             // Handle the case where getMaximumIntegerDigits() is smaller
1868             // than the real number of integer digits.  If this is so, we
1869             // output the least significant max integer digits.  For example,
1870             // the value 1997 printed with 2 max integer digits is just "97".
1871             if (count > maxIntDigits) {
1872                 count = maxIntDigits;
1873                 digitIndex = digitList.decimalAt - count;
1874             }
1875
1876             int sizeBeforeIntegerPart = result.length();
1877             for (int i=count-1; i>=0; --i) {
1878                 if (i < digitList.decimalAt && digitIndex < digitList.count) {
1879                     // Output a real digit
1880                     result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
1881                 } else {
1882                     // Output a leading zero
1883                     result.append(zero);
1884                 }
1885
1886                 // Output grouping separator if necessary.  Don't output a
1887                 // grouping separator if i==0 though; that's at the end of
1888                 // the integer part.
1889                 if (isGroupingUsed() && i>0 && (groupingSize != 0) &&
1890                     (i % groupingSize == 0)) {
1891                     int gStart = result.length();
1892                     result.append(grouping);
1893                     delegate.formatted(Field.GROUPING_SEPARATOR,
1894                                        Field.GROUPING_SEPARATOR, gStart,
1895                                        result.length(), result);
1896                 }
1897             }
1898
1899             // Determine whether or not there are any printable fractional
1900             // digits.  If we've used up the digits we know there aren't.
1901             boolean fractionPresent = (minFraDigits > 0) ||
1902                 (!isInteger && digitIndex < digitList.count);
1903
1904             // If there is no fraction present, and we haven't printed any
1905             // integer digits, then print a zero.  Otherwise we won't print
1906             // _any_ digits, and we won't be able to parse this string.
1907             if (!fractionPresent && result.length() == sizeBeforeIntegerPart) {
1908                 result.append(zero);
1909             }
1910
1911             delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
1912                                iFieldStart, result.length(), result);
1913
1914             // Output the decimal separator if we always do so.
1915             int sStart = result.length();
1916             if (decimalSeparatorAlwaysShown || fractionPresent) {
1917                 result.append(decimal);
1918             }
1919
1920             if (sStart != result.length()) {
1921                 delegate.formatted(Field.DECIMAL_SEPARATOR,
1922                                    Field.DECIMAL_SEPARATOR,
1923                                    sStart, result.length(), result);
1924             }
1925             int fFieldStart = result.length();
1926
1927             for (int i=0; i < maxFraDigits; ++i) {
1928                 // Here is where we escape from the loop.  We escape if we've
1929                 // output the maximum fraction digits (specified in the for
1930                 // expression above).
1931                 // We also stop when we've output the minimum digits and either:
1932                 // we have an integer, so there is no fractional stuff to
1933                 // display, or we're out of significant digits.
1934                 if (i >= minFraDigits &&
1935                     (isInteger || digitIndex >= digitList.count)) {
1936                     break;
1937                 }
1938
1939                 // Output leading fractional zeros. These are zeros that come
1940                 // after the decimal but before any significant digits. These
1941                 // are only output if abs(number being formatted) < 1.0.
1942                 if (-1-i > (digitList.decimalAt-1)) {
1943                     result.append(zero);
1944                     continue;
1945                 }
1946
1947                 // Output a digit, if we have any precision left, or a
1948                 // zero if we don't.  We don't want to output noise digits.
1949                 if (!isInteger && digitIndex < digitList.count) {
1950                     result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
1951                 } else {
1952                     result.append(zero);
1953                 }
1954             }
1955
1956             // Record field information for caller.
1957             delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
1958                                fFieldStart, result.length(), result);
1959         }
1960
1961         if (isNegative) {
1962             append(result, negativeSuffix, delegate,
1963                    getNegativeSuffixFieldPositions(), Field.SIGN);
1964         } else {
1965             append(result, positiveSuffix, delegate,
1966                    getPositiveSuffixFieldPositions(), Field.SIGN);
1967         }
1968
1969         return result;
1970     }
1971
1972     /**
1973      * Appends the String <code>string</code> to <code>result</code>.
1974      * <code>delegate</code> is notified of all  the
1975      * <code>FieldPosition</code>s in <code>positions</code>.
1976      * <p>
1977      * If one of the <code>FieldPosition</code>s in <code>positions</code>
1978      * identifies a <code>SIGN</code> attribute, it is mapped to
1979      * <code>signAttribute</code>. This is used
1980      * to map the <code>SIGN</code> attribute to the <code>EXPONENT</code>
1981      * attribute as necessary.
1982      * <p>
1983      * This is used by <code>subformat</code> to add the prefix/suffix.
1984      */

1985     private void append(StringBuffer result, String string,
1986                         FieldDelegate delegate,
1987                         FieldPosition[] positions,
1988                         Format.Field signAttribute) {
1989         int start = result.length();
1990
1991         if (!string.isEmpty()) {
1992             result.append(string);
1993             for (int counter = 0, max = positions.length; counter < max;
1994                  counter++) {
1995                 FieldPosition fp = positions[counter];
1996                 Format.Field attribute = fp.getFieldAttribute();
1997
1998                 if (attribute == Field.SIGN) {
1999                     attribute = signAttribute;
2000                 }
2001                 delegate.formatted(attribute, attribute,
2002                                    start + fp.getBeginIndex(),
2003                                    start + fp.getEndIndex(), result);
2004             }
2005         }
2006     }
2007
2008     /**
2009      * Parses text from a string to produce a <code>Number</code>.
2010      * <p>
2011      * The method attempts to parse text starting at the index given by
2012      * <code>pos</code>.
2013      * If parsing succeeds, then the index of <code>pos</code> is updated
2014      * to the index after the last character used (parsing does not necessarily
2015      * use all characters up to the end of the string), and the parsed
2016      * number is returned. The updated <code>pos</code> can be used to
2017      * indicate the starting point for the next call to this method.
2018      * If an error occurs, then the index of <code>pos</code> is not
2019      * changed, the error index of <code>pos</code> is set to the index of
2020      * the character where the error occurred, and null is returned.
2021      * <p>
2022      * The subclass returned depends on the value of {@link #isParseBigDecimal}
2023      * as well as on the string being parsed.
2024      * <ul>
2025      *   <li>If <code>isParseBigDecimal()</code> is false (the default),
2026      *       most integer values are returned as <code>Long</code>
2027      *       objects, no matter how they are written: <code>"17"</code> and
2028      *       <code>"17.000"</code> both parse to <code>Long(17)</code>.
2029      *       Values that cannot fit into a <code>Long</code> are returned as
2030      *       <code>Double</code>s. This includes values with a fractional part,
2031      *       infinite values, <code>NaN</code>, and the value -0.0.
2032      *       <code>DecimalFormat</code> does <em>not</em> decide whether to
2033      *       return a <code>Double</code> or a <code>Long</code> based on the
2034      *       presence of a decimal separator in the source string. Doing so
2035      *       would prevent integers that overflow the mantissa of a double,
2036      *       such as <code>"-9,223,372,036,854,775,808.00"</code>, from being
2037      *       parsed accurately.
2038      *       <p>
2039      *       Callers may use the <code>Number</code> methods
2040      *       <code>doubleValue</code>, <code>longValue</code>, etc., to obtain
2041      *       the type they want.
2042      *   <li>If <code>isParseBigDecimal()</code> is true, values are returned
2043      *       as <code>BigDecimal</code> objects. The values are the ones
2044      *       constructed by {@link java.math.BigDecimal#BigDecimal(String)}
2045      *       for corresponding strings in locale-independent format. The
2046      *       special cases negative and positive infinity and NaN are returned
2047      *       as <code>Double</code> instances holding the values of the
2048      *       corresponding <code>Double</code> constants.
2049      * </ul>
2050      * <p>
2051      * <code>DecimalFormat</code> parses all Unicode characters that represent
2052      * decimal digits, as defined by <code>Character.digit()</code>. In
2053      * addition, <code>DecimalFormat</code> also recognizes as digits the ten
2054      * consecutive characters starting with the localized zero digit defined in
2055      * the <code>DecimalFormatSymbols</code> object.
2056      *
2057      * @param text the string to be parsed
2058      * @param pos  A <code>ParsePosition</code> object with index and error
2059      *             index information as described above.
2060      * @return     the parsed value, or <code>null</code> if the parse fails
2061      * @exception  NullPointerException if <code>text</code> or
2062      *             <code>pos</code> is null.
2063      */

2064     @Override
2065     public Number parse(String text, ParsePosition pos) {
2066         // special case NaN
2067         if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) {
2068             pos.index = pos.index + symbols.getNaN().length();
2069             return Double.valueOf(Double.NaN);
2070         }
2071
2072         boolean[] status = new boolean[STATUS_LENGTH];
2073         if (!subparse(text, pos, positivePrefix, negativePrefix, digitList, false, status)) {
2074             return null;
2075         }
2076
2077         // special case INFINITY
2078         if (status[STATUS_INFINITE]) {
2079             if (status[STATUS_POSITIVE] == (multiplier >= 0)) {
2080                 return Double.valueOf(Double.POSITIVE_INFINITY);
2081             } else {
2082                 return Double.valueOf(Double.NEGATIVE_INFINITY);
2083             }
2084         }
2085
2086         if (multiplier == 0) {
2087             if (digitList.isZero()) {
2088                 return Double.valueOf(Double.NaN);
2089             } else if (status[STATUS_POSITIVE]) {
2090                 return Double.valueOf(Double.POSITIVE_INFINITY);
2091             } else {
2092                 return Double.valueOf(Double.NEGATIVE_INFINITY);
2093             }
2094         }
2095
2096         if (isParseBigDecimal()) {
2097             BigDecimal bigDecimalResult = digitList.getBigDecimal();
2098
2099             if (multiplier != 1) {
2100                 try {
2101                     bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier());
2102                 }
2103                 catch (ArithmeticException e) {  // non-terminating decimal expansion
2104                     bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier(), roundingMode);
2105                 }
2106             }
2107
2108             if (!status[STATUS_POSITIVE]) {
2109                 bigDecimalResult = bigDecimalResult.negate();
2110             }
2111             return bigDecimalResult;
2112         } else {
2113             boolean gotDouble = true;
2114             boolean gotLongMinimum = false;
2115             double  doubleResult = 0.0;
2116             long    longResult = 0;
2117
2118             // Finally, have DigitList parse the digits into a value.
2119             if (digitList.fitsIntoLong(status[STATUS_POSITIVE], isParseIntegerOnly())) {
2120                 gotDouble = false;
2121                 longResult = digitList.getLong();
2122                 if (longResult < 0) {  // got Long.MIN_VALUE
2123                     gotLongMinimum = true;
2124                 }
2125             } else {
2126                 doubleResult = digitList.getDouble();
2127             }
2128
2129             // Divide by multiplier. We have to be careful here not to do
2130             // unneeded conversions between double and long.
2131             if (multiplier != 1) {
2132                 if (gotDouble) {
2133                     doubleResult /= multiplier;
2134                 } else {
2135                     // Avoid converting to double if we can
2136                     if (longResult % multiplier == 0) {
2137                         longResult /= multiplier;
2138                     } else {
2139                         doubleResult = ((double)longResult) / multiplier;
2140                         gotDouble = true;
2141                     }
2142                 }
2143             }
2144
2145             if (!status[STATUS_POSITIVE] && !gotLongMinimum) {
2146                 doubleResult = -doubleResult;
2147                 longResult = -longResult;
2148             }
2149
2150             // At this point, if we divided the result by the multiplier, the
2151             // result may fit into a long.  We check for this case and return
2152             // a long if possible.
2153             // We must do this AFTER applying the negative (if appropriate)
2154             // in order to handle the case of LONG_MIN; otherwise, if we do
2155             // this with a positive value -LONG_MIN, the double is > 0, but
2156             // the long is < 0. We also must retain a double in the case of
2157             // -0.0, which will compare as == to a long 0 cast to a double
2158             // (bug 4162852).
2159             if (multiplier != 1 && gotDouble) {
2160                 longResult = (long)doubleResult;
2161                 gotDouble = ((doubleResult != (double)longResult) ||
2162                             (doubleResult == 0.0 && 1/doubleResult < 0.0)) &&
2163                             !isParseIntegerOnly();
2164             }
2165
2166             // cast inside of ?: because of binary numeric promotion, JLS 15.25
2167             return gotDouble ? (Number)doubleResult : (Number)longResult;
2168         }
2169     }
2170
2171     /**
2172      * Return a BigInteger multiplier.
2173      */

2174     private BigInteger getBigIntegerMultiplier() {
2175         if (bigIntegerMultiplier == null) {
2176             bigIntegerMultiplier = BigInteger.valueOf(multiplier);
2177         }
2178         return bigIntegerMultiplier;
2179     }
2180     private transient BigInteger bigIntegerMultiplier;
2181
2182     /**
2183      * Return a BigDecimal multiplier.
2184      */

2185     private BigDecimal getBigDecimalMultiplier() {
2186         if (bigDecimalMultiplier == null) {
2187             bigDecimalMultiplier = new BigDecimal(multiplier);
2188         }
2189         return bigDecimalMultiplier;
2190     }
2191     private transient BigDecimal bigDecimalMultiplier;
2192
2193     private static final int STATUS_INFINITE = 0;
2194     private static final int STATUS_POSITIVE = 1;
2195     private static final int STATUS_LENGTH   = 2;
2196
2197     /**
2198      * Parse the given text into a number.  The text is parsed beginning at
2199      * parsePosition, until an unparseable character is seen.
2200      * @param text The string to parse.
2201      * @param parsePosition The position at which to being parsing.  Upon
2202      * return, the first unparseable character.
2203      * @param digits The DigitList to set to the parsed value.
2204      * @param isExponent If true, parse an exponent.  This means no
2205      * infinite values and integer only.
2206      * @param status Upon return contains boolean status flags indicating
2207      * whether the value was infinite and whether it was positive.
2208      */

2209     private final boolean subparse(String text, ParsePosition parsePosition,
2210                    String positivePrefix, String negativePrefix,
2211                    DigitList digits, boolean isExponent,
2212                    boolean status[]) {
2213         int position = parsePosition.index;
2214         int oldStart = parsePosition.index;
2215         int backup;
2216         boolean gotPositive, gotNegative;
2217
2218         // check for positivePrefix; take longest
2219         gotPositive = text.regionMatches(position, positivePrefix, 0,
2220                                          positivePrefix.length());
2221         gotNegative = text.regionMatches(position, negativePrefix, 0,
2222                                          negativePrefix.length());
2223
2224         if (gotPositive && gotNegative) {
2225             if (positivePrefix.length() > negativePrefix.length()) {
2226                 gotNegative = false;
2227             } else if (positivePrefix.length() < negativePrefix.length()) {
2228                 gotPositive = false;
2229             }
2230         }
2231
2232         if (gotPositive) {
2233             position += positivePrefix.length();
2234         } else if (gotNegative) {
2235             position += negativePrefix.length();
2236         } else {
2237             parsePosition.errorIndex = position;
2238             return false;
2239         }
2240
2241         // process digits or Inf, find decimal position
2242         status[STATUS_INFINITE] = false;
2243         if (!isExponent && text.regionMatches(position,symbols.getInfinity(),0,
2244                           symbols.getInfinity().length())) {
2245             position += symbols.getInfinity().length();
2246             status[STATUS_INFINITE] = true;
2247         } else {
2248             // We now have a string of digits, possibly with grouping symbols,
2249             // and decimal points.  We want to process these into a DigitList.
2250             // We don't want to put a bunch of leading zeros into the DigitList
2251             // though, so we keep track of the location of the decimal point,
2252             // put only significant digits into the DigitList, and adjust the
2253             // exponent as needed.
2254
2255             digits.decimalAt = digits.count = 0;
2256             char zero = symbols.getZeroDigit();
2257             char decimal = isCurrencyFormat ?
2258                 symbols.getMonetaryDecimalSeparator() :
2259                 symbols.getDecimalSeparator();
2260             char grouping = symbols.getGroupingSeparator();
2261             String exponentString = symbols.getExponentSeparator();
2262             boolean sawDecimal = false;
2263             boolean sawExponent = false;
2264             boolean sawDigit = false;
2265             int exponent = 0; // Set to the exponent value, if any
2266
2267             // We have to track digitCount ourselves, because digits.count will
2268             // pin when the maximum allowable digits is reached.
2269             int digitCount = 0;
2270
2271             backup = -1;
2272             for (; position < text.length(); ++position) {
2273                 char ch = text.charAt(position);
2274
2275                 /* We recognize all digit ranges, not only the Latin digit range
2276                  * '0'..'9'.  We do so by using the Character.digit() method,
2277                  * which converts a valid Unicode digit to the range 0..9.
2278                  *
2279                  * The character 'ch' may be a digit.  If so, place its value
2280                  * from 0 to 9 in 'digit'.  First try using the locale digit,
2281                  * which may or MAY NOT be a standard Unicode digit range.  If
2282                  * this fails, try using the standard Unicode digit ranges by
2283                  * calling Character.digit().  If this also fails, digit will
2284                  * have a value outside the range 0..9.
2285                  */

2286                 int digit = ch - zero;
2287                 if (digit < 0 || digit > 9) {
2288                     digit = Character.digit(ch, 10);
2289                 }
2290
2291                 if (digit == 0) {
2292                     // Cancel out backup setting (see grouping handler below)
2293                     backup = -1; // Do this BEFORE continue statement below!!!
2294                     sawDigit = true;
2295
2296                     // Handle leading zeros
2297                     if (digits.count == 0) {
2298                         // Ignore leading zeros in integer part of number.
2299                         if (!sawDecimal) {
2300                             continue;
2301                         }
2302
2303                         // If we have seen the decimal, but no significant
2304                         // digits yet, then we account for leading zeros by
2305                         // decrementing the digits.decimalAt into negative
2306                         // values.
2307                         --digits.decimalAt;
2308                     } else {
2309                         ++digitCount;
2310                         digits.append((char)(digit + '0'));
2311                     }
2312                 } else if (digit > 0 && digit <= 9) { // [sic] digit==0 handled above
2313                     sawDigit = true;
2314                     ++digitCount;
2315                     digits.append((char)(digit + '0'));
2316
2317                     // Cancel out backup setting (see grouping handler below)
2318                     backup = -1;
2319                 } else if (!isExponent && ch == decimal) {
2320                     // If we're only parsing integers, or if we ALREADY saw the
2321                     // decimal, then don't parse this one.
2322                     if (isParseIntegerOnly() || sawDecimal) {
2323                         break;
2324                     }
2325                     digits.decimalAt = digitCount; // Not digits.count!
2326                     sawDecimal = true;
2327                 } else if (!isExponent && ch == grouping && isGroupingUsed()) {
2328                     if (sawDecimal) {
2329                         break;
2330                     }
2331                     // Ignore grouping characters, if we are using them, but
2332                     // require that they be followed by a digit.  Otherwise
2333                     // we backup and reprocess them.
2334                     backup = position;
2335                 } else if (!isExponent && text.regionMatches(position, exponentString, 0, exponentString.length())
2336                              && !sawExponent) {
2337                     // Process the exponent by recursively calling this method.
2338                      ParsePosition pos = new ParsePosition(position + exponentString.length());
2339                     boolean[] stat = new boolean[STATUS_LENGTH];
2340                     DigitList exponentDigits = new DigitList();
2341
2342                     if (subparse(text, pos, "", Character.toString(symbols.getMinusSign()), exponentDigits, true, stat) &&
2343                         exponentDigits.fitsIntoLong(stat[STATUS_POSITIVE], true)) {
2344                         position = pos.index; // Advance past the exponent
2345                         exponent = (int)exponentDigits.getLong();
2346                         if (!stat[STATUS_POSITIVE]) {
2347                             exponent = -exponent;
2348                         }
2349                         sawExponent = true;
2350                     }
2351                     break// Whether we fail or succeed, we exit this loop
2352                 } else {
2353                     break;
2354                 }
2355             }
2356
2357             if (backup != -1) {
2358                 position = backup;
2359             }
2360
2361             // If there was no decimal point we have an integer
2362             if (!sawDecimal) {
2363                 digits.decimalAt = digitCount; // Not digits.count!
2364             }
2365
2366             // Adjust for exponent, if any
2367             digits.decimalAt += exponent;
2368
2369             // If none of the text string was recognized.  For example, parse
2370             // "x" with pattern "#0.00" (return index and error index both 0)
2371             // parse "$" with pattern "$#0.00". (return index 0 and error
2372             // index 1).
2373             if (!sawDigit && digitCount == 0) {
2374                 parsePosition.index = oldStart;
2375                 parsePosition.errorIndex = oldStart;
2376                 return false;
2377             }
2378         }
2379
2380         // check for suffix
2381         if (!isExponent) {
2382             if (gotPositive) {
2383                 gotPositive = text.regionMatches(position,positiveSuffix,0,
2384                                                  positiveSuffix.length());
2385             }
2386             if (gotNegative) {
2387                 gotNegative = text.regionMatches(position,negativeSuffix,0,
2388                                                  negativeSuffix.length());
2389             }
2390
2391         // if both match, take longest
2392         if (gotPositive && gotNegative) {
2393             if (positiveSuffix.length() > negativeSuffix.length()) {
2394                 gotNegative = false;
2395             } else if (positiveSuffix.length() < negativeSuffix.length()) {
2396                 gotPositive = false;
2397             }
2398         }
2399
2400         // fail if neither or both
2401         if (gotPositive == gotNegative) {
2402             parsePosition.errorIndex = position;
2403             return false;
2404         }
2405
2406         parsePosition.index = position +
2407             (gotPositive ? positiveSuffix.length() : negativeSuffix.length()); // mark success!
2408         } else {
2409             parsePosition.index = position;
2410         }
2411
2412         status[STATUS_POSITIVE] = gotPositive;
2413         if (parsePosition.index == oldStart) {
2414             parsePosition.errorIndex = position;
2415             return false;
2416         }
2417         return true;
2418     }
2419
2420     /**
2421      * Returns a copy of the decimal format symbols, which is generally not
2422      * changed by the programmer or user.
2423      * @return a copy of the desired DecimalFormatSymbols
2424      * @see java.text.DecimalFormatSymbols
2425      */

2426     public DecimalFormatSymbols getDecimalFormatSymbols() {
2427         try {
2428             // don't allow multiple references
2429             return (DecimalFormatSymbols) symbols.clone();
2430         } catch (Exception foo) {
2431             return null// should never happen
2432         }
2433     }
2434
2435
2436     /**
2437      * Sets the decimal format symbols, which is generally not changed
2438      * by the programmer or user.
2439      * @param newSymbols desired DecimalFormatSymbols
2440      * @see java.text.DecimalFormatSymbols
2441      */

2442     public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
2443         try {
2444             // don't allow multiple references
2445             symbols = (DecimalFormatSymbols) newSymbols.clone();
2446             expandAffixes();
2447             fastPathCheckNeeded = true;
2448         } catch (Exception foo) {
2449             // should never happen
2450         }
2451     }
2452
2453     /**
2454      * Get the positive prefix.
2455      * <P>Examples: +123, $123, sFr123
2456      *
2457      * @return the positive prefix
2458      */

2459     public String getPositivePrefix () {
2460         return positivePrefix;
2461     }
2462
2463     /**
2464      * Set the positive prefix.
2465      * <P>Examples: +123, $123, sFr123
2466      *
2467      * @param newValue the new positive prefix
2468      */

2469     public void setPositivePrefix (String newValue) {
2470         positivePrefix = newValue;
2471         posPrefixPattern = null;
2472         positivePrefixFieldPositions = null;
2473         fastPathCheckNeeded = true;
2474     }
2475
2476     /**
2477      * Returns the FieldPositions of the fields in the prefix used for
2478      * positive numbers. This is not used if the user has explicitly set
2479      * a positive prefix via <code>setPositivePrefix</code>. This is
2480      * lazily created.
2481      *
2482      * @return FieldPositions in positive prefix
2483      */

2484     private FieldPosition[] getPositivePrefixFieldPositions() {
2485         if (positivePrefixFieldPositions == null) {
2486             if (posPrefixPattern != null) {
2487                 positivePrefixFieldPositions = expandAffix(posPrefixPattern);
2488             } else {
2489                 positivePrefixFieldPositions = EmptyFieldPositionArray;
2490             }
2491         }
2492         return positivePrefixFieldPositions;
2493     }
2494
2495     /**
2496      * Get the negative prefix.
2497      * <P>Examples: -123, ($123) (with negative suffix), sFr-123
2498      *
2499      * @return the negative prefix
2500      */

2501     public String getNegativePrefix () {
2502         return negativePrefix;
2503     }
2504
2505     /**
2506      * Set the negative prefix.
2507      * <P>Examples: -123, ($123) (with negative suffix), sFr-123
2508      *
2509      * @param newValue the new negative prefix
2510      */

2511     public void setNegativePrefix (String newValue) {
2512         negativePrefix = newValue;
2513         negPrefixPattern = null;
2514         fastPathCheckNeeded = true;
2515     }
2516
2517     /**
2518      * Returns the FieldPositions of the fields in the prefix used for
2519      * negative numbers. This is not used if the user has explicitly set
2520      * a negative prefix via <code>setNegativePrefix</code>. This is
2521      * lazily created.
2522      *
2523      * @return FieldPositions in positive prefix
2524      */

2525     private FieldPosition[] getNegativePrefixFieldPositions() {
2526         if (negativePrefixFieldPositions == null) {
2527             if (negPrefixPattern != null) {
2528                 negativePrefixFieldPositions = expandAffix(negPrefixPattern);
2529             } else {
2530                 negativePrefixFieldPositions = EmptyFieldPositionArray;
2531             }
2532         }
2533         return negativePrefixFieldPositions;
2534     }
2535
2536     /**
2537      * Get the positive suffix.
2538      * <P>Example: 123%
2539      *
2540      * @return the positive suffix
2541      */

2542     public String getPositiveSuffix () {
2543         return positiveSuffix;
2544     }
2545
2546     /**
2547      * Set the positive suffix.
2548      * <P>Example: 123%
2549      *
2550      * @param newValue the new positive suffix
2551      */

2552     public void setPositiveSuffix (String newValue) {
2553         positiveSuffix = newValue;
2554         posSuffixPattern = null;
2555         fastPathCheckNeeded = true;
2556     }
2557
2558     /**
2559      * Returns the FieldPositions of the fields in the suffix used for
2560      * positive numbers. This is not used if the user has explicitly set
2561      * a positive suffix via <code>setPositiveSuffix</code>. This is
2562      * lazily created.
2563      *
2564      * @return FieldPositions in positive prefix
2565      */

2566     private FieldPosition[] getPositiveSuffixFieldPositions() {
2567         if (positiveSuffixFieldPositions == null) {
2568             if (posSuffixPattern != null) {
2569                 positiveSuffixFieldPositions = expandAffix(posSuffixPattern);
2570             } else {
2571                 positiveSuffixFieldPositions = EmptyFieldPositionArray;
2572             }
2573         }
2574         return positiveSuffixFieldPositions;
2575     }
2576
2577     /**
2578      * Get the negative suffix.
2579      * <P>Examples: -123%, ($123) (with positive suffixes)
2580      *
2581      * @return the negative suffix
2582      */

2583     public String getNegativeSuffix () {
2584         return negativeSuffix;
2585     }
2586
2587     /**
2588      * Set the negative suffix.
2589      * <P>Examples: 123%
2590      *
2591      * @param newValue the new negative suffix
2592      */

2593     public void setNegativeSuffix (String newValue) {
2594         negativeSuffix = newValue;
2595         negSuffixPattern = null;
2596         fastPathCheckNeeded = true;
2597     }
2598
2599     /**
2600      * Returns the FieldPositions of the fields in the suffix used for
2601      * negative numbers. This is not used if the user has explicitly set
2602      * a negative suffix via <code>setNegativeSuffix</code>. This is
2603      * lazily created.
2604      *
2605      * @return FieldPositions in positive prefix
2606      */

2607     private FieldPosition[] getNegativeSuffixFieldPositions() {
2608         if (negativeSuffixFieldPositions == null) {
2609             if (negSuffixPattern != null) {
2610                 negativeSuffixFieldPositions = expandAffix(negSuffixPattern);
2611             } else {
2612                 negativeSuffixFieldPositions = EmptyFieldPositionArray;
2613             }
2614         }
2615         return negativeSuffixFieldPositions;
2616     }
2617
2618     /**
2619      * Gets the multiplier for use in percent, per mille, and similar
2620      * formats.
2621      *
2622      * @return the multiplier
2623      * @see #setMultiplier(int)
2624      */

2625     public int getMultiplier () {
2626         return multiplier;
2627     }
2628
2629     /**
2630      * Sets the multiplier for use in percent, per mille, and similar
2631      * formats.
2632      * For a percent format, set the multiplier to 100 and the suffixes to
2633      * have '%' (for Arabic, use the Arabic percent sign).
2634      * For a per mille format, set the multiplier to 1000 and the suffixes to
2635      * have '&#92;u2030'.
2636      *
2637      * <P>Example: with multiplier 100, 1.23 is formatted as "123", and
2638      * "123" is parsed into 1.23.
2639      *
2640      * @param newValue the new multiplier
2641      * @see #getMultiplier
2642      */

2643     public void setMultiplier (int newValue) {
2644         multiplier = newValue;
2645         bigDecimalMultiplier = null;
2646         bigIntegerMultiplier = null;
2647         fastPathCheckNeeded = true;
2648     }
2649
2650     /**
2651      * {@inheritDoc}
2652      */

2653     @Override
2654     public void setGroupingUsed(boolean newValue) {
2655         super.setGroupingUsed(newValue);
2656         fastPathCheckNeeded = true;
2657     }
2658
2659     /**
2660      * Return the grouping size. Grouping size is the number of digits between
2661      * grouping separators in the integer portion of a number.  For example,
2662      * in the number "123,456.78", the grouping size is 3.
2663      *
2664      * @return the grouping size
2665      * @see #setGroupingSize
2666      * @see java.text.NumberFormat#isGroupingUsed
2667      * @see java.text.DecimalFormatSymbols#getGroupingSeparator
2668      */

2669     public int getGroupingSize () {
2670         return groupingSize;
2671     }
2672
2673     /**
2674      * Set the grouping size. Grouping size is the number of digits between
2675      * grouping separators in the integer portion of a number.  For example,
2676      * in the number "123,456.78", the grouping size is 3.
2677      * <br>
2678      * The value passed in is converted to a byte, which may lose information.
2679      *
2680      * @param newValue the new grouping size
2681      * @see #getGroupingSize
2682      * @see java.text.NumberFormat#setGroupingUsed
2683      * @see java.text.DecimalFormatSymbols#setGroupingSeparator
2684      */

2685     public void setGroupingSize (int newValue) {
2686         groupingSize = (byte)newValue;
2687         fastPathCheckNeeded = true;
2688     }
2689
2690     /**
2691      * Allows you to get the behavior of the decimal separator with integers.
2692      * (The decimal separator will always appear with decimals.)
2693      * <P>Example: Decimal ON: 12345 &rarr; 12345.; OFF: 12345 &rarr; 12345
2694      *
2695      * @return {@code trueif the decimal separator is always shown;
2696      *         {@code false} otherwise
2697      */

2698     public boolean isDecimalSeparatorAlwaysShown() {
2699         return decimalSeparatorAlwaysShown;
2700     }
2701
2702     /**
2703      * Allows you to set the behavior of the decimal separator with integers.
2704      * (The decimal separator will always appear with decimals.)
2705      * <P>Example: Decimal ON: 12345 &rarr; 12345.; OFF: 12345 &rarr; 12345
2706      *
2707      * @param newValue {@code trueif the decimal separator is always shown;
2708      *                 {@code false} otherwise
2709      */

2710     public void setDecimalSeparatorAlwaysShown(boolean newValue) {
2711         decimalSeparatorAlwaysShown = newValue;
2712         fastPathCheckNeeded = true;
2713     }
2714
2715     /**
2716      * Returns whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
2717      * method returns <code>BigDecimal</code>. The default value is false.
2718      *
2719      * @return {@code trueif the parse method returns BigDecimal;
2720      *         {@code false} otherwise
2721      * @see #setParseBigDecimal
2722      * @since 1.5
2723      */

2724     public boolean isParseBigDecimal() {
2725         return parseBigDecimal;
2726     }
2727
2728     /**
2729      * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
2730      * method returns <code>BigDecimal</code>.
2731      *
2732      * @param newValue {@code trueif the parse method returns BigDecimal;
2733      *                 {@code false} otherwise
2734      * @see #isParseBigDecimal
2735      * @since 1.5
2736      */

2737     public void setParseBigDecimal(boolean newValue) {
2738         parseBigDecimal = newValue;
2739     }
2740
2741     /**
2742      * Standard override; no change in semantics.
2743      */

2744     @Override
2745     public Object clone() {
2746         DecimalFormat other = (DecimalFormat) super.clone();
2747         other.symbols = (DecimalFormatSymbols) symbols.clone();
2748         other.digitList = (DigitList) digitList.clone();
2749
2750         // Fast-path is almost stateless algorithm. The only logical state is the
2751         // isFastPath flag. In addition fastPathCheckNeeded is a sentinel flag
2752         // that forces recalculation of all fast-path fields when set to true.
2753         //
2754         // There is thus no need to clone all the fast-path fields.
2755         // We just only need to set fastPathCheckNeeded to true when cloning,
2756         // and init fastPathData to null as if it were a truly new instance.
2757         // Every fast-path field will be recalculated (only once) at next usage of
2758         // fast-path algorithm.
2759         other.fastPathCheckNeeded = true;
2760         other.isFastPath = false;
2761         other.fastPathData = null;
2762
2763         return other;
2764     }
2765
2766     /**
2767      * Overrides equals
2768      */

2769     @Override
2770     public boolean equals(Object obj)
2771     {
2772         if (obj == null)
2773             return false;
2774         if (!super.equals(obj))
2775             return false// super does class check
2776         DecimalFormat other = (DecimalFormat) obj;
2777         return ((posPrefixPattern == other.posPrefixPattern &&
2778                  positivePrefix.equals(other.positivePrefix))
2779                 || (posPrefixPattern != null &&
2780                     posPrefixPattern.equals(other.posPrefixPattern)))
2781             && ((posSuffixPattern == other.posSuffixPattern &&
2782                  positiveSuffix.equals(other.positiveSuffix))
2783                 || (posSuffixPattern != null &&
2784                     posSuffixPattern.equals(other.posSuffixPattern)))
2785             && ((negPrefixPattern == other.negPrefixPattern &&
2786                  negativePrefix.equals(other.negativePrefix))
2787                 || (negPrefixPattern != null &&
2788                     negPrefixPattern.equals(other.negPrefixPattern)))
2789             && ((negSuffixPattern == other.negSuffixPattern &&
2790                  negativeSuffix.equals(other.negativeSuffix))
2791                 || (negSuffixPattern != null &&
2792                     negSuffixPattern.equals(other.negSuffixPattern)))
2793             && multiplier == other.multiplier
2794             && groupingSize == other.groupingSize
2795             && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown
2796             && parseBigDecimal == other.parseBigDecimal
2797             && useExponentialNotation == other.useExponentialNotation
2798             && (!useExponentialNotation ||
2799                 minExponentDigits == other.minExponentDigits)
2800             && maximumIntegerDigits == other.maximumIntegerDigits
2801             && minimumIntegerDigits == other.minimumIntegerDigits
2802             && maximumFractionDigits == other.maximumFractionDigits
2803             && minimumFractionDigits == other.minimumFractionDigits
2804             && roundingMode == other.roundingMode
2805             && symbols.equals(other.symbols);
2806     }
2807
2808     /**
2809      * Overrides hashCode
2810      */

2811     @Override
2812     public int hashCode() {
2813         return super.hashCode() * 37 + positivePrefix.hashCode();
2814         // just enough fields for a reasonable distribution
2815     }
2816
2817     /**
2818      * Synthesizes a pattern string that represents the current state
2819      * of this Format object.
2820      *
2821      * @return a pattern string
2822      * @see #applyPattern
2823      */

2824     public String toPattern() {
2825         return toPattern( false );
2826     }
2827
2828     /**
2829      * Synthesizes a localized pattern string that represents the current
2830      * state of this Format object.
2831      *
2832      * @return a localized pattern string
2833      * @see #applyPattern
2834      */

2835     public String toLocalizedPattern() {
2836         return toPattern( true );
2837     }
2838
2839     /**
2840      * Expand the affix pattern strings into the expanded affix strings.  If any
2841      * affix pattern string is nulldo not expand it.  This method should be
2842      * called any time the symbols or the affix patterns change in order to keep
2843      * the expanded affix strings up to date.
2844      */

2845     private void expandAffixes() {
2846         // Reuse one StringBuffer for better performance
2847         StringBuffer buffer = new StringBuffer();
2848         if (posPrefixPattern != null) {
2849             positivePrefix = expandAffix(posPrefixPattern, buffer);
2850             positivePrefixFieldPositions = null;
2851         }
2852         if (posSuffixPattern != null) {
2853             positiveSuffix = expandAffix(posSuffixPattern, buffer);
2854             positiveSuffixFieldPositions = null;
2855         }
2856         if (negPrefixPattern != null) {
2857             negativePrefix = expandAffix(negPrefixPattern, buffer);
2858             negativePrefixFieldPositions = null;
2859         }
2860         if (negSuffixPattern != null) {
2861             negativeSuffix = expandAffix(negSuffixPattern, buffer);
2862             negativeSuffixFieldPositions = null;
2863         }
2864     }
2865
2866     /**
2867      * Expand an affix pattern into an affix string.  All characters in the
2868      * pattern are literal unless prefixed by QUOTE.  The following characters
2869      * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2870      * PATTERN_MINUS, and CURRENCY_SIGN.  If CURRENCY_SIGN is doubled (QUOTE +
2871      * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
2872      * currency code.  Any other character after a QUOTE represents itself.
2873      * QUOTE must be followed by another character; QUOTE may not occur by
2874      * itself at the end of the pattern.
2875      *
2876      * @param pattern the non-null, possibly empty pattern
2877      * @param buffer a scratch StringBuffer; its contents will be lost
2878      * @return the expanded equivalent of pattern
2879      */

2880     private String expandAffix(String pattern, StringBuffer buffer) {
2881         buffer.setLength(0);
2882         for (int i=0; i<pattern.length(); ) {
2883             char c = pattern.charAt(i++);
2884             if (c == QUOTE) {
2885                 c = pattern.charAt(i++);
2886                 switch (c) {
2887                 case CURRENCY_SIGN:
2888                     if (i<pattern.length() &&
2889                         pattern.charAt(i) == CURRENCY_SIGN) {
2890                         ++i;
2891                         buffer.append(symbols.getInternationalCurrencySymbol());
2892                     } else {
2893                         buffer.append(symbols.getCurrencySymbol());
2894                     }
2895                     continue;
2896                 case PATTERN_PERCENT:
2897                     c = symbols.getPercent();
2898                     break;
2899                 case PATTERN_PER_MILLE:
2900                     c = symbols.getPerMill();
2901                     break;
2902                 case PATTERN_MINUS:
2903                     c = symbols.getMinusSign();
2904                     break;
2905                 }
2906             }
2907             buffer.append(c);
2908         }
2909         return buffer.toString();
2910     }
2911
2912     /**
2913      * Expand an affix pattern into an array of FieldPositions describing
2914      * how the pattern would be expanded.
2915      * All characters in the
2916      * pattern are literal unless prefixed by QUOTE.  The following characters
2917      * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2918      * PATTERN_MINUS, and CURRENCY_SIGN.  If CURRENCY_SIGN is doubled (QUOTE +
2919      * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
2920      * currency code.  Any other character after a QUOTE represents itself.
2921      * QUOTE must be followed by another character; QUOTE may not occur by
2922      * itself at the end of the pattern.
2923      *
2924      * @param pattern the non-null, possibly empty pattern
2925      * @return FieldPosition array of the resulting fields.
2926      */

2927     private FieldPosition[] expandAffix(String pattern) {
2928         ArrayList<FieldPosition> positions = null;
2929         int stringIndex = 0;
2930         for (int i=0; i<pattern.length(); ) {
2931             char c = pattern.charAt(i++);
2932             if (c == QUOTE) {
2933                 int field = -1;
2934                 Format.Field fieldID = null;
2935                 c = pattern.charAt(i++);
2936                 switch (c) {
2937                 case CURRENCY_SIGN:
2938                     String string;
2939                     if (i<pattern.length() &&
2940                         pattern.charAt(i) == CURRENCY_SIGN) {
2941                         ++i;
2942                         string = symbols.getInternationalCurrencySymbol();
2943                     } else {
2944                         string = symbols.getCurrencySymbol();
2945                     }
2946                     if (!string.isEmpty()) {
2947                         if (positions == null) {
2948                             positions = new ArrayList<>(2);
2949                         }
2950                         FieldPosition fp = new FieldPosition(Field.CURRENCY);
2951                         fp.setBeginIndex(stringIndex);
2952                         fp.setEndIndex(stringIndex + string.length());
2953                         positions.add(fp);
2954                         stringIndex += string.length();
2955                     }
2956                     continue;
2957                 case PATTERN_PERCENT:
2958                     c = symbols.getPercent();
2959                     field = -1;
2960                     fieldID = Field.PERCENT;
2961                     break;
2962                 case PATTERN_PER_MILLE:
2963                     c = symbols.getPerMill();
2964                     field = -1;
2965                     fieldID = Field.PERMILLE;
2966                     break;
2967                 case PATTERN_MINUS:
2968                     c = symbols.getMinusSign();
2969                     field = -1;
2970                     fieldID = Field.SIGN;
2971                     break;
2972                 }
2973                 if (fieldID != null) {
2974                     if (positions == null) {
2975                         positions = new ArrayList<>(2);
2976                     }
2977                     FieldPosition fp = new FieldPosition(fieldID, field);
2978                     fp.setBeginIndex(stringIndex);
2979                     fp.setEndIndex(stringIndex + 1);
2980                     positions.add(fp);
2981                 }
2982             }
2983             stringIndex++;
2984         }
2985         if (positions != null) {
2986             return positions.toArray(EmptyFieldPositionArray);
2987         }
2988         return EmptyFieldPositionArray;
2989     }
2990
2991     /**
2992      * Appends an affix pattern to the given StringBuffer, quoting special
2993      * characters as needed.  Uses the internal affix pattern, if that exists,
2994      * or the literal affix, if the internal affix pattern is null.  The
2995      * appended string will generate the same affix pattern (or literal affix)
2996      * when passed to toPattern().
2997      *
2998      * @param buffer the affix string is appended to this
2999      * @param affixPattern a pattern such as posPrefixPattern; may be null
3000      * @param expAffix a corresponding expanded affix, such as positivePrefix.
3001      * Ignored unless affixPattern is null.  If affixPattern is null, then
3002      * expAffix is appended as a literal affix.
3003      * @param localized true if the appended pattern should contain localized
3004      * pattern characters; otherwise, non-localized pattern chars are appended
3005      */

3006     private void appendAffix(StringBuffer buffer, String affixPattern,
3007                              String expAffix, boolean localized) {
3008         if (affixPattern == null) {
3009             appendAffix(buffer, expAffix, localized);
3010         } else {
3011             int i;
3012             for (int pos=0; pos<affixPattern.length(); pos=i) {
3013                 i = affixPattern.indexOf(QUOTE, pos);
3014                 if (i < 0) {
3015                     appendAffix(buffer, affixPattern.substring(pos), localized);
3016                     break;
3017                 }
3018                 if (i > pos) {
3019                     appendAffix(buffer, affixPattern.substring(pos, i), localized);
3020                 }
3021                 char c = affixPattern.charAt(++i);
3022                 ++i;
3023                 if (c == QUOTE) {
3024                     buffer.append(c);
3025                     // Fall through and append another QUOTE below
3026                 } else if (c == CURRENCY_SIGN &&
3027                            i<affixPattern.length() &&
3028                            affixPattern.charAt(i) == CURRENCY_SIGN) {
3029                     ++i;
3030                     buffer.append(c);
3031                     // Fall through and append another CURRENCY_SIGN below
3032                 } else if (localized) {
3033                     switch (c) {
3034                     case PATTERN_PERCENT:
3035                         c = symbols.getPercent();
3036                         break;
3037                     case PATTERN_PER_MILLE:
3038                         c = symbols.getPerMill();
3039                         break;
3040                     case PATTERN_MINUS:
3041                         c = symbols.getMinusSign();
3042                         break;
3043                     }
3044                 }
3045                 buffer.append(c);
3046             }
3047         }
3048     }
3049
3050     /**
3051      * Append an affix to the given StringBuffer, using quotes if
3052      * there are special characters.  Single quotes themselves must be
3053      * escaped in either case.
3054      */

3055     private void appendAffix(StringBuffer buffer, String affix, boolean localized) {
3056         boolean needQuote;
3057         if (localized) {
3058             needQuote = affix.indexOf(symbols.getZeroDigit()) >= 0
3059                 || affix.indexOf(symbols.getGroupingSeparator()) >= 0
3060                 || affix.indexOf(symbols.getDecimalSeparator()) >= 0
3061                 || affix.indexOf(symbols.getPercent()) >= 0
3062                 || affix.indexOf(symbols.getPerMill()) >= 0
3063                 || affix.indexOf(symbols.getDigit()) >= 0
3064                 || affix.indexOf(symbols.getPatternSeparator()) >= 0
3065                 || affix.indexOf(symbols.getMinusSign()) >= 0
3066                 || affix.indexOf(CURRENCY_SIGN) >= 0;
3067         } else {
3068             needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 0
3069                 || affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 0
3070                 || affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 0
3071                 || affix.indexOf(PATTERN_PERCENT) >= 0
3072                 || affix.indexOf(PATTERN_PER_MILLE) >= 0
3073                 || affix.indexOf(PATTERN_DIGIT) >= 0
3074                 || affix.indexOf(PATTERN_SEPARATOR) >= 0
3075                 || affix.indexOf(PATTERN_MINUS) >= 0
3076                 || affix.indexOf(CURRENCY_SIGN) >= 0;
3077         }
3078         if (needQuote) buffer.append('\'');
3079         if (affix.indexOf('\'') < 0) buffer.append(affix);
3080         else {
3081             for (int j=0; j<affix.length(); ++j) {
3082                 char c = affix.charAt(j);
3083                 buffer.append(c);
3084                 if (c == '\'') buffer.append(c);
3085             }
3086         }
3087         if (needQuote) buffer.append('\'');
3088     }
3089
3090     /**
3091      * Does the real work of generating a pattern.  */

3092     private String toPattern(boolean localized) {
3093         StringBuffer result = new StringBuffer();
3094         for (int j = 1; j >= 0; --j) {
3095             if (j == 1)
3096                 appendAffix(result, posPrefixPattern, positivePrefix, localized);
3097             else appendAffix(result, negPrefixPattern, negativePrefix, localized);
3098             int i;
3099             int digitCount = useExponentialNotation
3100                         ? getMaximumIntegerDigits()
3101                         : Math.max(groupingSize, getMinimumIntegerDigits())+1;
3102             for (i = digitCount; i > 0; --i) {
3103                 if (i != digitCount && isGroupingUsed() && groupingSize != 0 &&
3104                     i % groupingSize == 0) {
3105                     result.append(localized ? symbols.getGroupingSeparator() :
3106                                   PATTERN_GROUPING_SEPARATOR);
3107                 }
3108                 result.append(i <= getMinimumIntegerDigits()
3109                     ? (localized ? symbols.getZeroDigit() : PATTERN_ZERO_DIGIT)
3110                     : (localized ? symbols.getDigit() : PATTERN_DIGIT));
3111             }
3112             if (getMaximumFractionDigits() > 0 || decimalSeparatorAlwaysShown)
3113                 result.append(localized ? symbols.getDecimalSeparator() :
3114                               PATTERN_DECIMAL_SEPARATOR);
3115             for (i = 0; i < getMaximumFractionDigits(); ++i) {
3116                 if (i < getMinimumFractionDigits()) {
3117                     result.append(localized ? symbols.getZeroDigit() :
3118                                   PATTERN_ZERO_DIGIT);
3119                 } else {
3120                     result.append(localized ? symbols.getDigit() :
3121                                   PATTERN_DIGIT);
3122                 }
3123             }
3124         if (useExponentialNotation)
3125         {
3126             result.append(localized ? symbols.getExponentSeparator() :
3127                   PATTERN_EXPONENT);
3128         for (i=0; i<minExponentDigits; ++i)
3129                     result.append(localized ? symbols.getZeroDigit() :
3130                                   PATTERN_ZERO_DIGIT);
3131         }
3132             if (j == 1) {
3133                 appendAffix(result, posSuffixPattern, positiveSuffix, localized);
3134                 if ((negSuffixPattern == posSuffixPattern && // n == p == null
3135                      negativeSuffix.equals(positiveSuffix))
3136                     || (negSuffixPattern != null &&
3137                         negSuffixPattern.equals(posSuffixPattern))) {
3138                     if ((negPrefixPattern != null && posPrefixPattern != null &&
3139                          negPrefixPattern.equals("'-" + posPrefixPattern)) ||
3140                         (negPrefixPattern == posPrefixPattern && // n == p == null
3141                          negativePrefix.equals(symbols.getMinusSign() + positivePrefix)))
3142                         break;
3143                 }
3144                 result.append(localized ? symbols.getPatternSeparator() :
3145                               PATTERN_SEPARATOR);
3146             } else appendAffix(result, negSuffixPattern, negativeSuffix, localized);
3147         }
3148         return result.toString();
3149     }
3150
3151     /**
3152      * Apply the given pattern to this Format object.  A pattern is a
3153      * short-hand specification for the various formatting properties.
3154      * These properties can also be changed individually through the
3155      * various setter methods.
3156      * <p>
3157      * There is no limit to integer digits set
3158      * by this routine, since that is the typical end-user desire;
3159      * use setMaximumInteger if you want to set a real value.
3160      * For negative numbers, use a second pattern, separated by a semicolon
3161      * <P>Example <code>"#,#00.0#"</code> &rarr; 1,234.56
3162      * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
3163      * a maximum of 2 fraction digits.
3164      * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
3165      * parentheses.
3166      * <p>In negative patterns, the minimum and maximum counts are ignored;
3167      * these are presumed to be set in the positive pattern.
3168      *
3169      * @param pattern a new pattern
3170      * @exception NullPointerException if <code>pattern</code> is null
3171      * @exception IllegalArgumentException if the given pattern is invalid.
3172      */

3173     public void applyPattern(String pattern) {
3174         applyPattern(pattern, false);
3175     }
3176
3177     /**
3178      * Apply the given pattern to this Format object.  The pattern
3179      * is assumed to be in a localized notation. A pattern is a
3180      * short-hand specification for the various formatting properties.
3181      * These properties can also be changed individually through the
3182      * various setter methods.
3183      * <p>
3184      * There is no limit to integer digits set
3185      * by this routine, since that is the typical end-user desire;
3186      * use setMaximumInteger if you want to set a real value.
3187      * For negative numbers, use a second pattern, separated by a semicolon
3188      * <P>Example <code>"#,#00.0#"</code> &rarr; 1,234.56
3189      * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
3190      * a maximum of 2 fraction digits.
3191      * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
3192      * parentheses.
3193      * <p>In negative patterns, the minimum and maximum counts are ignored;
3194      * these are presumed to be set in the positive pattern.
3195      *
3196      * @param pattern a new pattern
3197      * @exception NullPointerException if <code>pattern</code> is null
3198      * @exception IllegalArgumentException if the given pattern is invalid.
3199      */

3200     public void applyLocalizedPattern(String pattern) {
3201         applyPattern(pattern, true);
3202     }
3203
3204     /**
3205      * Does the real work of applying a pattern.
3206      */

3207     private void applyPattern(String pattern, boolean localized) {
3208         char zeroDigit         = PATTERN_ZERO_DIGIT;
3209         char groupingSeparator = PATTERN_GROUPING_SEPARATOR;
3210         char decimalSeparator  = PATTERN_DECIMAL_SEPARATOR;
3211         char percent           = PATTERN_PERCENT;
3212         char perMill           = PATTERN_PER_MILLE;
3213         char digit             = PATTERN_DIGIT;
3214         char separator         = PATTERN_SEPARATOR;
3215         String exponent          = PATTERN_EXPONENT;
3216         char minus             = PATTERN_MINUS;
3217         if (localized) {
3218             zeroDigit         = symbols.getZeroDigit();
3219             groupingSeparator = symbols.getGroupingSeparator();
3220             decimalSeparator  = symbols.getDecimalSeparator();
3221             percent           = symbols.getPercent();
3222             perMill           = symbols.getPerMill();
3223             digit             = symbols.getDigit();
3224             separator         = symbols.getPatternSeparator();
3225             exponent          = symbols.getExponentSeparator();
3226             minus             = symbols.getMinusSign();
3227         }
3228         boolean gotNegative = false;
3229         decimalSeparatorAlwaysShown = false;
3230         isCurrencyFormat = false;
3231         useExponentialNotation = false;
3232
3233         int start = 0;
3234         for (int j = 1; j >= 0 && start < pattern.length(); --j) {
3235             boolean inQuote = false;
3236             StringBuffer prefix = new StringBuffer();
3237             StringBuffer suffix = new StringBuffer();
3238             int decimalPos = -1;
3239             int multiplier = 1;
3240             int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0;
3241             byte groupingCount = -1;
3242
3243             // The phase ranges from 0 to 2.  Phase 0 is the prefix.  Phase 1 is
3244             // the section of the pattern with digits, decimal separator,
3245             // grouping characters.  Phase 2 is the suffix.  In phases 0 and 2,
3246             // percent, per mille, and currency symbols are recognized and
3247             // translated.  The separation of the characters into phases is
3248             // strictly enforced; if phase 1 characters are to appear in the
3249             // suffix, for example, they must be quoted.
3250             int phase = 0;
3251
3252             // The affix is either the prefix or the suffix.
3253             StringBuffer affix = prefix;
3254
3255             for (int pos = start; pos < pattern.length(); ++pos) {
3256                 char ch = pattern.charAt(pos);
3257                 switch (phase) {
3258                 case 0:
3259                 case 2:
3260                     // Process the prefix / suffix characters
3261                     if (inQuote) {
3262                         // A quote within quotes indicates either the closing
3263                         // quote or two quotes, which is a quote literal. That
3264                         // is, we have the second quote in 'do' or 'don''t'.
3265                         if (ch == QUOTE) {
3266                             if ((pos+1) < pattern.length() &&
3267                                 pattern.charAt(pos+1) == QUOTE) {
3268                                 ++pos;
3269                                 affix.append("''"); // 'don''t'
3270                             } else {
3271                                 inQuote = false// 'do'
3272                             }
3273                             continue;
3274                         }
3275                     } else {
3276                         // Process unquoted characters seen in prefix or suffix
3277                         // phase.
3278                         if (ch == digit ||
3279                             ch == zeroDigit ||
3280                             ch == groupingSeparator ||
3281                             ch == decimalSeparator) {
3282                             phase = 1;
3283                             --pos; // Reprocess this character
3284                             continue;
3285                         } else if (ch == CURRENCY_SIGN) {
3286                             // Use lookahead to determine if the currency sign
3287                             // is doubled or not.
3288                             boolean doubled = (pos + 1) < pattern.length() &&
3289                                 pattern.charAt(pos + 1) == CURRENCY_SIGN;
3290                             if (doubled) { // Skip over the doubled character
3291                              ++pos;
3292                             }
3293                             isCurrencyFormat = true;
3294                             affix.append(doubled ? "'\u00A4\u00A4" : "'\u00A4");
3295                             continue;
3296                         } else if (ch == QUOTE) {
3297                             // A quote outside quotes indicates either the
3298                             // opening quote or two quotes, which is a quote
3299                             // literal. That is, we have the first quote in 'do'
3300                             // or o''clock.
3301                             if (ch == QUOTE) {
3302                                 if ((pos+1) < pattern.length() &&
3303                                     pattern.charAt(pos+1) == QUOTE) {
3304                                     ++pos;
3305                                     affix.append("''"); // o''clock
3306                                 } else {
3307                                     inQuote = true// 'do'
3308                                 }
3309                                 continue;
3310                             }
3311                         } else if (ch == separator) {
3312                             // Don't allow separators before we see digit
3313                             // characters of phase 1, and don't allow separators
3314                             // in the second pattern (j == 0).
3315                             if (phase == 0 || j == 0) {
3316                                 throw new IllegalArgumentException("Unquoted special character '" +
3317                                     ch + "' in pattern \"" + pattern + '"');
3318                             }
3319                             start = pos + 1;
3320                             pos = pattern.length();
3321                             continue;
3322                         }
3323
3324                         // Next handle characters which are appended directly.
3325                         else if (ch == percent) {
3326                             if (multiplier != 1) {
3327                                 throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +
3328                                     pattern + '"');
3329                             }
3330                             multiplier = 100;
3331                             affix.append("'%");
3332                             continue;
3333                         } else if (ch == perMill) {
3334                             if (multiplier != 1) {
3335                                 throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +
3336                                     pattern + '"');
3337                             }
3338                             multiplier = 1000;
3339                             affix.append("'\u2030");
3340                             continue;
3341                         } else if (ch == minus) {
3342                             affix.append("'-");
3343                             continue;
3344                         }
3345                     }
3346                     // Note that if we are within quotes, or if this is an
3347                     // unquoted, non-special character, then we usually fall
3348                     // through to here.
3349                     affix.append(ch);
3350                     break;
3351
3352                 case 1:
3353                     // The negative subpattern (j = 0) serves only to specify the
3354                     // negative prefix and suffix, so all the phase 1 characters
3355                     // e.g. digits, zeroDigit, groupingSeparator,
3356                     // decimalSeparator, exponent are ignored
3357                     if (j == 0) {
3358                         while (pos < pattern.length()) {
3359                             char negPatternChar = pattern.charAt(pos);
3360                             if (negPatternChar == digit
3361                                     || negPatternChar == zeroDigit
3362                                     || negPatternChar == groupingSeparator
3363                                     || negPatternChar == decimalSeparator) {
3364                                 ++pos;
3365                             } else if (pattern.regionMatches(pos, exponent,
3366                                     0, exponent.length())) {
3367                                 pos = pos + exponent.length();
3368                             } else {
3369                                 // Not a phase 1 character, consider it as
3370                                 // suffix and parse it in phase 2
3371                                 --pos; //process it again in outer loop
3372                                 phase = 2;
3373                                 affix = suffix;
3374                                 break;
3375                             }
3376                         }
3377                         continue;
3378                     }
3379
3380                     // Process the digits, decimal, and grouping characters. We
3381                     // record five pieces of information. We expect the digits
3382                     // to occur in the pattern ####0000.####, and we record the
3383                     // number of left digits, zero (central) digits, and right
3384                     // digits. The position of the last grouping character is
3385                     // recorded (should be somewhere within the first two blocks
3386                     // of characters), as is the position of the decimal point,
3387                     // if any (should be in the zero digits). If there is no
3388                     // decimal point, then there should be no right digits.
3389                     if (ch == digit) {
3390                         if (zeroDigitCount > 0) {
3391                             ++digitRightCount;
3392                         } else {
3393                             ++digitLeftCount;
3394                         }
3395                         if (groupingCount >= 0 && decimalPos < 0) {
3396                             ++groupingCount;
3397                         }
3398                     } else if (ch == zeroDigit) {
3399                         if (digitRightCount > 0) {
3400                             throw new IllegalArgumentException("Unexpected '0' in pattern \"" +
3401                                 pattern + '"');
3402                         }
3403                         ++zeroDigitCount;
3404                         if (groupingCount >= 0 && decimalPos < 0) {
3405                             ++groupingCount;
3406                         }
3407                     } else if (ch == groupingSeparator) {
3408                         groupingCount = 0;
3409                     } else if (ch == decimalSeparator) {
3410                         if (decimalPos >= 0) {
3411                             throw new IllegalArgumentException("Multiple decimal separators in pattern \"" +
3412                                 pattern + '"');
3413                         }
3414                         decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
3415                     } else if (pattern.regionMatches(pos, exponent, 0, exponent.length())){
3416                         if (useExponentialNotation) {
3417                             throw new IllegalArgumentException("Multiple exponential " +
3418                                 "symbols in pattern \"" + pattern + '"');
3419                         }
3420                         useExponentialNotation = true;
3421                         minExponentDigits = 0;
3422
3423                         // Use lookahead to parse out the exponential part
3424                         // of the pattern, then jump into phase 2.
3425                         pos = pos+exponent.length();
3426                          while (pos < pattern.length() &&
3427                                pattern.charAt(pos) == zeroDigit) {
3428                             ++minExponentDigits;
3429                             ++pos;
3430                         }
3431
3432                         if ((digitLeftCount + zeroDigitCount) < 1 ||
3433                             minExponentDigits < 1) {
3434                             throw new IllegalArgumentException("Malformed exponential " +
3435                                 "pattern \"" + pattern + '"');
3436                         }
3437
3438                         // Transition to phase 2
3439                         phase = 2;
3440                         affix = suffix;
3441                         --pos;
3442                         continue;
3443                     } else {
3444                         phase = 2;
3445                         affix = suffix;
3446                         --pos;
3447                         continue;
3448                     }
3449                     break;
3450                 }
3451             }
3452
3453             // Handle patterns with no '0' pattern character. These patterns
3454             // are legal, but must be interpreted.  "##.###" -> "#0.###".
3455             // ".###" -> ".0##".
3456             /* We allow patterns of the form "####" to produce a zeroDigitCount
3457              * of zero (got that?); although this seems like it might make it
3458              * possible for format() to produce empty strings, format() checks
3459              * for this condition and outputs a zero digit in this situation.
3460              * Having a zeroDigitCount of zero yields a minimum integer digits
3461              * of zero, which allows proper round-trip patterns.  That is, we
3462              * don't want "#" to become "#0" when toPattern() is called (even
3463              * though that's what it really is, semantically).
3464              */

3465             if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {
3466                 // Handle "###.###" and "###." and ".###"
3467                 int n = decimalPos;
3468                 if (n == 0) { // Handle ".###"
3469                     ++n;
3470                 }
3471                 digitRightCount = digitLeftCount - n;
3472                 digitLeftCount = n - 1;
3473                 zeroDigitCount = 1;
3474             }
3475
3476             // Do syntax checking on the digits.
3477             if ((decimalPos < 0 && digitRightCount > 0) ||
3478                 (decimalPos >= 0 && (decimalPos < digitLeftCount ||
3479                  decimalPos > (digitLeftCount + zeroDigitCount))) ||
3480                  groupingCount == 0 || inQuote) {
3481                 throw new IllegalArgumentException("Malformed pattern \"" +
3482                     pattern + '"');
3483             }
3484
3485             if (j == 1) {
3486                 posPrefixPattern = prefix.toString();
3487                 posSuffixPattern = suffix.toString();
3488                 negPrefixPattern = posPrefixPattern;   // assume these for now
3489                 negSuffixPattern = posSuffixPattern;
3490                 int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
3491                 /* The effectiveDecimalPos is the position the decimal is at or
3492                  * would be at if there is no decimal. Note that if decimalPos<0,
3493                  * then digitTotalCount == digitLeftCount + zeroDigitCount.
3494                  */

3495                 int effectiveDecimalPos = decimalPos >= 0 ?
3496                     decimalPos : digitTotalCount;
3497                 setMinimumIntegerDigits(effectiveDecimalPos - digitLeftCount);
3498                 setMaximumIntegerDigits(useExponentialNotation ?
3499                     digitLeftCount + getMinimumIntegerDigits() :
3500                     MAXIMUM_INTEGER_DIGITS);
3501                 setMaximumFractionDigits(decimalPos >= 0 ?
3502                     (digitTotalCount - decimalPos) : 0);
3503                 setMinimumFractionDigits(decimalPos >= 0 ?
3504                     (digitLeftCount + zeroDigitCount - decimalPos) : 0);
3505                 setGroupingUsed(groupingCount > 0);
3506                 this.groupingSize = (groupingCount > 0) ? groupingCount : 0;
3507                 this.multiplier = multiplier;
3508                 setDecimalSeparatorAlwaysShown(decimalPos == 0 ||
3509                     decimalPos == digitTotalCount);
3510             } else {
3511                 negPrefixPattern = prefix.toString();
3512                 negSuffixPattern = suffix.toString();
3513                 gotNegative = true;
3514             }
3515         }
3516
3517         if (pattern.isEmpty()) {
3518             posPrefixPattern = posSuffixPattern = "";
3519             setMinimumIntegerDigits(0);
3520             setMaximumIntegerDigits(MAXIMUM_INTEGER_DIGITS);
3521             setMinimumFractionDigits(0);
3522             setMaximumFractionDigits(MAXIMUM_FRACTION_DIGITS);
3523         }
3524
3525         // If there was no negative pattern, or if the negative pattern is
3526         // identical to the positive pattern, then prepend the minus sign to
3527         // the positive pattern to form the negative pattern.
3528         if (!gotNegative ||
3529             (negPrefixPattern.equals(posPrefixPattern)
3530              && negSuffixPattern.equals(posSuffixPattern))) {
3531             negSuffixPattern = posSuffixPattern;
3532             negPrefixPattern = "'-" + posPrefixPattern;
3533         }
3534
3535         expandAffixes();
3536     }
3537
3538     /**
3539      * Sets the maximum number of digits allowed in the integer portion of a
3540      * number.
3541      * For formatting numbers other than <code>BigInteger</code> and
3542      * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
3543      * 309 is used. Negative input values are replaced with 0.
3544      * @see NumberFormat#setMaximumIntegerDigits
3545      */

3546     @Override
3547     public void setMaximumIntegerDigits(int newValue) {
3548         maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
3549         super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
3550             DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
3551         if (minimumIntegerDigits > maximumIntegerDigits) {
3552             minimumIntegerDigits = maximumIntegerDigits;
3553             super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
3554                 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
3555         }
3556         fastPathCheckNeeded = true;
3557     }
3558
3559     /**
3560      * Sets the minimum number of digits allowed in the integer portion of a
3561      * number.
3562      * For formatting numbers other than <code>BigInteger</code> and
3563      * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
3564      * 309 is used. Negative input values are replaced with 0.
3565      * @see NumberFormat#setMinimumIntegerDigits
3566      */

3567     @Override
3568     public void setMinimumIntegerDigits(int newValue) {
3569         minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
3570         super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
3571             DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
3572         if (minimumIntegerDigits > maximumIntegerDigits) {
3573             maximumIntegerDigits = minimumIntegerDigits;
3574             super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
3575                 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
3576         }
3577         fastPathCheckNeeded = true;
3578     }
3579
3580     /**
3581      * Sets the maximum number of digits allowed in the fraction portion of a
3582      * number.
3583      * For formatting numbers other than <code>BigInteger</code> and
3584      * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
3585      * 340 is used. Negative input values are replaced with 0.
3586      * @see NumberFormat#setMaximumFractionDigits
3587      */

3588     @Override
3589     public void setMaximumFractionDigits(int newValue) {
3590         maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
3591         super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
3592             DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
3593         if (minimumFractionDigits > maximumFractionDigits) {
3594             minimumFractionDigits = maximumFractionDigits;
3595             super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
3596                 DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
3597         }
3598         fastPathCheckNeeded = true;
3599     }
3600
3601     /**
3602      * Sets the minimum number of digits allowed in the fraction portion of a
3603      * number.
3604      * For formatting numbers other than <code>BigInteger</code> and
3605      * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
3606      * 340 is used. Negative input values are replaced with 0.
3607      * @see NumberFormat#setMinimumFractionDigits
3608      */

3609     @Override
3610     public void setMinimumFractionDigits(int newValue) {
3611         minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
3612         super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
3613             DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
3614         if (minimumFractionDigits > maximumFractionDigits) {
3615             maximumFractionDigits = minimumFractionDigits;
3616             super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
3617                 DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
3618         }
3619         fastPathCheckNeeded = true;
3620     }
3621
3622     /**
3623      * Gets the maximum number of digits allowed in the integer portion of a
3624      * number.
3625      * For formatting numbers other than <code>BigInteger</code> and
3626      * <code>BigDecimal</code> objects, the lower of the return value and
3627      * 309 is used.
3628      * @see #setMaximumIntegerDigits
3629      */

3630     @Override
3631     public int getMaximumIntegerDigits() {
3632         return maximumIntegerDigits;
3633     }
3634
3635     /**
3636      * Gets the minimum number of digits allowed in the integer portion of a
3637      * number.
3638      * For formatting numbers other than <code>BigInteger</code> and
3639      * <code>BigDecimal</code> objects, the lower of the return value and
3640      * 309 is used.
3641      * @see #setMinimumIntegerDigits
3642      */

3643     @Override
3644     public int getMinimumIntegerDigits() {
3645         return minimumIntegerDigits;
3646     }
3647
3648     /**
3649      * Gets the maximum number of digits allowed in the fraction portion of a
3650      * number.
3651      * For formatting numbers other than <code>BigInteger</code> and
3652      * <code>BigDecimal</code> objects, the lower of the return value and
3653      * 340 is used.
3654      * @see #setMaximumFractionDigits
3655      */

3656     @Override
3657     public int getMaximumFractionDigits() {
3658         return maximumFractionDigits;
3659     }
3660
3661     /**
3662      * Gets the minimum number of digits allowed in the fraction portion of a
3663      * number.
3664      * For formatting numbers other than <code>BigInteger</code> and
3665      * <code>BigDecimal</code> objects, the lower of the return value and
3666      * 340 is used.
3667      * @see #setMinimumFractionDigits
3668      */

3669     @Override
3670     public int getMinimumFractionDigits() {
3671         return minimumFractionDigits;
3672     }
3673
3674     /**
3675      * Gets the currency used by this decimal format when formatting
3676      * currency values.
3677      * The currency is obtained by calling
3678      * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency}
3679      * on this number format's symbols.
3680      *
3681      * @return the currency used by this decimal format, or <code>null</code>
3682      * @since 1.4
3683      */

3684     @Override
3685     public Currency getCurrency() {
3686         return symbols.getCurrency();
3687     }
3688
3689     /**
3690      * Sets the currency used by this number format when formatting
3691      * currency values. This does not update the minimum or maximum
3692      * number of fraction digits used by the number format.
3693      * The currency is set by calling
3694      * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency}
3695      * on this number format's symbols.
3696      *
3697      * @param currency the new currency to be used by this decimal format
3698      * @exception NullPointerException if <code>currency</code> is null
3699      * @since 1.4
3700      */

3701     @Override
3702     public void setCurrency(Currency currency) {
3703         if (currency != symbols.getCurrency()) {
3704             symbols.setCurrency(currency);
3705             if (isCurrencyFormat) {
3706                 expandAffixes();
3707             }
3708         }
3709         fastPathCheckNeeded = true;
3710     }
3711
3712     /**
3713      * Gets the {@link java.math.RoundingMode} used in this DecimalFormat.
3714      *
3715      * @return The <code>RoundingMode</code> used for this DecimalFormat.
3716      * @see #setRoundingMode(RoundingMode)
3717      * @since 1.6
3718      */

3719     @Override
3720     public RoundingMode getRoundingMode() {
3721         return roundingMode;
3722     }
3723
3724     /**
3725      * Sets the {@link java.math.RoundingMode} used in this DecimalFormat.
3726      *
3727      * @param roundingMode The <code>RoundingMode</code> to be used
3728      * @see #getRoundingMode()
3729      * @exception NullPointerException if <code>roundingMode</code> is null.
3730      * @since 1.6
3731      */

3732     @Override
3733     public void setRoundingMode(RoundingMode roundingMode) {
3734         if (roundingMode == null) {
3735             throw new NullPointerException();
3736         }
3737
3738         this.roundingMode = roundingMode;
3739         digitList.setRoundingMode(roundingMode);
3740         fastPathCheckNeeded = true;
3741     }
3742
3743     /**
3744      * Reads the default serializable fields from the stream and performs
3745      * validations and adjustments for older serialized versions. The
3746      * validations and adjustments are:
3747      * <ol>
3748      * <li>
3749      * Verify that the superclass's digit count fields correctly reflect
3750      * the limits imposed on formatting numbers other than
3751      * <code>BigInteger</code> and <code>BigDecimal</code> objects. These
3752      * limits are stored in the superclass for serialization compatibility
3753      * with older versions, while the limits for <code>BigInteger</code> and
3754      * <code>BigDecimal</code> objects are kept in this class.
3755      * If, in the superclass, the minimum or maximum integer digit count is
3756      * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or
3757      * maximum fraction digit count is larger than
3758      * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid
3759      * and this method throws an <code>InvalidObjectException</code>.
3760      * <li>
3761      * If <code>serialVersionOnStream</code> is less than 4, initialize
3762      * <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN
3763      * RoundingMode.HALF_EVEN}.  This field is new with version 4.
3764      * <li>
3765      * If <code>serialVersionOnStream</code> is less than 3, then call
3766      * the setters for the minimum and maximum integer and fraction digits with
3767      * the values of the corresponding superclass getters to initialize the
3768      * fields in this class. The fields in this class are new with version 3.
3769      * <li>
3770      * If <code>serialVersionOnStream</code> is less than 1, indicating that
3771      * the stream was written by JDK 1.1, initialize
3772      * <code>useExponentialNotation</code>
3773      * to false, since it was not present in JDK 1.1.
3774      * <li>
3775      * Set <code>serialVersionOnStream</code> to the maximum allowed value so
3776      * that default serialization will work properly if this object is streamed
3777      * out again.
3778      * </ol>
3779      *
3780      * <p>Stream versions older than 2 will not have the affix pattern variables
3781      * <code>posPrefixPattern</code> etc.  As a result, they will be initialized
3782      * to <code>null</code>, which means the affix strings will be taken as
3783      * literal values.  This is exactly what we want, since that corresponds to
3784      * the pre-version-2 behavior.
3785      */

3786     private void readObject(ObjectInputStream stream)
3787          throws IOException, ClassNotFoundException
3788     {
3789         stream.defaultReadObject();
3790         digitList = new DigitList();
3791
3792         // We force complete fast-path reinitialization when the instance is
3793         // deserialized. See clone() comment on fastPathCheckNeeded.
3794         fastPathCheckNeeded = true;
3795         isFastPath = false;
3796         fastPathData = null;
3797
3798         if (serialVersionOnStream < 4) {
3799             setRoundingMode(RoundingMode.HALF_EVEN);
3800         } else {
3801             setRoundingMode(getRoundingMode());
3802         }
3803
3804         // We only need to check the maximum counts because NumberFormat
3805         // .readObject has already ensured that the maximum is greater than the
3806         // minimum count.
3807         if (super.getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS ||
3808             super.getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {
3809             throw new InvalidObjectException("Digit count out of range");
3810         }
3811         if (serialVersionOnStream < 3) {
3812             setMaximumIntegerDigits(super.getMaximumIntegerDigits());
3813             setMinimumIntegerDigits(super.getMinimumIntegerDigits());
3814             setMaximumFractionDigits(super.getMaximumFractionDigits());
3815             setMinimumFractionDigits(super.getMinimumFractionDigits());
3816         }
3817         if (serialVersionOnStream < 1) {
3818             // Didn't have exponential fields
3819             useExponentialNotation = false;
3820         }
3821         serialVersionOnStream = currentSerialVersion;
3822     }
3823
3824     //----------------------------------------------------------------------
3825     // INSTANCE VARIABLES
3826     //----------------------------------------------------------------------
3827
3828     private transient DigitList digitList = new DigitList();
3829
3830     /**
3831      * The symbol used as a prefix when formatting positive numbers, e.g. "+".
3832      *
3833      * @serial
3834      * @see #getPositivePrefix
3835      */

3836     private String  positivePrefix = "";
3837
3838     /**
3839      * The symbol used as a suffix when formatting positive numbers.
3840      * This is often an empty string.
3841      *
3842      * @serial
3843      * @see #getPositiveSuffix
3844      */

3845     private String  positiveSuffix = "";
3846
3847     /**
3848      * The symbol used as a prefix when formatting negative numbers, e.g. "-".
3849      *
3850      * @serial
3851      * @see #getNegativePrefix
3852      */

3853     private String  negativePrefix = "-";
3854
3855     /**
3856      * The symbol used as a suffix when formatting negative numbers.
3857      * This is often an empty string.
3858      *
3859      * @serial
3860      * @see #getNegativeSuffix
3861      */

3862     private String  negativeSuffix = "";
3863
3864     /**
3865      * The prefix pattern for non-negative numbers.  This variable corresponds
3866      * to <code>positivePrefix</code>.
3867      *
3868      * <p>This pattern is expanded by the method <code>expandAffix()</code> to
3869      * <code>positivePrefix</code> to update the latter to reflect changes in
3870      * <code>symbols</code>.  If this variable is <code>null</code> then
3871      * <code>positivePrefix</code> is taken as a literal value that does not
3872      * change when <code>symbols</code> changes.  This variable is always
3873      * <code>null</code> for <code>DecimalFormat</code> objects older than
3874      * stream version 2 restored from stream.
3875      *
3876      * @serial
3877      * @since 1.3
3878      */

3879     private String posPrefixPattern;
3880
3881     /**
3882      * The suffix pattern for non-negative numbers.  This variable corresponds
3883      * to <code>positiveSuffix</code>.  This variable is analogous to
3884      * <code>posPrefixPattern</code>; see that variable for further
3885      * documentation.
3886      *
3887      * @serial
3888      * @since 1.3
3889      */

3890     private String posSuffixPattern;
3891
3892     /**
3893      * The prefix pattern for negative numbers.  This variable corresponds
3894      * to <code>negativePrefix</code>.  This variable is analogous to
3895      * <code>posPrefixPattern</code>; see that variable for further
3896      * documentation.
3897      *
3898      * @serial
3899      * @since 1.3
3900      */

3901     private String negPrefixPattern;
3902
3903     /**
3904      * The suffix pattern for negative numbers.  This variable corresponds
3905      * to <code>negativeSuffix</code>.  This variable is analogous to
3906      * <code>posPrefixPattern</code>; see that variable for further
3907      * documentation.
3908      *
3909      * @serial
3910      * @since 1.3
3911      */

3912     private String negSuffixPattern;
3913
3914     /**
3915      * The multiplier for use in percent, per mille, etc.
3916      *
3917      * @serial
3918      * @see #getMultiplier
3919      */

3920     private int     multiplier = 1;
3921
3922     /**
3923      * The number of digits between grouping separators in the integer
3924      * portion of a number.  Must be greater than 0 if
3925      * <code>NumberFormat.groupingUsed</code> is true.
3926      *
3927      * @serial
3928      * @see #getGroupingSize
3929      * @see java.text.NumberFormat#isGroupingUsed
3930      */

3931     private byte    groupingSize = 3;  // invariant, > 0 if useThousands
3932
3933     /**
3934      * If true, forces the decimal separator to always appear in a formatted
3935      * number, even if the fractional part of the number is zero.
3936      *
3937      * @serial
3938      * @see #isDecimalSeparatorAlwaysShown
3939      */

3940     private boolean decimalSeparatorAlwaysShown = false;
3941
3942     /**
3943      * If true, parse returns BigDecimal wherever possible.
3944      *
3945      * @serial
3946      * @see #isParseBigDecimal
3947      * @since 1.5
3948      */

3949     private boolean parseBigDecimal = false;
3950
3951
3952     /**
3953      * True if this object represents a currency format.  This determines
3954      * whether the monetary decimal separator is used instead of the normal one.
3955      */

3956     private transient boolean isCurrencyFormat = false;
3957
3958     /**
3959      * The <code>DecimalFormatSymbols</code> object used by this format.
3960      * It contains the symbols used to format numbers, e.g. the grouping separator,
3961      * decimal separator, and so on.
3962      *
3963      * @serial
3964      * @see #setDecimalFormatSymbols
3965      * @see java.text.DecimalFormatSymbols
3966      */

3967     private DecimalFormatSymbols symbols = null// LIU new DecimalFormatSymbols();
3968
3969     /**
3970      * True to force the use of exponential (i.e. scientific) notation when formatting
3971      * numbers.
3972      *
3973      * @serial
3974      * @since 1.2
3975      */

3976     private boolean useExponentialNotation;  // Newly persistent in the Java 2 platform v.1.2
3977
3978     /**
3979      * FieldPositions describing the positive prefix String. This is
3980      * lazily created. Use <code>getPositivePrefixFieldPositions</code>
3981      * when needed.
3982      */

3983     private transient FieldPosition[] positivePrefixFieldPositions;
3984
3985     /**
3986      * FieldPositions describing the positive suffix String. This is
3987      * lazily created. Use <code>getPositiveSuffixFieldPositions</code>
3988      * when needed.
3989      */

3990     private transient FieldPosition[] positiveSuffixFieldPositions;
3991
3992     /**
3993      * FieldPositions describing the negative prefix String. This is
3994      * lazily created. Use <code>getNegativePrefixFieldPositions</code>
3995      * when needed.
3996      */

3997     private transient FieldPosition[] negativePrefixFieldPositions;
3998
3999     /**
4000      * FieldPositions describing the negative suffix String. This is
4001      * lazily created. Use <code>getNegativeSuffixFieldPositions</code>
4002      * when needed.
4003      */

4004     private transient FieldPosition[] negativeSuffixFieldPositions;
4005
4006     /**
4007      * The minimum number of digits used to display the exponent when a number is
4008      * formatted in exponential notation.  This field is ignored if
4009      * <code>useExponentialNotation</code> is not true.
4010      *
4011      * @serial
4012      * @since 1.2
4013      */

4014     private byte    minExponentDigits;       // Newly persistent in the Java 2 platform v.1.2
4015
4016     /**
4017      * The maximum number of digits allowed in the integer portion of a
4018      * <code>BigInteger</code> or <code>BigDecimal</code> number.
4019      * <code>maximumIntegerDigits</code> must be greater than or equal to
4020      * <code>minimumIntegerDigits</code>.
4021      *
4022      * @serial
4023      * @see #getMaximumIntegerDigits
4024      * @since 1.5
4025      */

4026     private int    maximumIntegerDigits = super.getMaximumIntegerDigits();
4027
4028     /**
4029      * The minimum number of digits allowed in the integer portion of a
4030      * <code>BigInteger</code> or <code>BigDecimal</code> number.
4031      * <code>minimumIntegerDigits</code> must be less than or equal to
4032      * <code>maximumIntegerDigits</code>.
4033      *
4034      * @serial
4035      * @see #getMinimumIntegerDigits
4036      * @since 1.5
4037      */

4038     private int    minimumIntegerDigits = super.getMinimumIntegerDigits();
4039
4040     /**
4041      * The maximum number of digits allowed in the fractional portion of a
4042      * <code>BigInteger</code> or <code>BigDecimal</code> number.
4043      * <code>maximumFractionDigits</code> must be greater than or equal to
4044      * <code>minimumFractionDigits</code>.
4045      *
4046      * @serial
4047      * @see #getMaximumFractionDigits
4048      * @since 1.5
4049      */

4050     private int    maximumFractionDigits = super.getMaximumFractionDigits();
4051
4052     /**
4053      * The minimum number of digits allowed in the fractional portion of a
4054      * <code>BigInteger</code> or <code>BigDecimal</code> number.
4055      * <code>minimumFractionDigits</code> must be less than or equal to
4056      * <code>maximumFractionDigits</code>.
4057      *
4058      * @serial
4059      * @see #getMinimumFractionDigits
4060      * @since 1.5
4061      */

4062     private int    minimumFractionDigits = super.getMinimumFractionDigits();
4063
4064     /**
4065      * The {@link java.math.RoundingMode} used in this DecimalFormat.
4066      *
4067      * @serial
4068      * @since 1.6
4069      */

4070     private RoundingMode roundingMode = RoundingMode.HALF_EVEN;
4071
4072     // ------ DecimalFormat fields for fast-path for double algorithm  ------
4073
4074     /**
4075      * Helper inner utility class for storing the data used in the fast-path
4076      * algorithm. Almost all fields related to fast-path are encapsulated in
4077      * this class.
4078      *
4079      * Any {@code DecimalFormat} instance has a {@code fastPathData}
4080      * reference field that is null unless both the properties of the instance
4081      * are such that the instance is in the "fast-path" state, and a format call
4082      * has been done at least once while in this state.
4083      *
4084      * Almost all fields are related to the "fast-path" state only and don't
4085      * change until one of the instance properties is changed.
4086      *
4087      * {@code firstUsedIndex} and {@code lastFreeIndex} are the only
4088      * two fields that are used and modified while inside a call to
4089      * {@code fastDoubleFormat}.
4090      *
4091      */

4092     private static class FastPathData {
4093         // --- Temporary fields used in fast-path, shared by several methods.
4094
4095         /** The first unused index at the end of the formatted result. */
4096         int lastFreeIndex;
4097
4098         /** The first used index at the beginning of the formatted result */
4099         int firstUsedIndex;
4100
4101         // --- State fields related to fast-path status. Changes due to a
4102         //     property change only. Set by checkAndSetFastPathStatus() only.
4103
4104         /** Difference between locale zero and default zero representation. */
4105         int  zeroDelta;
4106
4107         /** Locale char for grouping separator. */
4108         char groupingChar;
4109
4110         /**  Fixed index position of last integral digit of formatted result */
4111         int integralLastIndex;
4112
4113         /**  Fixed index position of first fractional digit of formatted result */
4114         int fractionalFirstIndex;
4115
4116         /** Fractional constants depending on decimal|currency state */
4117         double fractionalScaleFactor;
4118         int fractionalMaxIntBound;
4119
4120
4121         /** The char array buffer that will contain the formatted result */
4122         char[] fastPathContainer;
4123
4124         /** Suffixes recorded as char array for efficiency. */
4125         char[] charsPositivePrefix;
4126         char[] charsNegativePrefix;
4127         char[] charsPositiveSuffix;
4128         char[] charsNegativeSuffix;
4129         boolean positiveAffixesRequired = true;
4130         boolean negativeAffixesRequired = true;
4131     }
4132
4133     /** The format fast-path status of the instance. Logical state. */
4134     private transient boolean isFastPath = false;
4135
4136     /** Flag stating need of check and reinit fast-path status on next format call. */
4137     private transient boolean fastPathCheckNeeded = true;
4138
4139     /** DecimalFormat reference to its FastPathData */
4140     private transient FastPathData fastPathData;
4141
4142
4143     //----------------------------------------------------------------------
4144
4145     static final int currentSerialVersion = 4;
4146
4147     /**
4148      * The internal serial version which says which version was written.
4149      * Possible values are:
4150      * <ul>
4151      * <li><b>0</b> (default): versions before the Java 2 platform v1.2
4152      * <li><b>1</b>: version for 1.2, which includes the two new fields
4153      *      <code>useExponentialNotation</code> and
4154      *      <code>minExponentDigits</code>.
4155      * <li><b>2</b>: version for 1.3 and later, which adds four new fields:
4156      *      <code>posPrefixPattern</code>, <code>posSuffixPattern</code>,
4157      *      <code>negPrefixPattern</code>, and <code>negSuffixPattern</code>.
4158      * <li><b>3</b>: version for 1.5 and later, which adds five new fields:
4159      *      <code>maximumIntegerDigits</code>,
4160      *      <code>minimumIntegerDigits</code>,
4161      *      <code>maximumFractionDigits</code>,
4162      *      <code>minimumFractionDigits</code>, and
4163      *      <code>parseBigDecimal</code>.
4164      * <li><b>4</b>: version for 1.6 and later, which adds one new field:
4165      *      <code>roundingMode</code>.
4166      * </ul>
4167      * @since 1.2
4168      * @serial
4169      */

4170     private int serialVersionOnStream = currentSerialVersion;
4171
4172     //----------------------------------------------------------------------
4173     // CONSTANTS
4174     //----------------------------------------------------------------------
4175
4176     // ------ Fast-Path for double Constants ------
4177
4178     /** Maximum valid integer value for applying fast-path algorithm */
4179     private static final double MAX_INT_AS_DOUBLE = (double) Integer.MAX_VALUE;
4180
4181     /**
4182      * The digit arrays used in the fast-path methods for collecting digits.
4183      * Using 3 constants arrays of chars ensures a very fast collection of digits
4184      */

4185     private static class DigitArrays {
4186         static final char[] DigitOnes1000 = new char[1000];
4187         static final char[] DigitTens1000 = new char[1000];
4188         static final char[] DigitHundreds1000 = new char[1000];
4189
4190         // initialize on demand holder class idiom for arrays of digits
4191         static {
4192             int tenIndex = 0;
4193             int hundredIndex = 0;
4194             char digitOne = '0';
4195             char digitTen = '0';
4196             char digitHundred = '0';
4197             for (int i = 0;  i < 1000; i++ ) {
4198
4199                 DigitOnes1000[i] = digitOne;
4200                 if (digitOne == '9')
4201                     digitOne = '0';
4202                 else
4203                     digitOne++;
4204
4205                 DigitTens1000[i] = digitTen;
4206                 if (i == (tenIndex + 9)) {
4207                     tenIndex += 10;
4208                     if (digitTen == '9')
4209                         digitTen = '0';
4210                     else
4211                         digitTen++;
4212                 }
4213
4214                 DigitHundreds1000[i] = digitHundred;
4215                 if (i == (hundredIndex + 99)) {
4216                     digitHundred++;
4217                     hundredIndex += 100;
4218                 }
4219             }
4220         }
4221     }
4222     // ------ Fast-Path for double Constants end ------
4223
4224     // Constants for characters used in programmatic (unlocalized) patterns.
4225     private static final char       PATTERN_ZERO_DIGIT         = '0';
4226     private static final char       PATTERN_GROUPING_SEPARATOR = ',';
4227     private static final char       PATTERN_DECIMAL_SEPARATOR  = '.';
4228     private static final char       PATTERN_PER_MILLE          = '\u2030';
4229     private static final char       PATTERN_PERCENT            = '%';
4230     private static final char       PATTERN_DIGIT              = '#';
4231     private static final char       PATTERN_SEPARATOR          = ';';
4232     private static final String     PATTERN_EXPONENT           = "E";
4233     private static final char       PATTERN_MINUS              = '-';
4234
4235     /**
4236      * The CURRENCY_SIGN is the standard Unicode symbol for currency.  It
4237      * is used in patterns and substituted with either the currency symbol,
4238      * or if it is doubled, with the international currency symbol.  If the
4239      * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
4240      * replaced with the monetary decimal separator.
4241      *
4242      * The CURRENCY_SIGN is not localized.
4243      */

4244     private static final char       CURRENCY_SIGN = '\u00A4';
4245
4246     private static final char       QUOTE = '\'';
4247
4248     private static FieldPosition[] EmptyFieldPositionArray = new FieldPosition[0];
4249
4250     // Upper limit on integer and fraction digits for a Java double
4251     static final int DOUBLE_INTEGER_DIGITS  = 309;
4252     static final int DOUBLE_FRACTION_DIGITS = 340;
4253
4254     // Upper limit on integer and fraction digits for BigDecimal and BigInteger
4255     static final int MAXIMUM_INTEGER_DIGITS  = Integer.MAX_VALUE;
4256     static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE;
4257
4258     // Proclaim JDK 1.1 serial compatibility.
4259     static final long serialVersionUID = 864413376551465018L;
4260 }
4261