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