1 /*
   2  * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
  28  * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
  29  *
  30  *   The original version of this source code and documentation is copyrighted
  31  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
  32  * materials are provided under terms of a License Agreement between Taligent
  33  * and Sun. This technology is protected by multiple US and International
  34  * patents. This notice and attribution to Taligent may not be removed.
  35  *   Taligent is a registered trademark of Taligent, Inc.
  36  *
  37  */
  38 
  39 package java.text;
  40 
  41 import java.io.InvalidObjectException;
  42 import java.io.IOException;
  43 import java.io.ObjectInputStream;
  44 import java.math.BigDecimal;
  45 import java.math.BigInteger;
  46 import java.math.RoundingMode;
  47 import java.util.ArrayList;
  48 import java.util.Currency;
  49 import java.util.Locale;
  50 import java.util.ResourceBundle;
  51 import java.util.concurrent.ConcurrentHashMap;
  52 import java.util.concurrent.ConcurrentMap;
  53 import java.util.concurrent.atomic.AtomicInteger;
  54 import java.util.concurrent.atomic.AtomicLong;
  55 import sun.util.resources.LocaleData;
  56 
  57 /**
  58  * <code>DecimalFormat</code> is a concrete subclass of
  59  * <code>NumberFormat</code> that formats decimal numbers. It has a variety of
  60  * features designed to make it possible to parse and format numbers in any
  61  * locale, including support for Western, Arabic, and Indic digits.  It also
  62  * supports different kinds of numbers, including integers (123), fixed-point
  63  * numbers (123.4), scientific notation (1.23E4), percentages (12%), and
  64  * currency amounts ($123).  All of these can be localized.
  65  *
  66  * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the
  67  * default locale, call one of <code>NumberFormat</code>'s factory methods, such
  68  * as <code>getInstance()</code>.  In general, do not call the
  69  * <code>DecimalFormat</code> constructors directly, since the
  70  * <code>NumberFormat</code> factory methods may return subclasses other than
  71  * <code>DecimalFormat</code>. If you need to customize the format object, do
  72  * something like this:
  73  *
  74  * <blockquote><pre>
  75  * NumberFormat f = NumberFormat.getInstance(loc);
  76  * if (f instanceof DecimalFormat) {
  77  *     ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
  78  * }
  79  * </pre></blockquote>
  80  *
  81  * <p>A <code>DecimalFormat</code> comprises a <em>pattern</em> and a set of
  82  * <em>symbols</em>.  The pattern may be set directly using
  83  * <code>applyPattern()</code>, or indirectly using the API methods.  The
  84  * symbols are stored in a <code>DecimalFormatSymbols</code> object.  When using
  85  * the <code>NumberFormat</code> factory methods, the pattern and symbols are
  86  * read from localized <code>ResourceBundle</code>s.
  87  *
  88  * <h4>Patterns</h4>
  89  *
  90  * <code>DecimalFormat</code> patterns have the following syntax:
  91  * <blockquote><pre>
  92  * <i>Pattern:</i>
  93  *         <i>PositivePattern</i>
  94  *         <i>PositivePattern</i> ; <i>NegativePattern</i>
  95  * <i>PositivePattern:</i>
  96  *         <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
  97  * <i>NegativePattern:</i>
  98  *         <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
  99  * <i>Prefix:</i>
 100  *         any Unicode characters except &#92;uFFFE, &#92;uFFFF, and special characters
 101  * <i>Suffix:</i>
 102  *         any Unicode characters except &#92;uFFFE, &#92;uFFFF, and special characters
 103  * <i>Number:</i>
 104  *         <i>Integer</i> <i>Exponent<sub>opt</sub></i>
 105  *         <i>Integer</i> . <i>Fraction</i> <i>Exponent<sub>opt</sub></i>
 106  * <i>Integer:</i>
 107  *         <i>MinimumInteger</i>
 108  *         #
 109  *         # <i>Integer</i>
 110  *         # , <i>Integer</i>
 111  * <i>MinimumInteger:</i>
 112  *         0
 113  *         0 <i>MinimumInteger</i>
 114  *         0 , <i>MinimumInteger</i>
 115  * <i>Fraction:</i>
 116  *         <i>MinimumFraction<sub>opt</sub></i> <i>OptionalFraction<sub>opt</sub></i>
 117  * <i>MinimumFraction:</i>
 118  *         0 <i>MinimumFraction<sub>opt</sub></i>
 119  * <i>OptionalFraction:</i>
 120  *         # <i>OptionalFraction<sub>opt</sub></i>
 121  * <i>Exponent:</i>
 122  *         E <i>MinimumExponent</i>
 123  * <i>MinimumExponent:</i>
 124  *         0 <i>MinimumExponent<sub>opt</sub></i>
 125  * </pre></blockquote>
 126  *
 127  * <p>A <code>DecimalFormat</code> pattern contains a positive and negative
 128  * subpattern, for example, <code>"#,##0.00;(#,##0.00)"</code>.  Each
 129  * subpattern has a prefix, numeric part, and suffix. The negative subpattern
 130  * is optional; if absent, then the positive subpattern prefixed with the
 131  * localized minus sign (<code>'-'</code> in most locales) is used as the
 132  * negative subpattern. That is, <code>"0.00"</code> alone is equivalent to
 133  * <code>"0.00;-0.00"</code>.  If there is an explicit negative subpattern, it
 134  * serves only to specify the negative prefix and suffix; the number of digits,
 135  * minimal digits, and other characteristics are all the same as the positive
 136  * pattern. That means that <code>"#,##0.0#;(#)"</code> produces precisely
 137  * the same behavior as <code>"#,##0.0#;(#,##0.0#)"</code>.
 138  *
 139  * <p>The prefixes, suffixes, and various symbols used for infinity, digits,
 140  * thousands separators, decimal separators, etc. may be set to arbitrary
 141  * values, and they will appear properly during formatting.  However, care must
 142  * be taken that the symbols and strings do not conflict, or parsing will be
 143  * unreliable.  For example, either the positive and negative prefixes or the
 144  * suffixes must be distinct for <code>DecimalFormat.parse()</code> to be able
 145  * to distinguish positive from negative values.  (If they are identical, then
 146  * <code>DecimalFormat</code> will behave as if no negative subpattern was
 147  * specified.)  Another example is that the decimal separator and thousands
 148  * separator should be distinct characters, or parsing will be impossible.
 149  *
 150  * <p>The grouping separator is commonly used for thousands, but in some
 151  * countries it separates ten-thousands. The grouping size is a constant number
 152  * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for
 153  * 1,0000,0000.  If you supply a pattern with multiple grouping characters, the
 154  * interval between the last one and the end of the integer is the one that is
 155  * used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> ==
 156  * <code>"##,####,####"</code>.
 157  *
 158  * <h4>Special Pattern Characters</h4>
 159  *
 160  * <p>Many characters in a pattern are taken literally; they are matched during
 161  * parsing and output unchanged during formatting.  Special characters, on the
 162  * other hand, stand for other characters, strings, or classes of characters.
 163  * They must be quoted, unless noted otherwise, if they are to appear in the
 164  * prefix or suffix as literals.
 165  *
 166  * <p>The characters listed here are used in non-localized patterns.  Localized
 167  * patterns use the corresponding characters taken from this formatter's
 168  * <code>DecimalFormatSymbols</code> object instead, and these characters lose
 169  * their special status.  Two exceptions are the currency sign and quote, which
 170  * are not localized.
 171  *
 172  * <blockquote>
 173  * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol,
 174  *  location, localized, and meaning.">
 175  *     <tr bgcolor="#ccccff">
 176  *          <th align=left>Symbol
 177  *          <th align=left>Location
 178  *          <th align=left>Localized?
 179  *          <th align=left>Meaning
 180  *     <tr valign=top>
 181  *          <td><code>0</code>
 182  *          <td>Number
 183  *          <td>Yes
 184  *          <td>Digit
 185  *     <tr valign=top bgcolor="#eeeeff">
 186  *          <td><code>#</code>
 187  *          <td>Number
 188  *          <td>Yes
 189  *          <td>Digit, zero shows as absent
 190  *     <tr valign=top>
 191  *          <td><code>.</code>
 192  *          <td>Number
 193  *          <td>Yes
 194  *          <td>Decimal separator or monetary decimal separator
 195  *     <tr valign=top bgcolor="#eeeeff">
 196  *          <td><code>-</code>
 197  *          <td>Number
 198  *          <td>Yes
 199  *          <td>Minus sign
 200  *     <tr valign=top>
 201  *          <td><code>,</code>
 202  *          <td>Number
 203  *          <td>Yes
 204  *          <td>Grouping separator
 205  *     <tr valign=top bgcolor="#eeeeff">
 206  *          <td><code>E</code>
 207  *          <td>Number
 208  *          <td>Yes
 209  *          <td>Separates mantissa and exponent in scientific notation.
 210  *              <em>Need not be quoted in prefix or suffix.</em>
 211  *     <tr valign=top>
 212  *          <td><code>;</code>
 213  *          <td>Subpattern boundary
 214  *          <td>Yes
 215  *          <td>Separates positive and negative subpatterns
 216  *     <tr valign=top bgcolor="#eeeeff">
 217  *          <td><code>%</code>
 218  *          <td>Prefix or suffix
 219  *          <td>Yes
 220  *          <td>Multiply by 100 and show as percentage
 221  *     <tr valign=top>
 222  *          <td><code>&#92;u2030</code>
 223  *          <td>Prefix or suffix
 224  *          <td>Yes
 225  *          <td>Multiply by 1000 and show as per mille value
 226  *     <tr valign=top bgcolor="#eeeeff">
 227  *          <td><code>&#164;</code> (<code>&#92;u00A4</code>)
 228  *          <td>Prefix or suffix
 229  *          <td>No
 230  *          <td>Currency sign, replaced by currency symbol.  If
 231  *              doubled, replaced by international currency symbol.
 232  *              If present in a pattern, the monetary decimal separator
 233  *              is used instead of the decimal separator.
 234  *     <tr valign=top>
 235  *          <td><code>'</code>
 236  *          <td>Prefix or suffix
 237  *          <td>No
 238  *          <td>Used to quote special characters in a prefix or suffix,
 239  *              for example, <code>"'#'#"</code> formats 123 to
 240  *              <code>"#123"</code>.  To create a single quote
 241  *              itself, use two in a row: <code>"# o''clock"</code>.
 242  * </table>
 243  * </blockquote>
 244  *
 245  * <h4>Scientific Notation</h4>
 246  *
 247  * <p>Numbers in scientific notation are expressed as the product of a mantissa
 248  * and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3.  The
 249  * mantissa is often in the range 1.0 <= x < 10.0, but it need not be.
 250  * <code>DecimalFormat</code> can be instructed to format and parse scientific
 251  * notation <em>only via a pattern</em>; there is currently no factory method
 252  * that creates a scientific notation format.  In a pattern, the exponent
 253  * character immediately followed by one or more digit characters indicates
 254  * scientific notation.  Example: <code>"0.###E0"</code> formats the number
 255  * 1234 as <code>"1.234E3"</code>.
 256  *
 257  * <ul>
 258  * <li>The number of digit characters after the exponent character gives the
 259  * minimum exponent digit count.  There is no maximum.  Negative exponents are
 260  * formatted using the localized minus sign, <em>not</em> the prefix and suffix
 261  * from the pattern.  This allows patterns such as <code>"0.###E0 m/s"</code>.
 262  *
 263  * <li>The minimum and maximum number of integer digits are interpreted
 264  * together:
 265  *
 266  * <ul>
 267  * <li>If the maximum number of integer digits is greater than their minimum number
 268  * and greater than 1, it forces the exponent to be a multiple of the maximum
 269  * number of integer digits, and the minimum number of integer digits to be
 270  * interpreted as 1.  The most common use of this is to generate
 271  * <em>engineering notation</em>, in which the exponent is a multiple of three,
 272  * e.g., <code>"##0.#####E0"</code>. Using this pattern, the number 12345
 273  * formats to <code>"12.345E3"</code>, and 123456 formats to
 274  * <code>"123.456E3"</code>.
 275  *
 276  * <li>Otherwise, the minimum number of integer digits is achieved by adjusting the
 277  * exponent.  Example: 0.00123 formatted with <code>"00.###E0"</code> yields
 278  * <code>"12.3E-4"</code>.
 279  * </ul>
 280  *
 281  * <li>The number of significant digits in the mantissa is the sum of the
 282  * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is
 283  * unaffected by the maximum integer digits.  For example, 12345 formatted with
 284  * <code>"##0.##E0"</code> is <code>"12.3E3"</code>. To show all digits, set
 285  * the significant digits count to zero.  The number of significant digits
 286  * does not affect parsing.
 287  *
 288  * <li>Exponential patterns may not contain grouping separators.
 289  * </ul>
 290  *
 291  * <h4>Rounding</h4>
 292  *
 293  * <code>DecimalFormat</code> provides rounding modes defined in
 294  * {@link java.math.RoundingMode} for formatting.  By default, it uses
 295  * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
 296  *
 297  * <h4>Digits</h4>
 298  *
 299  * For formatting, <code>DecimalFormat</code> uses the ten consecutive
 300  * characters starting with the localized zero digit defined in the
 301  * <code>DecimalFormatSymbols</code> object as digits. For parsing, these
 302  * digits as well as all Unicode decimal digits, as defined by
 303  * {@link Character#digit Character.digit}, are recognized.
 304  *
 305  * <h4>Special Values</h4>
 306  *
 307  * <p><code>NaN</code> is formatted as a string, which typically has a single character
 308  * <code>&#92;uFFFD</code>.  This string is determined by the
 309  * <code>DecimalFormatSymbols</code> object.  This is the only value for which
 310  * the prefixes and suffixes are not used.
 311  *
 312  * <p>Infinity is formatted as a string, which typically has a single character
 313  * <code>&#92;u221E</code>, with the positive or negative prefixes and suffixes
 314  * applied.  The infinity string is determined by the
 315  * <code>DecimalFormatSymbols</code> object.
 316  *
 317  * <p>Negative zero (<code>"-0"</code>) parses to
 318  * <ul>
 319  * <li><code>BigDecimal(0)</code> if <code>isParseBigDecimal()</code> is
 320  * true,
 321  * <li><code>Long(0)</code> if <code>isParseBigDecimal()</code> is false
 322  *     and <code>isParseIntegerOnly()</code> is true,
 323  * <li><code>Double(-0.0)</code> if both <code>isParseBigDecimal()</code>
 324  * and <code>isParseIntegerOnly()</code> are false.
 325  * </ul>
 326  *
 327  * <h4><a name="synchronization">Synchronization</a></h4>
 328  *
 329  * <p>
 330  * Decimal formats are generally not synchronized.
 331  * It is recommended to create separate format instances for each thread.
 332  * If multiple threads access a format concurrently, it must be synchronized
 333  * externally.
 334  *
 335  * <h4>Example</h4>
 336  *
 337  * <blockquote><pre>
 338  * <strong>// Print out a number using the localized number, integer, currency,
 339  * // and percent format for each locale</strong>
 340  * Locale[] locales = NumberFormat.getAvailableLocales();
 341  * double myNumber = -1234.56;
 342  * NumberFormat form;
 343  * for (int j=0; j<4; ++j) {
 344  *     System.out.println("FORMAT");
 345  *     for (int i = 0; i < locales.length; ++i) {
 346  *         if (locales[i].getCountry().length() == 0) {
 347  *            continue; // Skip language-only locales
 348  *         }
 349  *         System.out.print(locales[i].getDisplayName());
 350  *         switch (j) {
 351  *         case 0:
 352  *             form = NumberFormat.getInstance(locales[i]); break;
 353  *         case 1:
 354  *             form = NumberFormat.getIntegerInstance(locales[i]); break;
 355  *         case 2:
 356  *             form = NumberFormat.getCurrencyInstance(locales[i]); break;
 357  *         default:
 358  *             form = NumberFormat.getPercentInstance(locales[i]); break;
 359  *         }
 360  *         if (form instanceof DecimalFormat) {
 361  *             System.out.print(": " + ((DecimalFormat) form).toPattern());
 362  *         }
 363  *         System.out.print(" -> " + form.format(myNumber));
 364  *         try {
 365  *             System.out.println(" -> " + form.parse(form.format(myNumber)));
 366  *         } catch (ParseException e) {}
 367  *     }
 368  * }
 369  * </pre></blockquote>
 370  *
 371  * @see          <a href="http://java.sun.com/docs/books/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a>
 372  * @see          NumberFormat
 373  * @see          DecimalFormatSymbols
 374  * @see          ParsePosition
 375  * @author       Mark Davis
 376  * @author       Alan Liu
 377  */
 378 public class DecimalFormat extends NumberFormat {
 379 
 380     /**
 381      * Creates a DecimalFormat using the default pattern and symbols
 382      * for the default locale. This is a convenient way to obtain a
 383      * DecimalFormat when internationalization is not the main concern.
 384      * <p>
 385      * To obtain standard formats for a given locale, use the factory methods
 386      * on NumberFormat such as getNumberInstance. These factories will
 387      * return the most appropriate sub-class of NumberFormat for a given
 388      * locale.
 389      *
 390      * @see java.text.NumberFormat#getInstance
 391      * @see java.text.NumberFormat#getNumberInstance
 392      * @see java.text.NumberFormat#getCurrencyInstance
 393      * @see java.text.NumberFormat#getPercentInstance
 394      */
 395     public DecimalFormat() {
 396         Locale def = Locale.getDefault(Locale.Category.FORMAT);
 397         // try to get the pattern from the cache
 398         String pattern = cachedLocaleData.get(def);
 399         if (pattern == null) {  /* cache miss */
 400             // Get the pattern for the default locale.
 401             ResourceBundle rb = LocaleData.getNumberFormatData(def);
 402             String[] all = rb.getStringArray("NumberPatterns");
 403             pattern = all[0];
 404             /* update cache */
 405             cachedLocaleData.putIfAbsent(def, pattern);
 406         }
 407 
 408         // Always applyPattern after the symbols are set
 409         this.symbols = new DecimalFormatSymbols(def);
 410         applyPattern(pattern, false);
 411     }
 412 
 413 
 414     /**
 415      * Creates a DecimalFormat using the given pattern and the symbols
 416      * for the default locale. This is a convenient way to obtain a
 417      * DecimalFormat when internationalization is not the main concern.
 418      * <p>
 419      * To obtain standard formats for a given locale, use the factory methods
 420      * on NumberFormat such as getNumberInstance. These factories will
 421      * return the most appropriate sub-class of NumberFormat for a given
 422      * locale.
 423      *
 424      * @param pattern A non-localized pattern string.
 425      * @exception NullPointerException if <code>pattern</code> is null
 426      * @exception IllegalArgumentException if the given pattern is invalid.
 427      * @see java.text.NumberFormat#getInstance
 428      * @see java.text.NumberFormat#getNumberInstance
 429      * @see java.text.NumberFormat#getCurrencyInstance
 430      * @see java.text.NumberFormat#getPercentInstance
 431      */
 432     public DecimalFormat(String pattern) {
 433         // Always applyPattern after the symbols are set
 434         this.symbols = new DecimalFormatSymbols(Locale.getDefault(Locale.Category.FORMAT));
 435         applyPattern(pattern, false);
 436     }
 437 
 438 
 439     /**
 440      * Creates a DecimalFormat using the given pattern and symbols.
 441      * Use this constructor when you need to completely customize the
 442      * behavior of the format.
 443      * <p>
 444      * To obtain standard formats for a given
 445      * locale, use the factory methods on NumberFormat such as
 446      * getInstance or getCurrencyInstance. If you need only minor adjustments
 447      * to a standard format, you can modify the format returned by
 448      * a NumberFormat factory method.
 449      *
 450      * @param pattern a non-localized pattern string
 451      * @param symbols the set of symbols to be used
 452      * @exception NullPointerException if any of the given arguments is null
 453      * @exception IllegalArgumentException if the given pattern is invalid
 454      * @see java.text.NumberFormat#getInstance
 455      * @see java.text.NumberFormat#getNumberInstance
 456      * @see java.text.NumberFormat#getCurrencyInstance
 457      * @see java.text.NumberFormat#getPercentInstance
 458      * @see java.text.DecimalFormatSymbols
 459      */
 460     public DecimalFormat (String pattern, DecimalFormatSymbols symbols) {
 461         // Always applyPattern after the symbols are set
 462         this.symbols = (DecimalFormatSymbols)symbols.clone();
 463         applyPattern(pattern, false);
 464     }
 465 
 466 
 467     // Overrides
 468     /**
 469      * Formats a number and appends the resulting text to the given string
 470      * buffer.
 471      * The number can be of any subclass of {@link java.lang.Number}.
 472      * <p>
 473      * This implementation uses the maximum precision permitted.
 474      * @param number     the number to format
 475      * @param toAppendTo the <code>StringBuffer</code> to which the formatted
 476      *                   text is to be appended
 477      * @param pos        On input: an alignment field, if desired.
 478      *                   On output: the offsets of the alignment field.
 479      * @return           the value passed in as <code>toAppendTo</code>
 480      * @exception        IllegalArgumentException if <code>number</code> is
 481      *                   null or not an instance of <code>Number</code>.
 482      * @exception        NullPointerException if <code>toAppendTo</code> or
 483      *                   <code>pos</code> is null
 484      * @exception        ArithmeticException if rounding is needed with rounding
 485      *                   mode being set to RoundingMode.UNNECESSARY
 486      * @see              java.text.FieldPosition
 487      */
 488     public final StringBuffer format(Object number,
 489                                      StringBuffer toAppendTo,
 490                                      FieldPosition pos) {
 491         if (number instanceof Long || number instanceof Integer ||
 492                    number instanceof Short || number instanceof Byte ||
 493                    number instanceof AtomicInteger ||
 494                    number instanceof AtomicLong ||
 495                    (number instanceof BigInteger &&
 496                     ((BigInteger)number).bitLength () < 64)) {
 497             return format(((Number)number).longValue(), toAppendTo, pos);
 498         } else if (number instanceof BigDecimal) {
 499             return format((BigDecimal)number, toAppendTo, pos);
 500         } else if (number instanceof BigInteger) {
 501             return format((BigInteger)number, toAppendTo, pos);
 502         } else if (number instanceof Number) {
 503             return format(((Number)number).doubleValue(), toAppendTo, pos);
 504         } else {
 505             throw new IllegalArgumentException("Cannot format given Object as a Number");
 506         }
 507     }
 508 
 509     /**
 510      * Formats a double to produce a string.
 511      * @param number    The double to format
 512      * @param result    where the text is to be appended
 513      * @param fieldPosition    On input: an alignment field, if desired.
 514      * On output: the offsets of the alignment field.
 515      * @exception ArithmeticException if rounding is needed with rounding
 516      *            mode being set to RoundingMode.UNNECESSARY
 517      * @return The formatted number string
 518      * @see java.text.FieldPosition
 519      */
 520     public StringBuffer format(double number, StringBuffer result,
 521                                FieldPosition fieldPosition) {
 522         fieldPosition.setBeginIndex(0);
 523         fieldPosition.setEndIndex(0);
 524 
 525         return format(number, result, fieldPosition.getFieldDelegate());
 526     }
 527 
 528     /**
 529      * Formats a double to produce a string.
 530      * @param number    The double to format
 531      * @param result    where the text is to be appended
 532      * @param delegate notified of locations of sub fields
 533      * @exception       ArithmeticException if rounding is needed with rounding
 534      *                  mode being set to RoundingMode.UNNECESSARY
 535      * @return The formatted number string
 536      */
 537     private StringBuffer format(double number, StringBuffer result,
 538                                 FieldDelegate delegate) {
 539         if (Double.isNaN(number) ||
 540            (Double.isInfinite(number) && multiplier == 0)) {
 541             int iFieldStart = result.length();
 542             result.append(symbols.getNaN());
 543             delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
 544                                iFieldStart, result.length(), result);
 545             return result;
 546         }
 547 
 548         /* Detecting whether a double is negative is easy with the exception of
 549          * the value -0.0.  This is a double which has a zero mantissa (and
 550          * exponent), but a negative sign bit.  It is semantically distinct from
 551          * a zero with a positive sign bit, and this distinction is important
 552          * to certain kinds of computations.  However, it's a little tricky to
 553          * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0).  How then, you may
 554          * ask, does it behave distinctly from +0.0?  Well, 1/(-0.0) ==
 555          * -Infinity.  Proper detection of -0.0 is needed to deal with the
 556          * issues raised by bugs 4106658, 4106667, and 4147706.  Liu 7/6/98.
 557          */
 558         boolean isNegative = ((number < 0.0) || (number == 0.0 && 1/number < 0.0)) ^ (multiplier < 0);
 559 
 560         if (multiplier != 1) {
 561             number *= multiplier;
 562         }
 563 
 564         if (Double.isInfinite(number)) {
 565             if (isNegative) {
 566                 append(result, negativePrefix, delegate,
 567                        getNegativePrefixFieldPositions(), Field.SIGN);
 568             } else {
 569                 append(result, positivePrefix, delegate,
 570                        getPositivePrefixFieldPositions(), Field.SIGN);
 571             }
 572 
 573             int iFieldStart = result.length();
 574             result.append(symbols.getInfinity());
 575             delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
 576                                iFieldStart, result.length(), result);
 577 
 578             if (isNegative) {
 579                 append(result, negativeSuffix, delegate,
 580                        getNegativeSuffixFieldPositions(), Field.SIGN);
 581             } else {
 582                 append(result, positiveSuffix, delegate,
 583                        getPositiveSuffixFieldPositions(), Field.SIGN);
 584             }
 585 
 586             return result;
 587         }
 588 
 589         if (isNegative) {
 590             number = -number;
 591         }
 592 
 593         // at this point we are guaranteed a nonnegative finite number.
 594         assert(number >= 0 && !Double.isInfinite(number));
 595 
 596         synchronized(digitList) {
 597             int maxIntDigits = super.getMaximumIntegerDigits();
 598             int minIntDigits = super.getMinimumIntegerDigits();
 599             int maxFraDigits = super.getMaximumFractionDigits();
 600             int minFraDigits = super.getMinimumFractionDigits();
 601 
 602             digitList.set(isNegative, number, useExponentialNotation ?
 603                           maxIntDigits + maxFraDigits : maxFraDigits,
 604                           !useExponentialNotation);
 605             return subformat(result, delegate, isNegative, false,
 606                        maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
 607         }
 608     }
 609 
 610     /**
 611      * Format a long to produce a string.
 612      * @param number    The long to format
 613      * @param result    where the text is to be appended
 614      * @param fieldPosition    On input: an alignment field, if desired.
 615      * On output: the offsets of the alignment field.
 616      * @exception       ArithmeticException if rounding is needed with rounding
 617      *                  mode being set to RoundingMode.UNNECESSARY
 618      * @return The formatted number string
 619      * @see java.text.FieldPosition
 620      */
 621     public StringBuffer format(long number, StringBuffer result,
 622                                FieldPosition fieldPosition) {
 623         fieldPosition.setBeginIndex(0);
 624         fieldPosition.setEndIndex(0);
 625 
 626         return format(number, result, fieldPosition.getFieldDelegate());
 627     }
 628 
 629     /**
 630      * Format a long to produce a string.
 631      * @param number    The long to format
 632      * @param result    where the text is to be appended
 633      * @param delegate notified of locations of sub fields
 634      * @return The formatted number string
 635      * @exception        ArithmeticException if rounding is needed with rounding
 636      *                   mode being set to RoundingMode.UNNECESSARY
 637      * @see java.text.FieldPosition
 638      */
 639     private StringBuffer format(long number, StringBuffer result,
 640                                FieldDelegate delegate) {
 641         boolean isNegative = (number < 0);
 642         if (isNegative) {
 643             number = -number;
 644         }
 645 
 646         // In general, long values always represent real finite numbers, so
 647         // we don't have to check for +/- Infinity or NaN.  However, there
 648         // is one case we have to be careful of:  The multiplier can push
 649         // a number near MIN_VALUE or MAX_VALUE outside the legal range.  We
 650         // check for this before multiplying, and if it happens we use
 651         // BigInteger instead.
 652         boolean useBigInteger = false;
 653         if (number < 0) { // This can only happen if number == Long.MIN_VALUE.
 654             if (multiplier != 0) {
 655                 useBigInteger = true;
 656             }
 657         } else if (multiplier != 1 && multiplier != 0) {
 658             long cutoff = Long.MAX_VALUE / multiplier;
 659             if (cutoff < 0) {
 660                 cutoff = -cutoff;
 661             }
 662             useBigInteger = (number > cutoff);
 663         }
 664 
 665         if (useBigInteger) {
 666             if (isNegative) {
 667                 number = -number;
 668             }
 669             BigInteger bigIntegerValue = BigInteger.valueOf(number);
 670             return format(bigIntegerValue, result, delegate, true);
 671         }
 672 
 673         number *= multiplier;
 674         if (number == 0) {
 675             isNegative = false;
 676         } else {
 677             if (multiplier < 0) {
 678                 number = -number;
 679                 isNegative = !isNegative;
 680             }
 681         }
 682 
 683         synchronized(digitList) {
 684             int maxIntDigits = super.getMaximumIntegerDigits();
 685             int minIntDigits = super.getMinimumIntegerDigits();
 686             int maxFraDigits = super.getMaximumFractionDigits();
 687             int minFraDigits = super.getMinimumFractionDigits();
 688 
 689             digitList.set(isNegative, number,
 690                      useExponentialNotation ? maxIntDigits + maxFraDigits : 0);
 691 
 692             return subformat(result, delegate, isNegative, true,
 693                        maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
 694         }
 695     }
 696 
 697     /**
 698      * Formats a BigDecimal to produce a string.
 699      * @param number    The BigDecimal to format
 700      * @param result    where the text is to be appended
 701      * @param fieldPosition    On input: an alignment field, if desired.
 702      * On output: the offsets of the alignment field.
 703      * @return The formatted number string
 704      * @exception        ArithmeticException if rounding is needed with rounding
 705      *                   mode being set to RoundingMode.UNNECESSARY
 706      * @see java.text.FieldPosition
 707      */
 708     private StringBuffer format(BigDecimal number, StringBuffer result,
 709                                 FieldPosition fieldPosition) {
 710         fieldPosition.setBeginIndex(0);
 711         fieldPosition.setEndIndex(0);
 712         return format(number, result, fieldPosition.getFieldDelegate());
 713     }
 714 
 715     /**
 716      * Formats a BigDecimal to produce a string.
 717      * @param number    The BigDecimal to format
 718      * @param result    where the text is to be appended
 719      * @param delegate notified of locations of sub fields
 720      * @exception        ArithmeticException if rounding is needed with rounding
 721      *                   mode being set to RoundingMode.UNNECESSARY
 722      * @return The formatted number string
 723      */
 724     private StringBuffer format(BigDecimal number, StringBuffer result,
 725                                 FieldDelegate delegate) {
 726         if (multiplier != 1) {
 727             number = number.multiply(getBigDecimalMultiplier());
 728         }
 729         boolean isNegative = number.signum() == -1;
 730         if (isNegative) {
 731             number = number.negate();
 732         }
 733 
 734         synchronized(digitList) {
 735             int maxIntDigits = getMaximumIntegerDigits();
 736             int minIntDigits = getMinimumIntegerDigits();
 737             int maxFraDigits = getMaximumFractionDigits();
 738             int minFraDigits = getMinimumFractionDigits();
 739             int maximumDigits = maxIntDigits + maxFraDigits;
 740 
 741             digitList.set(isNegative, number, useExponentialNotation ?
 742                 ((maximumDigits < 0) ? Integer.MAX_VALUE : maximumDigits) :
 743                 maxFraDigits, !useExponentialNotation);
 744 
 745             return subformat(result, delegate, isNegative, false,
 746                 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
 747         }
 748     }
 749 
 750     /**
 751      * Format a BigInteger to produce a string.
 752      * @param number    The BigInteger to format
 753      * @param result    where the text is to be appended
 754      * @param fieldPosition    On input: an alignment field, if desired.
 755      * On output: the offsets of the alignment field.
 756      * @return The formatted number string
 757      * @exception        ArithmeticException if rounding is needed with rounding
 758      *                   mode being set to RoundingMode.UNNECESSARY
 759      * @see java.text.FieldPosition
 760      */
 761     private StringBuffer format(BigInteger number, StringBuffer result,
 762                                FieldPosition fieldPosition) {
 763         fieldPosition.setBeginIndex(0);
 764         fieldPosition.setEndIndex(0);
 765 
 766         return format(number, result, fieldPosition.getFieldDelegate(), false);
 767     }
 768 
 769     /**
 770      * Format a BigInteger to produce a string.
 771      * @param number    The BigInteger to format
 772      * @param result    where the text is to be appended
 773      * @param delegate notified of locations of sub fields
 774      * @return The formatted number string
 775      * @exception        ArithmeticException if rounding is needed with rounding
 776      *                   mode being set to RoundingMode.UNNECESSARY
 777      * @see java.text.FieldPosition
 778      */
 779     private StringBuffer format(BigInteger number, StringBuffer result,
 780                                FieldDelegate delegate, boolean formatLong) {
 781         if (multiplier != 1) {
 782             number = number.multiply(getBigIntegerMultiplier());
 783         }
 784         boolean isNegative = number.signum() == -1;
 785         if (isNegative) {
 786             number = number.negate();
 787         }
 788 
 789         synchronized(digitList) {
 790             int maxIntDigits, minIntDigits, maxFraDigits, minFraDigits, maximumDigits;
 791             if (formatLong) {
 792                 maxIntDigits = super.getMaximumIntegerDigits();
 793                 minIntDigits = super.getMinimumIntegerDigits();
 794                 maxFraDigits = super.getMaximumFractionDigits();
 795                 minFraDigits = super.getMinimumFractionDigits();
 796                 maximumDigits = maxIntDigits + maxFraDigits;
 797             } else {
 798                 maxIntDigits = getMaximumIntegerDigits();
 799                 minIntDigits = getMinimumIntegerDigits();
 800                 maxFraDigits = getMaximumFractionDigits();
 801                 minFraDigits = getMinimumFractionDigits();
 802                 maximumDigits = maxIntDigits + maxFraDigits;
 803                 if (maximumDigits < 0) {
 804                     maximumDigits = Integer.MAX_VALUE;
 805                 }
 806             }
 807 
 808             digitList.set(isNegative, number,
 809                           useExponentialNotation ? maximumDigits : 0);
 810 
 811             return subformat(result, delegate, isNegative, true,
 812                 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
 813         }
 814     }
 815 
 816     /**
 817      * Formats an Object producing an <code>AttributedCharacterIterator</code>.
 818      * You can use the returned <code>AttributedCharacterIterator</code>
 819      * to build the resulting String, as well as to determine information
 820      * about the resulting String.
 821      * <p>
 822      * Each attribute key of the AttributedCharacterIterator will be of type
 823      * <code>NumberFormat.Field</code>, with the attribute value being the
 824      * same as the attribute key.
 825      *
 826      * @exception NullPointerException if obj is null.
 827      * @exception IllegalArgumentException when the Format cannot format the
 828      *            given object.
 829      * @exception        ArithmeticException if rounding is needed with rounding
 830      *                   mode being set to RoundingMode.UNNECESSARY
 831      * @param obj The object to format
 832      * @return AttributedCharacterIterator describing the formatted value.
 833      * @since 1.4
 834      */
 835     public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
 836         CharacterIteratorFieldDelegate delegate =
 837                          new CharacterIteratorFieldDelegate();
 838         StringBuffer sb = new StringBuffer();
 839 
 840         if (obj instanceof Double || obj instanceof Float) {
 841             format(((Number)obj).doubleValue(), sb, delegate);
 842         } else if (obj instanceof Long || obj instanceof Integer ||
 843                    obj instanceof Short || obj instanceof Byte ||
 844                    obj instanceof AtomicInteger || obj instanceof AtomicLong) {
 845             format(((Number)obj).longValue(), sb, delegate);
 846         } else if (obj instanceof BigDecimal) {
 847             format((BigDecimal)obj, sb, delegate);
 848         } else if (obj instanceof BigInteger) {
 849             format((BigInteger)obj, sb, delegate, false);
 850         } else if (obj == null) {
 851             throw new NullPointerException(
 852                 "formatToCharacterIterator must be passed non-null object");
 853         } else {
 854             throw new IllegalArgumentException(
 855                 "Cannot format given Object as a Number");
 856         }
 857         return delegate.getIterator(sb.toString());
 858     }
 859 
 860     /**
 861      * Complete the formatting of a finite number.  On entry, the digitList must
 862      * be filled in with the correct digits.
 863      */
 864     private StringBuffer subformat(StringBuffer result, FieldDelegate delegate,
 865                                    boolean isNegative, boolean isInteger,
 866                                    int maxIntDigits, int minIntDigits,
 867                                    int maxFraDigits, int minFraDigits) {
 868         // NOTE: This isn't required anymore because DigitList takes care of this.
 869         //
 870         //  // The negative of the exponent represents the number of leading
 871         //  // zeros between the decimal and the first non-zero digit, for
 872         //  // a value < 0.1 (e.g., for 0.00123, -fExponent == 2).  If this
 873         //  // is more than the maximum fraction digits, then we have an underflow
 874         //  // for the printed representation.  We recognize this here and set
 875         //  // the DigitList representation to zero in this situation.
 876         //
 877         //  if (-digitList.decimalAt >= getMaximumFractionDigits())
 878         //  {
 879         //      digitList.count = 0;
 880         //  }
 881 
 882         char zero = symbols.getZeroDigit();
 883         int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
 884         char grouping = symbols.getGroupingSeparator();
 885         char decimal = isCurrencyFormat ?
 886             symbols.getMonetaryDecimalSeparator() :
 887             symbols.getDecimalSeparator();
 888 
 889         /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
 890          * format as zero.  This allows sensible computations and preserves
 891          * relations such as signum(1/x) = signum(x), where x is +Infinity or
 892          * -Infinity.  Prior to this fix, we always formatted zero values as if
 893          * they were positive.  Liu 7/6/98.
 894          */
 895         if (digitList.isZero()) {
 896             digitList.decimalAt = 0; // Normalize
 897         }
 898 
 899         if (isNegative) {
 900             append(result, negativePrefix, delegate,
 901                    getNegativePrefixFieldPositions(), Field.SIGN);
 902         } else {
 903             append(result, positivePrefix, delegate,
 904                    getPositivePrefixFieldPositions(), Field.SIGN);
 905         }
 906 
 907         if (useExponentialNotation) {
 908             int iFieldStart = result.length();
 909             int iFieldEnd = -1;
 910             int fFieldStart = -1;
 911 
 912             // Minimum integer digits are handled in exponential format by
 913             // adjusting the exponent.  For example, 0.01234 with 3 minimum
 914             // integer digits is "123.4E-4".
 915 
 916             // Maximum integer digits are interpreted as indicating the
 917             // repeating range.  This is useful for engineering notation, in
 918             // which the exponent is restricted to a multiple of 3.  For
 919             // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
 920             // If maximum integer digits are > 1 and are larger than
 921             // minimum integer digits, then minimum integer digits are
 922             // ignored.
 923             int exponent = digitList.decimalAt;
 924             int repeat = maxIntDigits;
 925             int minimumIntegerDigits = minIntDigits;
 926             if (repeat > 1 && repeat > minIntDigits) {
 927                 // A repeating range is defined; adjust to it as follows.
 928                 // If repeat == 3, we have 6,5,4=>3; 3,2,1=>0; 0,-1,-2=>-3;
 929                 // -3,-4,-5=>-6, etc. This takes into account that the
 930                 // exponent we have here is off by one from what we expect;
 931                 // it is for the format 0.MMMMMx10^n.
 932                 if (exponent >= 1) {
 933                     exponent = ((exponent - 1) / repeat) * repeat;
 934                 } else {
 935                     // integer division rounds towards 0
 936                     exponent = ((exponent - repeat) / repeat) * repeat;
 937                 }
 938                 minimumIntegerDigits = 1;
 939             } else {
 940                 // No repeating range is defined; use minimum integer digits.
 941                 exponent -= minimumIntegerDigits;
 942             }
 943 
 944             // We now output a minimum number of digits, and more if there
 945             // are more digits, up to the maximum number of digits.  We
 946             // place the decimal point after the "integer" digits, which
 947             // are the first (decimalAt - exponent) digits.
 948             int minimumDigits = minIntDigits + minFraDigits;
 949             if (minimumDigits < 0) {    // overflow?
 950                 minimumDigits = Integer.MAX_VALUE;
 951             }
 952 
 953             // The number of integer digits is handled specially if the number
 954             // is zero, since then there may be no digits.
 955             int integerDigits = digitList.isZero() ? minimumIntegerDigits :
 956                     digitList.decimalAt - exponent;
 957             if (minimumDigits < integerDigits) {
 958                 minimumDigits = integerDigits;
 959             }
 960             int totalDigits = digitList.count;
 961             if (minimumDigits > totalDigits) {
 962                 totalDigits = minimumDigits;
 963             }
 964             boolean addedDecimalSeparator = false;
 965 
 966             for (int i=0; i<totalDigits; ++i) {
 967                 if (i == integerDigits) {
 968                     // Record field information for caller.
 969                     iFieldEnd = result.length();
 970 
 971                     result.append(decimal);
 972                     addedDecimalSeparator = true;
 973 
 974                     // Record field information for caller.
 975                     fFieldStart = result.length();
 976                 }
 977                 result.append((i < digitList.count) ?
 978                               (char)(digitList.digits[i] + zeroDelta) :
 979                               zero);
 980             }
 981 
 982             if (decimalSeparatorAlwaysShown && totalDigits == integerDigits) {
 983                 // Record field information for caller.
 984                 iFieldEnd = result.length();
 985 
 986                 result.append(decimal);
 987                 addedDecimalSeparator = true;
 988 
 989                 // Record field information for caller.
 990                 fFieldStart = result.length();
 991             }
 992 
 993             // Record field information
 994             if (iFieldEnd == -1) {
 995                 iFieldEnd = result.length();
 996             }
 997             delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
 998                                iFieldStart, iFieldEnd, result);
 999             if (addedDecimalSeparator) {
1000                 delegate.formatted(Field.DECIMAL_SEPARATOR,
1001                                    Field.DECIMAL_SEPARATOR,
1002                                    iFieldEnd, fFieldStart, result);
1003             }
1004             if (fFieldStart == -1) {
1005                 fFieldStart = result.length();
1006             }
1007             delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
1008                                fFieldStart, result.length(), result);
1009 
1010             // The exponent is output using the pattern-specified minimum
1011             // exponent digits.  There is no maximum limit to the exponent
1012             // digits, since truncating the exponent would result in an
1013             // unacceptable inaccuracy.
1014             int fieldStart = result.length();
1015 
1016             result.append(symbols.getExponentSeparator());
1017 
1018             delegate.formatted(Field.EXPONENT_SYMBOL, Field.EXPONENT_SYMBOL,
1019                                fieldStart, result.length(), result);
1020 
1021             // For zero values, we force the exponent to zero.  We
1022             // must do this here, and not earlier, because the value
1023             // is used to determine integer digit count above.
1024             if (digitList.isZero()) {
1025                 exponent = 0;
1026             }
1027 
1028             boolean negativeExponent = exponent < 0;
1029             if (negativeExponent) {
1030                 exponent = -exponent;
1031                 fieldStart = result.length();
1032                 result.append(symbols.getMinusSign());
1033                 delegate.formatted(Field.EXPONENT_SIGN, Field.EXPONENT_SIGN,
1034                                    fieldStart, result.length(), result);
1035             }
1036             digitList.set(negativeExponent, exponent);
1037 
1038             int eFieldStart = result.length();
1039 
1040             for (int i=digitList.decimalAt; i<minExponentDigits; ++i) {
1041                 result.append(zero);
1042             }
1043             for (int i=0; i<digitList.decimalAt; ++i) {
1044                 result.append((i < digitList.count) ?
1045                           (char)(digitList.digits[i] + zeroDelta) : zero);
1046             }
1047             delegate.formatted(Field.EXPONENT, Field.EXPONENT, eFieldStart,
1048                                result.length(), result);
1049         } else {
1050             int iFieldStart = result.length();
1051 
1052             // Output the integer portion.  Here 'count' is the total
1053             // number of integer digits we will display, including both
1054             // leading zeros required to satisfy getMinimumIntegerDigits,
1055             // and actual digits present in the number.
1056             int count = minIntDigits;
1057             int digitIndex = 0; // Index into digitList.fDigits[]
1058             if (digitList.decimalAt > 0 && count < digitList.decimalAt) {
1059                 count = digitList.decimalAt;
1060             }
1061 
1062             // Handle the case where getMaximumIntegerDigits() is smaller
1063             // than the real number of integer digits.  If this is so, we
1064             // output the least significant max integer digits.  For example,
1065             // the value 1997 printed with 2 max integer digits is just "97".
1066             if (count > maxIntDigits) {
1067                 count = maxIntDigits;
1068                 digitIndex = digitList.decimalAt - count;
1069             }
1070 
1071             int sizeBeforeIntegerPart = result.length();
1072             for (int i=count-1; i>=0; --i) {
1073                 if (i < digitList.decimalAt && digitIndex < digitList.count) {
1074                     // Output a real digit
1075                     result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
1076                 } else {
1077                     // Output a leading zero
1078                     result.append(zero);
1079                 }
1080 
1081                 // Output grouping separator if necessary.  Don't output a
1082                 // grouping separator if i==0 though; that's at the end of
1083                 // the integer part.
1084                 if (isGroupingUsed() && i>0 && (groupingSize != 0) &&
1085                     (i % groupingSize == 0)) {
1086                     int gStart = result.length();
1087                     result.append(grouping);
1088                     delegate.formatted(Field.GROUPING_SEPARATOR,
1089                                        Field.GROUPING_SEPARATOR, gStart,
1090                                        result.length(), result);
1091                 }
1092             }
1093 
1094             // Determine whether or not there are any printable fractional
1095             // digits.  If we've used up the digits we know there aren't.
1096             boolean fractionPresent = (minFraDigits > 0) ||
1097                 (!isInteger && digitIndex < digitList.count);
1098 
1099             // If there is no fraction present, and we haven't printed any
1100             // integer digits, then print a zero.  Otherwise we won't print
1101             // _any_ digits, and we won't be able to parse this string.
1102             if (!fractionPresent && result.length() == sizeBeforeIntegerPart) {
1103                 result.append(zero);
1104             }
1105 
1106             delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
1107                                iFieldStart, result.length(), result);
1108 
1109             // Output the decimal separator if we always do so.
1110             int sStart = result.length();
1111             if (decimalSeparatorAlwaysShown || fractionPresent) {
1112                 result.append(decimal);
1113             }
1114 
1115             if (sStart != result.length()) {
1116                 delegate.formatted(Field.DECIMAL_SEPARATOR,
1117                                    Field.DECIMAL_SEPARATOR,
1118                                    sStart, result.length(), result);
1119             }
1120             int fFieldStart = result.length();
1121 
1122             for (int i=0; i < maxFraDigits; ++i) {
1123                 // Here is where we escape from the loop.  We escape if we've
1124                 // output the maximum fraction digits (specified in the for
1125                 // expression above).
1126                 // We also stop when we've output the minimum digits and either:
1127                 // we have an integer, so there is no fractional stuff to
1128                 // display, or we're out of significant digits.
1129                 if (i >= minFraDigits &&
1130                     (isInteger || digitIndex >= digitList.count)) {
1131                     break;
1132                 }
1133 
1134                 // Output leading fractional zeros. These are zeros that come
1135                 // after the decimal but before any significant digits. These
1136                 // are only output if abs(number being formatted) < 1.0.
1137                 if (-1-i > (digitList.decimalAt-1)) {
1138                     result.append(zero);
1139                     continue;
1140                 }
1141 
1142                 // Output a digit, if we have any precision left, or a
1143                 // zero if we don't.  We don't want to output noise digits.
1144                 if (!isInteger && digitIndex < digitList.count) {
1145                     result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
1146                 } else {
1147                     result.append(zero);
1148                 }
1149             }
1150 
1151             // Record field information for caller.
1152             delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
1153                                fFieldStart, result.length(), result);
1154         }
1155 
1156         if (isNegative) {
1157             append(result, negativeSuffix, delegate,
1158                    getNegativeSuffixFieldPositions(), Field.SIGN);
1159         }
1160         else {
1161             append(result, positiveSuffix, delegate,
1162                    getPositiveSuffixFieldPositions(), Field.SIGN);
1163         }
1164 
1165         return result;
1166     }
1167 
1168     /**
1169      * Appends the String <code>string</code> to <code>result</code>.
1170      * <code>delegate</code> is notified of all  the
1171      * <code>FieldPosition</code>s in <code>positions</code>.
1172      * <p>
1173      * If one of the <code>FieldPosition</code>s in <code>positions</code>
1174      * identifies a <code>SIGN</code> attribute, it is mapped to
1175      * <code>signAttribute</code>. This is used
1176      * to map the <code>SIGN</code> attribute to the <code>EXPONENT</code>
1177      * attribute as necessary.
1178      * <p>
1179      * This is used by <code>subformat</code> to add the prefix/suffix.
1180      */
1181     private void append(StringBuffer result, String string,
1182                         FieldDelegate delegate,
1183                         FieldPosition[] positions,
1184                         Format.Field signAttribute) {
1185         int start = result.length();
1186 
1187         if (string.length() > 0) {
1188             result.append(string);
1189             for (int counter = 0, max = positions.length; counter < max;
1190                  counter++) {
1191                 FieldPosition fp = positions[counter];
1192                 Format.Field attribute = fp.getFieldAttribute();
1193 
1194                 if (attribute == Field.SIGN) {
1195                     attribute = signAttribute;
1196                 }
1197                 delegate.formatted(attribute, attribute,
1198                                    start + fp.getBeginIndex(),
1199                                    start + fp.getEndIndex(), result);
1200             }
1201         }
1202     }
1203 
1204     /**
1205      * Parses text from a string to produce a <code>Number</code>.
1206      * <p>
1207      * The method attempts to parse text starting at the index given by
1208      * <code>pos</code>.
1209      * If parsing succeeds, then the index of <code>pos</code> is updated
1210      * to the index after the last character used (parsing does not necessarily
1211      * use all characters up to the end of the string), and the parsed
1212      * number is returned. The updated <code>pos</code> can be used to
1213      * indicate the starting point for the next call to this method.
1214      * If an error occurs, then the index of <code>pos</code> is not
1215      * changed, the error index of <code>pos</code> is set to the index of
1216      * the character where the error occurred, and null is returned.
1217      * <p>
1218      * The subclass returned depends on the value of {@link #isParseBigDecimal}
1219      * as well as on the string being parsed.
1220      * <ul>
1221      *   <li>If <code>isParseBigDecimal()</code> is false (the default),
1222      *       most integer values are returned as <code>Long</code>
1223      *       objects, no matter how they are written: <code>"17"</code> and
1224      *       <code>"17.000"</code> both parse to <code>Long(17)</code>.
1225      *       Values that cannot fit into a <code>Long</code> are returned as
1226      *       <code>Double</code>s. This includes values with a fractional part,
1227      *       infinite values, <code>NaN</code>, and the value -0.0.
1228      *       <code>DecimalFormat</code> does <em>not</em> decide whether to
1229      *       return a <code>Double</code> or a <code>Long</code> based on the
1230      *       presence of a decimal separator in the source string. Doing so
1231      *       would prevent integers that overflow the mantissa of a double,
1232      *       such as <code>"-9,223,372,036,854,775,808.00"</code>, from being
1233      *       parsed accurately.
1234      *       <p>
1235      *       Callers may use the <code>Number</code> methods
1236      *       <code>doubleValue</code>, <code>longValue</code>, etc., to obtain
1237      *       the type they want.
1238      *   <li>If <code>isParseBigDecimal()</code> is true, values are returned
1239      *       as <code>BigDecimal</code> objects. The values are the ones
1240      *       constructed by {@link java.math.BigDecimal#BigDecimal(String)}
1241      *       for corresponding strings in locale-independent format. The
1242      *       special cases negative and positive infinity and NaN are returned
1243      *       as <code>Double</code> instances holding the values of the
1244      *       corresponding <code>Double</code> constants.
1245      * </ul>
1246      * <p>
1247      * <code>DecimalFormat</code> parses all Unicode characters that represent
1248      * decimal digits, as defined by <code>Character.digit()</code>. In
1249      * addition, <code>DecimalFormat</code> also recognizes as digits the ten
1250      * consecutive characters starting with the localized zero digit defined in
1251      * the <code>DecimalFormatSymbols</code> object.
1252      *
1253      * @param text the string to be parsed
1254      * @param pos  A <code>ParsePosition</code> object with index and error
1255      *             index information as described above.
1256      * @return     the parsed value, or <code>null</code> if the parse fails
1257      * @exception  NullPointerException if <code>text</code> or
1258      *             <code>pos</code> is null.
1259      */
1260     public Number parse(String text, ParsePosition pos) {
1261         // special case NaN
1262         if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) {
1263             pos.index = pos.index + symbols.getNaN().length();
1264             return new Double(Double.NaN);
1265         }
1266 
1267         boolean[] status = new boolean[STATUS_LENGTH];
1268         if (!subparse(text, pos, positivePrefix, negativePrefix, digitList, false, status)) {
1269             return null;
1270         }
1271 
1272         // special case INFINITY
1273         if (status[STATUS_INFINITE]) {
1274             if (status[STATUS_POSITIVE] == (multiplier >= 0)) {
1275                 return new Double(Double.POSITIVE_INFINITY);
1276             } else {
1277                 return new Double(Double.NEGATIVE_INFINITY);
1278             }
1279         }
1280 
1281         if (multiplier == 0) {
1282             if (digitList.isZero()) {
1283                 return new Double(Double.NaN);
1284             } else if (status[STATUS_POSITIVE]) {
1285                 return new Double(Double.POSITIVE_INFINITY);
1286             } else {
1287                 return new Double(Double.NEGATIVE_INFINITY);
1288             }
1289         }
1290 
1291         if (isParseBigDecimal()) {
1292             BigDecimal bigDecimalResult = digitList.getBigDecimal();
1293 
1294             if (multiplier != 1) {
1295                 try {
1296                     bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier());
1297                 }
1298                 catch (ArithmeticException e) {  // non-terminating decimal expansion
1299                     bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier(), roundingMode);
1300                 }
1301             }
1302 
1303             if (!status[STATUS_POSITIVE]) {
1304                 bigDecimalResult = bigDecimalResult.negate();
1305             }
1306             return bigDecimalResult;
1307         } else {
1308             boolean gotDouble = true;
1309             boolean gotLongMinimum = false;
1310             double  doubleResult = 0.0;
1311             long    longResult = 0;
1312 
1313             // Finally, have DigitList parse the digits into a value.
1314             if (digitList.fitsIntoLong(status[STATUS_POSITIVE], isParseIntegerOnly())) {
1315                 gotDouble = false;
1316                 longResult = digitList.getLong();
1317                 if (longResult < 0) {  // got Long.MIN_VALUE
1318                     gotLongMinimum = true;
1319                 }
1320             } else {
1321                 doubleResult = digitList.getDouble();
1322             }
1323 
1324             // Divide by multiplier. We have to be careful here not to do
1325             // unneeded conversions between double and long.
1326             if (multiplier != 1) {
1327                 if (gotDouble) {
1328                     doubleResult /= multiplier;
1329                 } else {
1330                     // Avoid converting to double if we can
1331                     if (longResult % multiplier == 0) {
1332                         longResult /= multiplier;
1333                     } else {
1334                         doubleResult = ((double)longResult) / multiplier;
1335                         gotDouble = true;
1336                     }
1337                 }
1338             }
1339 
1340             if (!status[STATUS_POSITIVE] && !gotLongMinimum) {
1341                 doubleResult = -doubleResult;
1342                 longResult = -longResult;
1343             }
1344 
1345             // At this point, if we divided the result by the multiplier, the
1346             // result may fit into a long.  We check for this case and return
1347             // a long if possible.
1348             // We must do this AFTER applying the negative (if appropriate)
1349             // in order to handle the case of LONG_MIN; otherwise, if we do
1350             // this with a positive value -LONG_MIN, the double is > 0, but
1351             // the long is < 0. We also must retain a double in the case of
1352             // -0.0, which will compare as == to a long 0 cast to a double
1353             // (bug 4162852).
1354             if (multiplier != 1 && gotDouble) {
1355                 longResult = (long)doubleResult;
1356                 gotDouble = ((doubleResult != (double)longResult) ||
1357                             (doubleResult == 0.0 && 1/doubleResult < 0.0)) &&
1358                             !isParseIntegerOnly();
1359             }
1360 
1361             return gotDouble ?
1362                 (Number)new Double(doubleResult) : (Number)new Long(longResult);
1363         }
1364     }
1365 
1366     /**
1367      * Return a BigInteger multiplier.
1368      */
1369     private BigInteger getBigIntegerMultiplier() {
1370         if (bigIntegerMultiplier == null) {
1371             bigIntegerMultiplier = BigInteger.valueOf(multiplier);
1372         }
1373         return bigIntegerMultiplier;
1374     }
1375     private transient BigInteger bigIntegerMultiplier;
1376 
1377     /**
1378      * Return a BigDecimal multiplier.
1379      */
1380     private BigDecimal getBigDecimalMultiplier() {
1381         if (bigDecimalMultiplier == null) {
1382             bigDecimalMultiplier = new BigDecimal(multiplier);
1383         }
1384         return bigDecimalMultiplier;
1385     }
1386     private transient BigDecimal bigDecimalMultiplier;
1387 
1388     private static final int STATUS_INFINITE = 0;
1389     private static final int STATUS_POSITIVE = 1;
1390     private static final int STATUS_LENGTH   = 2;
1391 
1392     /**
1393      * Parse the given text into a number.  The text is parsed beginning at
1394      * parsePosition, until an unparseable character is seen.
1395      * @param text The string to parse.
1396      * @param parsePosition The position at which to being parsing.  Upon
1397      * return, the first unparseable character.
1398      * @param digits The DigitList to set to the parsed value.
1399      * @param isExponent If true, parse an exponent.  This means no
1400      * infinite values and integer only.
1401      * @param status Upon return contains boolean status flags indicating
1402      * whether the value was infinite and whether it was positive.
1403      */
1404     private final boolean subparse(String text, ParsePosition parsePosition,
1405                    String positivePrefix, String negativePrefix,
1406                    DigitList digits, boolean isExponent,
1407                    boolean status[]) {
1408         int position = parsePosition.index;
1409         int oldStart = parsePosition.index;
1410         int backup;
1411         boolean gotPositive, gotNegative;
1412 
1413         // check for positivePrefix; take longest
1414         gotPositive = text.regionMatches(position, positivePrefix, 0,
1415                                          positivePrefix.length());
1416         gotNegative = text.regionMatches(position, negativePrefix, 0,
1417                                          negativePrefix.length());
1418 
1419         if (gotPositive && gotNegative) {
1420             if (positivePrefix.length() > negativePrefix.length()) {
1421                 gotNegative = false;
1422             } else if (positivePrefix.length() < negativePrefix.length()) {
1423                 gotPositive = false;
1424             }
1425         }
1426 
1427         if (gotPositive) {
1428             position += positivePrefix.length();
1429         } else if (gotNegative) {
1430             position += negativePrefix.length();
1431         } else {
1432             parsePosition.errorIndex = position;
1433             return false;
1434         }
1435 
1436         // process digits or Inf, find decimal position
1437         status[STATUS_INFINITE] = false;
1438         if (!isExponent && text.regionMatches(position,symbols.getInfinity(),0,
1439                           symbols.getInfinity().length())) {
1440             position += symbols.getInfinity().length();
1441             status[STATUS_INFINITE] = true;
1442         } else {
1443             // We now have a string of digits, possibly with grouping symbols,
1444             // and decimal points.  We want to process these into a DigitList.
1445             // We don't want to put a bunch of leading zeros into the DigitList
1446             // though, so we keep track of the location of the decimal point,
1447             // put only significant digits into the DigitList, and adjust the
1448             // exponent as needed.
1449 
1450             digits.decimalAt = digits.count = 0;
1451             char zero = symbols.getZeroDigit();
1452             char decimal = isCurrencyFormat ?
1453                 symbols.getMonetaryDecimalSeparator() :
1454                 symbols.getDecimalSeparator();
1455             char grouping = symbols.getGroupingSeparator();
1456             String exponentString = symbols.getExponentSeparator();
1457             boolean sawDecimal = false;
1458             boolean sawExponent = false;
1459             boolean sawDigit = false;
1460             int exponent = 0; // Set to the exponent value, if any
1461 
1462             // We have to track digitCount ourselves, because digits.count will
1463             // pin when the maximum allowable digits is reached.
1464             int digitCount = 0;
1465 
1466             backup = -1;
1467             for (; position < text.length(); ++position) {
1468                 char ch = text.charAt(position);
1469 
1470                 /* We recognize all digit ranges, not only the Latin digit range
1471                  * '0'..'9'.  We do so by using the Character.digit() method,
1472                  * which converts a valid Unicode digit to the range 0..9.
1473                  *
1474                  * The character 'ch' may be a digit.  If so, place its value
1475                  * from 0 to 9 in 'digit'.  First try using the locale digit,
1476                  * which may or MAY NOT be a standard Unicode digit range.  If
1477                  * this fails, try using the standard Unicode digit ranges by
1478                  * calling Character.digit().  If this also fails, digit will
1479                  * have a value outside the range 0..9.
1480                  */
1481                 int digit = ch - zero;
1482                 if (digit < 0 || digit > 9) {
1483                     digit = Character.digit(ch, 10);
1484                 }
1485 
1486                 if (digit == 0) {
1487                     // Cancel out backup setting (see grouping handler below)
1488                     backup = -1; // Do this BEFORE continue statement below!!!
1489                     sawDigit = true;
1490 
1491                     // Handle leading zeros
1492                     if (digits.count == 0) {
1493                         // Ignore leading zeros in integer part of number.
1494                         if (!sawDecimal) {
1495                             continue;
1496                         }
1497 
1498                         // If we have seen the decimal, but no significant
1499                         // digits yet, then we account for leading zeros by
1500                         // decrementing the digits.decimalAt into negative
1501                         // values.
1502                         --digits.decimalAt;
1503                     } else {
1504                         ++digitCount;
1505                         digits.append((char)(digit + '0'));
1506                     }
1507                 } else if (digit > 0 && digit <= 9) { // [sic] digit==0 handled above
1508                     sawDigit = true;
1509                     ++digitCount;
1510                     digits.append((char)(digit + '0'));
1511 
1512                     // Cancel out backup setting (see grouping handler below)
1513                     backup = -1;
1514                 } else if (!isExponent && ch == decimal) {
1515                     // If we're only parsing integers, or if we ALREADY saw the
1516                     // decimal, then don't parse this one.
1517                     if (isParseIntegerOnly() || sawDecimal) {
1518                         break;
1519                     }
1520                     digits.decimalAt = digitCount; // Not digits.count!
1521                     sawDecimal = true;
1522                 } else if (!isExponent && ch == grouping && isGroupingUsed()) {
1523                     if (sawDecimal) {
1524                         break;
1525                     }
1526                     // Ignore grouping characters, if we are using them, but
1527                     // require that they be followed by a digit.  Otherwise
1528                     // we backup and reprocess them.
1529                     backup = position;
1530                 } else if (!isExponent && text.regionMatches(position, exponentString, 0, exponentString.length())
1531                              && !sawExponent) {
1532                     // Process the exponent by recursively calling this method.
1533                      ParsePosition pos = new ParsePosition(position + exponentString.length());
1534                     boolean[] stat = new boolean[STATUS_LENGTH];
1535                     DigitList exponentDigits = new DigitList();
1536 
1537                     if (subparse(text, pos, "", Character.toString(symbols.getMinusSign()), exponentDigits, true, stat) &&
1538                         exponentDigits.fitsIntoLong(stat[STATUS_POSITIVE], true)) {
1539                         position = pos.index; // Advance past the exponent
1540                         exponent = (int)exponentDigits.getLong();
1541                         if (!stat[STATUS_POSITIVE]) {
1542                             exponent = -exponent;
1543                         }
1544                         sawExponent = true;
1545                     }
1546                     break; // Whether we fail or succeed, we exit this loop
1547                 }
1548                 else {
1549                     break;
1550                 }
1551             }
1552 
1553             if (backup != -1) {
1554                 position = backup;
1555             }
1556 
1557             // If there was no decimal point we have an integer
1558             if (!sawDecimal) {
1559                 digits.decimalAt = digitCount; // Not digits.count!
1560             }
1561 
1562             // Adjust for exponent, if any
1563             digits.decimalAt += exponent;
1564 
1565             // If none of the text string was recognized.  For example, parse
1566             // "x" with pattern "#0.00" (return index and error index both 0)
1567             // parse "$" with pattern "$#0.00". (return index 0 and error
1568             // index 1).
1569             if (!sawDigit && digitCount == 0) {
1570                 parsePosition.index = oldStart;
1571                 parsePosition.errorIndex = oldStart;
1572                 return false;
1573             }
1574         }
1575 
1576         // check for suffix
1577         if (!isExponent) {
1578             if (gotPositive) {
1579                 gotPositive = text.regionMatches(position,positiveSuffix,0,
1580                                                  positiveSuffix.length());
1581             }
1582             if (gotNegative) {
1583                 gotNegative = text.regionMatches(position,negativeSuffix,0,
1584                                                  negativeSuffix.length());
1585             }
1586 
1587         // if both match, take longest
1588         if (gotPositive && gotNegative) {
1589             if (positiveSuffix.length() > negativeSuffix.length()) {
1590                 gotNegative = false;
1591             } else if (positiveSuffix.length() < negativeSuffix.length()) {
1592                 gotPositive = false;
1593             }
1594         }
1595 
1596         // fail if neither or both
1597         if (gotPositive == gotNegative) {
1598             parsePosition.errorIndex = position;
1599             return false;
1600         }
1601 
1602         parsePosition.index = position +
1603             (gotPositive ? positiveSuffix.length() : negativeSuffix.length()); // mark success!
1604         } else {
1605             parsePosition.index = position;
1606         }
1607 
1608         status[STATUS_POSITIVE] = gotPositive;
1609         if (parsePosition.index == oldStart) {
1610             parsePosition.errorIndex = position;
1611             return false;
1612         }
1613         return true;
1614     }
1615 
1616     /**
1617      * Returns a copy of the decimal format symbols, which is generally not
1618      * changed by the programmer or user.
1619      * @return a copy of the desired DecimalFormatSymbols
1620      * @see java.text.DecimalFormatSymbols
1621      */
1622     public DecimalFormatSymbols getDecimalFormatSymbols() {
1623         try {
1624             // don't allow multiple references
1625             return (DecimalFormatSymbols) symbols.clone();
1626         } catch (Exception foo) {
1627             return null; // should never happen
1628         }
1629     }
1630 
1631 
1632     /**
1633      * Sets the decimal format symbols, which is generally not changed
1634      * by the programmer or user.
1635      * @param newSymbols desired DecimalFormatSymbols
1636      * @see java.text.DecimalFormatSymbols
1637      */
1638     public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
1639         try {
1640             // don't allow multiple references
1641             symbols = (DecimalFormatSymbols) newSymbols.clone();
1642             expandAffixes();
1643         } catch (Exception foo) {
1644             // should never happen
1645         }
1646     }
1647 
1648     /**
1649      * Get the positive prefix.
1650      * <P>Examples: +123, $123, sFr123
1651      */
1652     public String getPositivePrefix () {
1653         return positivePrefix;
1654     }
1655 
1656     /**
1657      * Set the positive prefix.
1658      * <P>Examples: +123, $123, sFr123
1659      */
1660     public void setPositivePrefix (String newValue) {
1661         positivePrefix = newValue;
1662         posPrefixPattern = null;
1663         positivePrefixFieldPositions = null;
1664     }
1665 
1666     /**
1667      * Returns the FieldPositions of the fields in the prefix used for
1668      * positive numbers. This is not used if the user has explicitly set
1669      * a positive prefix via <code>setPositivePrefix</code>. This is
1670      * lazily created.
1671      *
1672      * @return FieldPositions in positive prefix
1673      */
1674     private FieldPosition[] getPositivePrefixFieldPositions() {
1675         if (positivePrefixFieldPositions == null) {
1676             if (posPrefixPattern != null) {
1677                 positivePrefixFieldPositions = expandAffix(posPrefixPattern);
1678             }
1679             else {
1680                 positivePrefixFieldPositions = EmptyFieldPositionArray;
1681             }
1682         }
1683         return positivePrefixFieldPositions;
1684     }
1685 
1686     /**
1687      * Get the negative prefix.
1688      * <P>Examples: -123, ($123) (with negative suffix), sFr-123
1689      */
1690     public String getNegativePrefix () {
1691         return negativePrefix;
1692     }
1693 
1694     /**
1695      * Set the negative prefix.
1696      * <P>Examples: -123, ($123) (with negative suffix), sFr-123
1697      */
1698     public void setNegativePrefix (String newValue) {
1699         negativePrefix = newValue;
1700         negPrefixPattern = null;
1701     }
1702 
1703     /**
1704      * Returns the FieldPositions of the fields in the prefix used for
1705      * negative numbers. This is not used if the user has explicitly set
1706      * a negative prefix via <code>setNegativePrefix</code>. This is
1707      * lazily created.
1708      *
1709      * @return FieldPositions in positive prefix
1710      */
1711     private FieldPosition[] getNegativePrefixFieldPositions() {
1712         if (negativePrefixFieldPositions == null) {
1713             if (negPrefixPattern != null) {
1714                 negativePrefixFieldPositions = expandAffix(negPrefixPattern);
1715             }
1716             else {
1717                 negativePrefixFieldPositions = EmptyFieldPositionArray;
1718             }
1719         }
1720         return negativePrefixFieldPositions;
1721     }
1722 
1723     /**
1724      * Get the positive suffix.
1725      * <P>Example: 123%
1726      */
1727     public String getPositiveSuffix () {
1728         return positiveSuffix;
1729     }
1730 
1731     /**
1732      * Set the positive suffix.
1733      * <P>Example: 123%
1734      */
1735     public void setPositiveSuffix (String newValue) {
1736         positiveSuffix = newValue;
1737         posSuffixPattern = null;
1738     }
1739 
1740     /**
1741      * Returns the FieldPositions of the fields in the suffix used for
1742      * positive numbers. This is not used if the user has explicitly set
1743      * a positive suffix via <code>setPositiveSuffix</code>. This is
1744      * lazily created.
1745      *
1746      * @return FieldPositions in positive prefix
1747      */
1748     private FieldPosition[] getPositiveSuffixFieldPositions() {
1749         if (positiveSuffixFieldPositions == null) {
1750             if (posSuffixPattern != null) {
1751                 positiveSuffixFieldPositions = expandAffix(posSuffixPattern);
1752             }
1753             else {
1754                 positiveSuffixFieldPositions = EmptyFieldPositionArray;
1755             }
1756         }
1757         return positiveSuffixFieldPositions;
1758     }
1759 
1760     /**
1761      * Get the negative suffix.
1762      * <P>Examples: -123%, ($123) (with positive suffixes)
1763      */
1764     public String getNegativeSuffix () {
1765         return negativeSuffix;
1766     }
1767 
1768     /**
1769      * Set the negative suffix.
1770      * <P>Examples: 123%
1771      */
1772     public void setNegativeSuffix (String newValue) {
1773         negativeSuffix = newValue;
1774         negSuffixPattern = null;
1775     }
1776 
1777     /**
1778      * Returns the FieldPositions of the fields in the suffix used for
1779      * negative numbers. This is not used if the user has explicitly set
1780      * a negative suffix via <code>setNegativeSuffix</code>. This is
1781      * lazily created.
1782      *
1783      * @return FieldPositions in positive prefix
1784      */
1785     private FieldPosition[] getNegativeSuffixFieldPositions() {
1786         if (negativeSuffixFieldPositions == null) {
1787             if (negSuffixPattern != null) {
1788                 negativeSuffixFieldPositions = expandAffix(negSuffixPattern);
1789             }
1790             else {
1791                 negativeSuffixFieldPositions = EmptyFieldPositionArray;
1792             }
1793         }
1794         return negativeSuffixFieldPositions;
1795     }
1796 
1797     /**
1798      * Gets the multiplier for use in percent, per mille, and similar
1799      * formats.
1800      *
1801      * @see #setMultiplier(int)
1802      */
1803     public int getMultiplier () {
1804         return multiplier;
1805     }
1806 
1807     /**
1808      * Sets the multiplier for use in percent, per mille, and similar
1809      * formats.
1810      * For a percent format, set the multiplier to 100 and the suffixes to
1811      * have '%' (for Arabic, use the Arabic percent sign).
1812      * For a per mille format, set the multiplier to 1000 and the suffixes to
1813      * have '&#92;u2030'.
1814      *
1815      * <P>Example: with multiplier 100, 1.23 is formatted as "123", and
1816      * "123" is parsed into 1.23.
1817      *
1818      * @see #getMultiplier
1819      */
1820     public void setMultiplier (int newValue) {
1821         multiplier = newValue;
1822         bigDecimalMultiplier = null;
1823         bigIntegerMultiplier = null;
1824     }
1825 
1826     /**
1827      * Return the grouping size. Grouping size is the number of digits between
1828      * grouping separators in the integer portion of a number.  For example,
1829      * in the number "123,456.78", the grouping size is 3.
1830      * @see #setGroupingSize
1831      * @see java.text.NumberFormat#isGroupingUsed
1832      * @see java.text.DecimalFormatSymbols#getGroupingSeparator
1833      */
1834     public int getGroupingSize () {
1835         return groupingSize;
1836     }
1837 
1838     /**
1839      * Set the grouping size. Grouping size is the number of digits between
1840      * grouping separators in the integer portion of a number.  For example,
1841      * in the number "123,456.78", the grouping size is 3.
1842      * <br>
1843      * The value passed in is converted to a byte, which may lose information.
1844      * @see #getGroupingSize
1845      * @see java.text.NumberFormat#setGroupingUsed
1846      * @see java.text.DecimalFormatSymbols#setGroupingSeparator
1847      */
1848     public void setGroupingSize (int newValue) {
1849         groupingSize = (byte)newValue;
1850     }
1851 
1852     /**
1853      * Allows you to get the behavior of the decimal separator with integers.
1854      * (The decimal separator will always appear with decimals.)
1855      * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
1856      */
1857     public boolean isDecimalSeparatorAlwaysShown() {
1858         return decimalSeparatorAlwaysShown;
1859     }
1860 
1861     /**
1862      * Allows you to set the behavior of the decimal separator with integers.
1863      * (The decimal separator will always appear with decimals.)
1864      * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
1865      */
1866     public void setDecimalSeparatorAlwaysShown(boolean newValue) {
1867         decimalSeparatorAlwaysShown = newValue;
1868     }
1869 
1870     /**
1871      * Returns whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1872      * method returns <code>BigDecimal</code>. The default value is false.
1873      * @see #setParseBigDecimal
1874      * @since 1.5
1875      */
1876     public boolean isParseBigDecimal() {
1877         return parseBigDecimal;
1878     }
1879 
1880     /**
1881      * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1882      * method returns <code>BigDecimal</code>.
1883      * @see #isParseBigDecimal
1884      * @since 1.5
1885      */
1886     public void setParseBigDecimal(boolean newValue) {
1887         parseBigDecimal = newValue;
1888     }
1889 
1890     /**
1891      * Standard override; no change in semantics.
1892      */
1893     public Object clone() {
1894         DecimalFormat other = (DecimalFormat) super.clone();
1895         other.symbols = (DecimalFormatSymbols) symbols.clone();
1896         other.digitList = (DigitList) digitList.clone();
1897         return other;
1898     }
1899 
1900     /**
1901      * Overrides equals
1902      */
1903     public boolean equals(Object obj)
1904     {
1905         if (obj == null) return false;
1906         if (!super.equals(obj)) return false; // super does class check
1907         DecimalFormat other = (DecimalFormat) obj;
1908         return ((posPrefixPattern == other.posPrefixPattern &&
1909                  positivePrefix.equals(other.positivePrefix))
1910                 || (posPrefixPattern != null &&
1911                     posPrefixPattern.equals(other.posPrefixPattern)))
1912             && ((posSuffixPattern == other.posSuffixPattern &&
1913                  positiveSuffix.equals(other.positiveSuffix))
1914                 || (posSuffixPattern != null &&
1915                     posSuffixPattern.equals(other.posSuffixPattern)))
1916             && ((negPrefixPattern == other.negPrefixPattern &&
1917                  negativePrefix.equals(other.negativePrefix))
1918                 || (negPrefixPattern != null &&
1919                     negPrefixPattern.equals(other.negPrefixPattern)))
1920             && ((negSuffixPattern == other.negSuffixPattern &&
1921                  negativeSuffix.equals(other.negativeSuffix))
1922                 || (negSuffixPattern != null &&
1923                     negSuffixPattern.equals(other.negSuffixPattern)))
1924             && multiplier == other.multiplier
1925             && groupingSize == other.groupingSize
1926             && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown
1927             && parseBigDecimal == other.parseBigDecimal
1928             && useExponentialNotation == other.useExponentialNotation
1929             && (!useExponentialNotation ||
1930                 minExponentDigits == other.minExponentDigits)
1931             && maximumIntegerDigits == other.maximumIntegerDigits
1932             && minimumIntegerDigits == other.minimumIntegerDigits
1933             && maximumFractionDigits == other.maximumFractionDigits
1934             && minimumFractionDigits == other.minimumFractionDigits
1935             && roundingMode == other.roundingMode
1936             && symbols.equals(other.symbols);
1937     }
1938 
1939     /**
1940      * Overrides hashCode
1941      */
1942     public int hashCode() {
1943         return super.hashCode() * 37 + positivePrefix.hashCode();
1944         // just enough fields for a reasonable distribution
1945     }
1946 
1947     /**
1948      * Synthesizes a pattern string that represents the current state
1949      * of this Format object.
1950      * @see #applyPattern
1951      */
1952     public String toPattern() {
1953         return toPattern( false );
1954     }
1955 
1956     /**
1957      * Synthesizes a localized pattern string that represents the current
1958      * state of this Format object.
1959      * @see #applyPattern
1960      */
1961     public String toLocalizedPattern() {
1962         return toPattern( true );
1963     }
1964 
1965     /**
1966      * Expand the affix pattern strings into the expanded affix strings.  If any
1967      * affix pattern string is null, do not expand it.  This method should be
1968      * called any time the symbols or the affix patterns change in order to keep
1969      * the expanded affix strings up to date.
1970      */
1971     private void expandAffixes() {
1972         // Reuse one StringBuffer for better performance
1973         StringBuffer buffer = new StringBuffer();
1974         if (posPrefixPattern != null) {
1975             positivePrefix = expandAffix(posPrefixPattern, buffer);
1976             positivePrefixFieldPositions = null;
1977         }
1978         if (posSuffixPattern != null) {
1979             positiveSuffix = expandAffix(posSuffixPattern, buffer);
1980             positiveSuffixFieldPositions = null;
1981         }
1982         if (negPrefixPattern != null) {
1983             negativePrefix = expandAffix(negPrefixPattern, buffer);
1984             negativePrefixFieldPositions = null;
1985         }
1986         if (negSuffixPattern != null) {
1987             negativeSuffix = expandAffix(negSuffixPattern, buffer);
1988             negativeSuffixFieldPositions = null;
1989         }
1990     }
1991 
1992     /**
1993      * Expand an affix pattern into an affix string.  All characters in the
1994      * pattern are literal unless prefixed by QUOTE.  The following characters
1995      * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
1996      * PATTERN_MINUS, and CURRENCY_SIGN.  If CURRENCY_SIGN is doubled (QUOTE +
1997      * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
1998      * currency code.  Any other character after a QUOTE represents itself.
1999      * QUOTE must be followed by another character; QUOTE may not occur by
2000      * itself at the end of the pattern.
2001      *
2002      * @param pattern the non-null, possibly empty pattern
2003      * @param buffer a scratch StringBuffer; its contents will be lost
2004      * @return the expanded equivalent of pattern
2005      */
2006     private String expandAffix(String pattern, StringBuffer buffer) {
2007         buffer.setLength(0);
2008         for (int i=0; i<pattern.length(); ) {
2009             char c = pattern.charAt(i++);
2010             if (c == QUOTE) {
2011                 c = pattern.charAt(i++);
2012                 switch (c) {
2013                 case CURRENCY_SIGN:
2014                     if (i<pattern.length() &&
2015                         pattern.charAt(i) == CURRENCY_SIGN) {
2016                         ++i;
2017                         buffer.append(symbols.getInternationalCurrencySymbol());
2018                     } else {
2019                         buffer.append(symbols.getCurrencySymbol());
2020                     }
2021                     continue;
2022                 case PATTERN_PERCENT:
2023                     c = symbols.getPercent();
2024                     break;
2025                 case PATTERN_PER_MILLE:
2026                     c = symbols.getPerMill();
2027                     break;
2028                 case PATTERN_MINUS:
2029                     c = symbols.getMinusSign();
2030                     break;
2031                 }
2032             }
2033             buffer.append(c);
2034         }
2035         return buffer.toString();
2036     }
2037 
2038     /**
2039      * Expand an affix pattern into an array of FieldPositions describing
2040      * how the pattern would be expanded.
2041      * All characters in the
2042      * pattern are literal unless prefixed by QUOTE.  The following characters
2043      * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2044      * PATTERN_MINUS, and CURRENCY_SIGN.  If CURRENCY_SIGN is doubled (QUOTE +
2045      * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
2046      * currency code.  Any other character after a QUOTE represents itself.
2047      * QUOTE must be followed by another character; QUOTE may not occur by
2048      * itself at the end of the pattern.
2049      *
2050      * @param pattern the non-null, possibly empty pattern
2051      * @return FieldPosition array of the resulting fields.
2052      */
2053     private FieldPosition[] expandAffix(String pattern) {
2054         ArrayList positions = null;
2055         int stringIndex = 0;
2056         for (int i=0; i<pattern.length(); ) {
2057             char c = pattern.charAt(i++);
2058             if (c == QUOTE) {
2059                 int field = -1;
2060                 Format.Field fieldID = null;
2061                 c = pattern.charAt(i++);
2062                 switch (c) {
2063                 case CURRENCY_SIGN:
2064                     String string;
2065                     if (i<pattern.length() &&
2066                         pattern.charAt(i) == CURRENCY_SIGN) {
2067                         ++i;
2068                         string = symbols.getInternationalCurrencySymbol();
2069                     } else {
2070                         string = symbols.getCurrencySymbol();
2071                     }
2072                     if (string.length() > 0) {
2073                         if (positions == null) {
2074                             positions = new ArrayList(2);
2075                         }
2076                         FieldPosition fp = new FieldPosition(Field.CURRENCY);
2077                         fp.setBeginIndex(stringIndex);
2078                         fp.setEndIndex(stringIndex + string.length());
2079                         positions.add(fp);
2080                         stringIndex += string.length();
2081                     }
2082                     continue;
2083                 case PATTERN_PERCENT:
2084                     c = symbols.getPercent();
2085                     field = -1;
2086                     fieldID = Field.PERCENT;
2087                     break;
2088                 case PATTERN_PER_MILLE:
2089                     c = symbols.getPerMill();
2090                     field = -1;
2091                     fieldID = Field.PERMILLE;
2092                     break;
2093                 case PATTERN_MINUS:
2094                     c = symbols.getMinusSign();
2095                     field = -1;
2096                     fieldID = Field.SIGN;
2097                     break;
2098                 }
2099                 if (fieldID != null) {
2100                     if (positions == null) {
2101                         positions = new ArrayList(2);
2102                     }
2103                     FieldPosition fp = new FieldPosition(fieldID, field);
2104                     fp.setBeginIndex(stringIndex);
2105                     fp.setEndIndex(stringIndex + 1);
2106                     positions.add(fp);
2107                 }
2108             }
2109             stringIndex++;
2110         }
2111         if (positions != null) {
2112             return (FieldPosition[])positions.toArray(EmptyFieldPositionArray);
2113         }
2114         return EmptyFieldPositionArray;
2115     }
2116 
2117     /**
2118      * Appends an affix pattern to the given StringBuffer, quoting special
2119      * characters as needed.  Uses the internal affix pattern, if that exists,
2120      * or the literal affix, if the internal affix pattern is null.  The
2121      * appended string will generate the same affix pattern (or literal affix)
2122      * when passed to toPattern().
2123      *
2124      * @param buffer the affix string is appended to this
2125      * @param affixPattern a pattern such as posPrefixPattern; may be null
2126      * @param expAffix a corresponding expanded affix, such as positivePrefix.
2127      * Ignored unless affixPattern is null.  If affixPattern is null, then
2128      * expAffix is appended as a literal affix.
2129      * @param localized true if the appended pattern should contain localized
2130      * pattern characters; otherwise, non-localized pattern chars are appended
2131      */
2132     private void appendAffix(StringBuffer buffer, String affixPattern,
2133                              String expAffix, boolean localized) {
2134         if (affixPattern == null) {
2135             appendAffix(buffer, expAffix, localized);
2136         } else {
2137             int i;
2138             for (int pos=0; pos<affixPattern.length(); pos=i) {
2139                 i = affixPattern.indexOf(QUOTE, pos);
2140                 if (i < 0) {
2141                     appendAffix(buffer, affixPattern.substring(pos), localized);
2142                     break;
2143                 }
2144                 if (i > pos) {
2145                     appendAffix(buffer, affixPattern.substring(pos, i), localized);
2146                 }
2147                 char c = affixPattern.charAt(++i);
2148                 ++i;
2149                 if (c == QUOTE) {
2150                     buffer.append(c);
2151                     // Fall through and append another QUOTE below
2152                 } else if (c == CURRENCY_SIGN &&
2153                            i<affixPattern.length() &&
2154                            affixPattern.charAt(i) == CURRENCY_SIGN) {
2155                     ++i;
2156                     buffer.append(c);
2157                     // Fall through and append another CURRENCY_SIGN below
2158                 } else if (localized) {
2159                     switch (c) {
2160                     case PATTERN_PERCENT:
2161                         c = symbols.getPercent();
2162                         break;
2163                     case PATTERN_PER_MILLE:
2164                         c = symbols.getPerMill();
2165                         break;
2166                     case PATTERN_MINUS:
2167                         c = symbols.getMinusSign();
2168                         break;
2169                     }
2170                 }
2171                 buffer.append(c);
2172             }
2173         }
2174     }
2175 
2176     /**
2177      * Append an affix to the given StringBuffer, using quotes if
2178      * there are special characters.  Single quotes themselves must be
2179      * escaped in either case.
2180      */
2181     private void appendAffix(StringBuffer buffer, String affix, boolean localized) {
2182         boolean needQuote;
2183         if (localized) {
2184             needQuote = affix.indexOf(symbols.getZeroDigit()) >= 0
2185                 || affix.indexOf(symbols.getGroupingSeparator()) >= 0
2186                 || affix.indexOf(symbols.getDecimalSeparator()) >= 0
2187                 || affix.indexOf(symbols.getPercent()) >= 0
2188                 || affix.indexOf(symbols.getPerMill()) >= 0
2189                 || affix.indexOf(symbols.getDigit()) >= 0
2190                 || affix.indexOf(symbols.getPatternSeparator()) >= 0
2191                 || affix.indexOf(symbols.getMinusSign()) >= 0
2192                 || affix.indexOf(CURRENCY_SIGN) >= 0;
2193         }
2194         else {
2195             needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 0
2196                 || affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 0
2197                 || affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 0
2198                 || affix.indexOf(PATTERN_PERCENT) >= 0
2199                 || affix.indexOf(PATTERN_PER_MILLE) >= 0
2200                 || affix.indexOf(PATTERN_DIGIT) >= 0
2201                 || affix.indexOf(PATTERN_SEPARATOR) >= 0
2202                 || affix.indexOf(PATTERN_MINUS) >= 0
2203                 || affix.indexOf(CURRENCY_SIGN) >= 0;
2204         }
2205         if (needQuote) buffer.append('\'');
2206         if (affix.indexOf('\'') < 0) buffer.append(affix);
2207         else {
2208             for (int j=0; j<affix.length(); ++j) {
2209                 char c = affix.charAt(j);
2210                 buffer.append(c);
2211                 if (c == '\'') buffer.append(c);
2212             }
2213         }
2214         if (needQuote) buffer.append('\'');
2215     }
2216 
2217     /**
2218      * Does the real work of generating a pattern.  */
2219     private String toPattern(boolean localized) {
2220         StringBuffer result = new StringBuffer();
2221         for (int j = 1; j >= 0; --j) {
2222             if (j == 1)
2223                 appendAffix(result, posPrefixPattern, positivePrefix, localized);
2224             else appendAffix(result, negPrefixPattern, negativePrefix, localized);
2225             int i;
2226             int digitCount = useExponentialNotation
2227                         ? getMaximumIntegerDigits()
2228                         : Math.max(groupingSize, getMinimumIntegerDigits())+1;
2229             for (i = digitCount; i > 0; --i) {
2230                 if (i != digitCount && isGroupingUsed() && groupingSize != 0 &&
2231                     i % groupingSize == 0) {
2232                     result.append(localized ? symbols.getGroupingSeparator() :
2233                                   PATTERN_GROUPING_SEPARATOR);
2234                 }
2235                 result.append(i <= getMinimumIntegerDigits()
2236                     ? (localized ? symbols.getZeroDigit() : PATTERN_ZERO_DIGIT)
2237                     : (localized ? symbols.getDigit() : PATTERN_DIGIT));
2238             }
2239             if (getMaximumFractionDigits() > 0 || decimalSeparatorAlwaysShown)
2240                 result.append(localized ? symbols.getDecimalSeparator() :
2241                               PATTERN_DECIMAL_SEPARATOR);
2242             for (i = 0; i < getMaximumFractionDigits(); ++i) {
2243                 if (i < getMinimumFractionDigits()) {
2244                     result.append(localized ? symbols.getZeroDigit() :
2245                                   PATTERN_ZERO_DIGIT);
2246                 } else {
2247                     result.append(localized ? symbols.getDigit() :
2248                                   PATTERN_DIGIT);
2249                 }
2250             }
2251         if (useExponentialNotation)
2252         {
2253             result.append(localized ? symbols.getExponentSeparator() :
2254                   PATTERN_EXPONENT);
2255         for (i=0; i<minExponentDigits; ++i)
2256                     result.append(localized ? symbols.getZeroDigit() :
2257                                   PATTERN_ZERO_DIGIT);
2258         }
2259             if (j == 1) {
2260                 appendAffix(result, posSuffixPattern, positiveSuffix, localized);
2261                 if ((negSuffixPattern == posSuffixPattern && // n == p == null
2262                      negativeSuffix.equals(positiveSuffix))
2263                     || (negSuffixPattern != null &&
2264                         negSuffixPattern.equals(posSuffixPattern))) {
2265                     if ((negPrefixPattern != null && posPrefixPattern != null &&
2266                          negPrefixPattern.equals("'-" + posPrefixPattern)) ||
2267                         (negPrefixPattern == posPrefixPattern && // n == p == null
2268                          negativePrefix.equals(symbols.getMinusSign() + positivePrefix)))
2269                         break;
2270                 }
2271                 result.append(localized ? symbols.getPatternSeparator() :
2272                               PATTERN_SEPARATOR);
2273             } else appendAffix(result, negSuffixPattern, negativeSuffix, localized);
2274         }
2275         return result.toString();
2276     }
2277 
2278     /**
2279      * Apply the given pattern to this Format object.  A pattern is a
2280      * short-hand specification for the various formatting properties.
2281      * These properties can also be changed individually through the
2282      * various setter methods.
2283      * <p>
2284      * There is no limit to integer digits set
2285      * by this routine, since that is the typical end-user desire;
2286      * use setMaximumInteger if you want to set a real value.
2287      * For negative numbers, use a second pattern, separated by a semicolon
2288      * <P>Example <code>"#,#00.0#"</code> -> 1,234.56
2289      * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
2290      * a maximum of 2 fraction digits.
2291      * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
2292      * parentheses.
2293      * <p>In negative patterns, the minimum and maximum counts are ignored;
2294      * these are presumed to be set in the positive pattern.
2295      *
2296      * @exception NullPointerException if <code>pattern</code> is null
2297      * @exception IllegalArgumentException if the given pattern is invalid.
2298      */
2299     public void applyPattern(String pattern) {
2300         applyPattern(pattern, false);
2301     }
2302 
2303     /**
2304      * Apply the given pattern to this Format object.  The pattern
2305      * is assumed to be in a localized notation. A pattern is a
2306      * short-hand specification for the various formatting properties.
2307      * These properties can also be changed individually through the
2308      * various setter methods.
2309      * <p>
2310      * There is no limit to integer digits set
2311      * by this routine, since that is the typical end-user desire;
2312      * use setMaximumInteger if you want to set a real value.
2313      * For negative numbers, use a second pattern, separated by a semicolon
2314      * <P>Example <code>"#,#00.0#"</code> -> 1,234.56
2315      * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
2316      * a maximum of 2 fraction digits.
2317      * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
2318      * parentheses.
2319      * <p>In negative patterns, the minimum and maximum counts are ignored;
2320      * these are presumed to be set in the positive pattern.
2321      *
2322      * @exception NullPointerException if <code>pattern</code> is null
2323      * @exception IllegalArgumentException if the given pattern is invalid.
2324      */
2325     public void applyLocalizedPattern(String pattern) {
2326         applyPattern(pattern, true);
2327     }
2328 
2329     /**
2330      * Does the real work of applying a pattern.
2331      */
2332     private void applyPattern(String pattern, boolean localized) {
2333         char zeroDigit         = PATTERN_ZERO_DIGIT;
2334         char groupingSeparator = PATTERN_GROUPING_SEPARATOR;
2335         char decimalSeparator  = PATTERN_DECIMAL_SEPARATOR;
2336         char percent           = PATTERN_PERCENT;
2337         char perMill           = PATTERN_PER_MILLE;
2338         char digit             = PATTERN_DIGIT;
2339         char separator         = PATTERN_SEPARATOR;
2340         String exponent          = PATTERN_EXPONENT;
2341         char minus             = PATTERN_MINUS;
2342         if (localized) {
2343             zeroDigit         = symbols.getZeroDigit();
2344             groupingSeparator = symbols.getGroupingSeparator();
2345             decimalSeparator  = symbols.getDecimalSeparator();
2346             percent           = symbols.getPercent();
2347             perMill           = symbols.getPerMill();
2348             digit             = symbols.getDigit();
2349             separator         = symbols.getPatternSeparator();
2350             exponent          = symbols.getExponentSeparator();
2351             minus             = symbols.getMinusSign();
2352         }
2353         boolean gotNegative = false;
2354         decimalSeparatorAlwaysShown = false;
2355         isCurrencyFormat = false;
2356         useExponentialNotation = false;
2357 
2358         // Two variables are used to record the subrange of the pattern
2359         // occupied by phase 1.  This is used during the processing of the
2360         // second pattern (the one representing negative numbers) to ensure
2361         // that no deviation exists in phase 1 between the two patterns.
2362         int phaseOneStart = 0;
2363         int phaseOneLength = 0;
2364 
2365         int start = 0;
2366         for (int j = 1; j >= 0 && start < pattern.length(); --j) {
2367             boolean inQuote = false;
2368             StringBuffer prefix = new StringBuffer();
2369             StringBuffer suffix = new StringBuffer();
2370             int decimalPos = -1;
2371             int multiplier = 1;
2372             int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0;
2373             byte groupingCount = -1;
2374 
2375             // The phase ranges from 0 to 2.  Phase 0 is the prefix.  Phase 1 is
2376             // the section of the pattern with digits, decimal separator,
2377             // grouping characters.  Phase 2 is the suffix.  In phases 0 and 2,
2378             // percent, per mille, and currency symbols are recognized and
2379             // translated.  The separation of the characters into phases is
2380             // strictly enforced; if phase 1 characters are to appear in the
2381             // suffix, for example, they must be quoted.
2382             int phase = 0;
2383 
2384             // The affix is either the prefix or the suffix.
2385             StringBuffer affix = prefix;
2386 
2387             for (int pos = start; pos < pattern.length(); ++pos) {
2388                 char ch = pattern.charAt(pos);
2389                 switch (phase) {
2390                 case 0:
2391                 case 2:
2392                     // Process the prefix / suffix characters
2393                     if (inQuote) {
2394                         // A quote within quotes indicates either the closing
2395                         // quote or two quotes, which is a quote literal. That
2396                         // is, we have the second quote in 'do' or 'don''t'.
2397                         if (ch == QUOTE) {
2398                             if ((pos+1) < pattern.length() &&
2399                                 pattern.charAt(pos+1) == QUOTE) {
2400                                 ++pos;
2401                                 affix.append("''"); // 'don''t'
2402                             } else {
2403                                 inQuote = false; // 'do'
2404                             }
2405                             continue;
2406                         }
2407                     } else {
2408                         // Process unquoted characters seen in prefix or suffix
2409                         // phase.
2410                         if (ch == digit ||
2411                             ch == zeroDigit ||
2412                             ch == groupingSeparator ||
2413                             ch == decimalSeparator) {
2414                             phase = 1;
2415                             if (j == 1) {
2416                                 phaseOneStart = pos;
2417                             }
2418                             --pos; // Reprocess this character
2419                             continue;
2420                         } else if (ch == CURRENCY_SIGN) {
2421                             // Use lookahead to determine if the currency sign
2422                             // is doubled or not.
2423                             boolean doubled = (pos + 1) < pattern.length() &&
2424                                 pattern.charAt(pos + 1) == CURRENCY_SIGN;
2425                             if (doubled) { // Skip over the doubled character
2426                              ++pos;
2427                             }
2428                             isCurrencyFormat = true;
2429                             affix.append(doubled ? "'\u00A4\u00A4" : "'\u00A4");
2430                             continue;
2431                         } else if (ch == QUOTE) {
2432                             // A quote outside quotes indicates either the
2433                             // opening quote or two quotes, which is a quote
2434                             // literal. That is, we have the first quote in 'do'
2435                             // or o''clock.
2436                             if (ch == QUOTE) {
2437                                 if ((pos+1) < pattern.length() &&
2438                                     pattern.charAt(pos+1) == QUOTE) {
2439                                     ++pos;
2440                                     affix.append("''"); // o''clock
2441                                 } else {
2442                                     inQuote = true; // 'do'
2443                                 }
2444                                 continue;
2445                             }
2446                         } else if (ch == separator) {
2447                             // Don't allow separators before we see digit
2448                             // characters of phase 1, and don't allow separators
2449                             // in the second pattern (j == 0).
2450                             if (phase == 0 || j == 0) {
2451                                 throw new IllegalArgumentException("Unquoted special character '" +
2452                                     ch + "' in pattern \"" + pattern + '"');
2453                             }
2454                             start = pos + 1;
2455                             pos = pattern.length();
2456                             continue;
2457                         }
2458 
2459                         // Next handle characters which are appended directly.
2460                         else if (ch == percent) {
2461                             if (multiplier != 1) {
2462                                 throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +
2463                                     pattern + '"');
2464                             }
2465                             multiplier = 100;
2466                             affix.append("'%");
2467                             continue;
2468                         } else if (ch == perMill) {
2469                             if (multiplier != 1) {
2470                                 throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +
2471                                     pattern + '"');
2472                             }
2473                             multiplier = 1000;
2474                             affix.append("'\u2030");
2475                             continue;
2476                         } else if (ch == minus) {
2477                             affix.append("'-");
2478                             continue;
2479                         }
2480                     }
2481                     // Note that if we are within quotes, or if this is an
2482                     // unquoted, non-special character, then we usually fall
2483                     // through to here.
2484                     affix.append(ch);
2485                     break;
2486 
2487                 case 1:
2488                     // Phase one must be identical in the two sub-patterns. We
2489                     // enforce this by doing a direct comparison. While
2490                     // processing the first sub-pattern, we just record its
2491                     // length. While processing the second, we compare
2492                     // characters.
2493                     if (j == 1) {
2494                         ++phaseOneLength;
2495                     } else {
2496                         if (--phaseOneLength == 0) {
2497                             phase = 2;
2498                             affix = suffix;
2499                         }
2500                         continue;
2501                     }
2502 
2503                     // Process the digits, decimal, and grouping characters. We
2504                     // record five pieces of information. We expect the digits
2505                     // to occur in the pattern ####0000.####, and we record the
2506                     // number of left digits, zero (central) digits, and right
2507                     // digits. The position of the last grouping character is
2508                     // recorded (should be somewhere within the first two blocks
2509                     // of characters), as is the position of the decimal point,
2510                     // if any (should be in the zero digits). If there is no
2511                     // decimal point, then there should be no right digits.
2512                     if (ch == digit) {
2513                         if (zeroDigitCount > 0) {
2514                             ++digitRightCount;
2515                         } else {
2516                             ++digitLeftCount;
2517                         }
2518                         if (groupingCount >= 0 && decimalPos < 0) {
2519                             ++groupingCount;
2520                         }
2521                     } else if (ch == zeroDigit) {
2522                         if (digitRightCount > 0) {
2523                             throw new IllegalArgumentException("Unexpected '0' in pattern \"" +
2524                                 pattern + '"');
2525                         }
2526                         ++zeroDigitCount;
2527                         if (groupingCount >= 0 && decimalPos < 0) {
2528                             ++groupingCount;
2529                         }
2530                     } else if (ch == groupingSeparator) {
2531                         groupingCount = 0;
2532                     } else if (ch == decimalSeparator) {
2533                         if (decimalPos >= 0) {
2534                             throw new IllegalArgumentException("Multiple decimal separators in pattern \"" +
2535                                 pattern + '"');
2536                         }
2537                         decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
2538                     } else if (pattern.regionMatches(pos, exponent, 0, exponent.length())){
2539                         if (useExponentialNotation) {
2540                             throw new IllegalArgumentException("Multiple exponential " +
2541                                 "symbols in pattern \"" + pattern + '"');
2542                         }
2543                         useExponentialNotation = true;
2544                         minExponentDigits = 0;
2545 
2546                         // Use lookahead to parse out the exponential part
2547                         // of the pattern, then jump into phase 2.
2548                         pos = pos+exponent.length();
2549                          while (pos < pattern.length() &&
2550                                pattern.charAt(pos) == zeroDigit) {
2551                             ++minExponentDigits;
2552                             ++phaseOneLength;
2553                             ++pos;
2554                         }
2555 
2556                         if ((digitLeftCount + zeroDigitCount) < 1 ||
2557                             minExponentDigits < 1) {
2558                             throw new IllegalArgumentException("Malformed exponential " +
2559                                 "pattern \"" + pattern + '"');
2560                         }
2561 
2562                         // Transition to phase 2
2563                         phase = 2;
2564                         affix = suffix;
2565                         --pos;
2566                         continue;
2567                     } else {
2568                         phase = 2;
2569                         affix = suffix;
2570                         --pos;
2571                         --phaseOneLength;
2572                         continue;
2573                     }
2574                     break;
2575                 }
2576             }
2577 
2578             // Handle patterns with no '0' pattern character. These patterns
2579             // are legal, but must be interpreted.  "##.###" -> "#0.###".
2580             // ".###" -> ".0##".
2581             /* We allow patterns of the form "####" to produce a zeroDigitCount
2582              * of zero (got that?); although this seems like it might make it
2583              * possible for format() to produce empty strings, format() checks
2584              * for this condition and outputs a zero digit in this situation.
2585              * Having a zeroDigitCount of zero yields a minimum integer digits
2586              * of zero, which allows proper round-trip patterns.  That is, we
2587              * don't want "#" to become "#0" when toPattern() is called (even
2588              * though that's what it really is, semantically).
2589              */
2590             if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {
2591                 // Handle "###.###" and "###." and ".###"
2592                 int n = decimalPos;
2593                 if (n == 0) { // Handle ".###"
2594                     ++n;
2595                 }
2596                 digitRightCount = digitLeftCount - n;
2597                 digitLeftCount = n - 1;
2598                 zeroDigitCount = 1;
2599             }
2600 
2601             // Do syntax checking on the digits.
2602             if ((decimalPos < 0 && digitRightCount > 0) ||
2603                 (decimalPos >= 0 && (decimalPos < digitLeftCount ||
2604                  decimalPos > (digitLeftCount + zeroDigitCount))) ||
2605                  groupingCount == 0 || inQuote) {
2606                 throw new IllegalArgumentException("Malformed pattern \"" +
2607                     pattern + '"');
2608             }
2609 
2610             if (j == 1) {
2611                 posPrefixPattern = prefix.toString();
2612                 posSuffixPattern = suffix.toString();
2613                 negPrefixPattern = posPrefixPattern;   // assume these for now
2614                 negSuffixPattern = posSuffixPattern;
2615                 int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
2616                 /* The effectiveDecimalPos is the position the decimal is at or
2617                  * would be at if there is no decimal. Note that if decimalPos<0,
2618                  * then digitTotalCount == digitLeftCount + zeroDigitCount.
2619                  */
2620                 int effectiveDecimalPos = decimalPos >= 0 ?
2621                     decimalPos : digitTotalCount;
2622                 setMinimumIntegerDigits(effectiveDecimalPos - digitLeftCount);
2623                 setMaximumIntegerDigits(useExponentialNotation ?
2624                     digitLeftCount + getMinimumIntegerDigits() :
2625                     MAXIMUM_INTEGER_DIGITS);
2626                 setMaximumFractionDigits(decimalPos >= 0 ?
2627                     (digitTotalCount - decimalPos) : 0);
2628                 setMinimumFractionDigits(decimalPos >= 0 ?
2629                     (digitLeftCount + zeroDigitCount - decimalPos) : 0);
2630                 setGroupingUsed(groupingCount > 0);
2631                 this.groupingSize = (groupingCount > 0) ? groupingCount : 0;
2632                 this.multiplier = multiplier;
2633                 setDecimalSeparatorAlwaysShown(decimalPos == 0 ||
2634                     decimalPos == digitTotalCount);
2635             } else {
2636                 negPrefixPattern = prefix.toString();
2637                 negSuffixPattern = suffix.toString();
2638                 gotNegative = true;
2639             }
2640         }
2641 
2642         if (pattern.length() == 0) {
2643             posPrefixPattern = posSuffixPattern = "";
2644             setMinimumIntegerDigits(0);
2645             setMaximumIntegerDigits(MAXIMUM_INTEGER_DIGITS);
2646             setMinimumFractionDigits(0);
2647             setMaximumFractionDigits(MAXIMUM_FRACTION_DIGITS);
2648         }
2649 
2650         // If there was no negative pattern, or if the negative pattern is
2651         // identical to the positive pattern, then prepend the minus sign to
2652         // the positive pattern to form the negative pattern.
2653         if (!gotNegative ||
2654             (negPrefixPattern.equals(posPrefixPattern)
2655              && negSuffixPattern.equals(posSuffixPattern))) {
2656             negSuffixPattern = posSuffixPattern;
2657             negPrefixPattern = "'-" + posPrefixPattern;
2658         }
2659 
2660         expandAffixes();
2661     }
2662 
2663     /**
2664      * Sets the maximum number of digits allowed in the integer portion of a
2665      * number.
2666      * For formatting numbers other than <code>BigInteger</code> and
2667      * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2668      * 309 is used. Negative input values are replaced with 0.
2669      * @see NumberFormat#setMaximumIntegerDigits
2670      */
2671     public void setMaximumIntegerDigits(int newValue) {
2672         maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
2673         super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2674             DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
2675         if (minimumIntegerDigits > maximumIntegerDigits) {
2676             minimumIntegerDigits = maximumIntegerDigits;
2677             super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2678                 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
2679         }
2680     }
2681 
2682     /**
2683      * Sets the minimum number of digits allowed in the integer portion of a
2684      * number.
2685      * For formatting numbers other than <code>BigInteger</code> and
2686      * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2687      * 309 is used. Negative input values are replaced with 0.
2688      * @see NumberFormat#setMinimumIntegerDigits
2689      */
2690     public void setMinimumIntegerDigits(int newValue) {
2691         minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
2692         super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2693             DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
2694         if (minimumIntegerDigits > maximumIntegerDigits) {
2695             maximumIntegerDigits = minimumIntegerDigits;
2696             super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2697                 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
2698         }
2699     }
2700 
2701     /**
2702      * Sets the maximum number of digits allowed in the fraction portion of a
2703      * number.
2704      * For formatting numbers other than <code>BigInteger</code> and
2705      * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2706      * 340 is used. Negative input values are replaced with 0.
2707      * @see NumberFormat#setMaximumFractionDigits
2708      */
2709     public void setMaximumFractionDigits(int newValue) {
2710         maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
2711         super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2712             DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
2713         if (minimumFractionDigits > maximumFractionDigits) {
2714             minimumFractionDigits = maximumFractionDigits;
2715             super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2716                 DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
2717         }
2718     }
2719 
2720     /**
2721      * Sets the minimum number of digits allowed in the fraction portion of a
2722      * number.
2723      * For formatting numbers other than <code>BigInteger</code> and
2724      * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2725      * 340 is used. Negative input values are replaced with 0.
2726      * @see NumberFormat#setMinimumFractionDigits
2727      */
2728     public void setMinimumFractionDigits(int newValue) {
2729         minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
2730         super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2731             DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
2732         if (minimumFractionDigits > maximumFractionDigits) {
2733             maximumFractionDigits = minimumFractionDigits;
2734             super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2735                 DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
2736         }
2737     }
2738 
2739     /**
2740      * Gets the maximum number of digits allowed in the integer portion of a
2741      * number.
2742      * For formatting numbers other than <code>BigInteger</code> and
2743      * <code>BigDecimal</code> objects, the lower of the return value and
2744      * 309 is used.
2745      * @see #setMaximumIntegerDigits
2746      */
2747     public int getMaximumIntegerDigits() {
2748         return maximumIntegerDigits;
2749     }
2750 
2751     /**
2752      * Gets the minimum number of digits allowed in the integer portion of a
2753      * number.
2754      * For formatting numbers other than <code>BigInteger</code> and
2755      * <code>BigDecimal</code> objects, the lower of the return value and
2756      * 309 is used.
2757      * @see #setMinimumIntegerDigits
2758      */
2759     public int getMinimumIntegerDigits() {
2760         return minimumIntegerDigits;
2761     }
2762 
2763     /**
2764      * Gets the maximum number of digits allowed in the fraction portion of a
2765      * number.
2766      * For formatting numbers other than <code>BigInteger</code> and
2767      * <code>BigDecimal</code> objects, the lower of the return value and
2768      * 340 is used.
2769      * @see #setMaximumFractionDigits
2770      */
2771     public int getMaximumFractionDigits() {
2772         return maximumFractionDigits;
2773     }
2774 
2775     /**
2776      * Gets the minimum number of digits allowed in the fraction portion of a
2777      * number.
2778      * For formatting numbers other than <code>BigInteger</code> and
2779      * <code>BigDecimal</code> objects, the lower of the return value and
2780      * 340 is used.
2781      * @see #setMinimumFractionDigits
2782      */
2783     public int getMinimumFractionDigits() {
2784         return minimumFractionDigits;
2785     }
2786 
2787     /**
2788      * Gets the currency used by this decimal format when formatting
2789      * currency values.
2790      * The currency is obtained by calling
2791      * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency}
2792      * on this number format's symbols.
2793      *
2794      * @return the currency used by this decimal format, or <code>null</code>
2795      * @since 1.4
2796      */
2797     public Currency getCurrency() {
2798         return symbols.getCurrency();
2799     }
2800 
2801     /**
2802      * Sets the currency used by this number format when formatting
2803      * currency values. This does not update the minimum or maximum
2804      * number of fraction digits used by the number format.
2805      * The currency is set by calling
2806      * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency}
2807      * on this number format's symbols.
2808      *
2809      * @param currency the new currency to be used by this decimal format
2810      * @exception NullPointerException if <code>currency</code> is null
2811      * @since 1.4
2812      */
2813     public void setCurrency(Currency currency) {
2814         if (currency != symbols.getCurrency()) {
2815             symbols.setCurrency(currency);
2816             if (isCurrencyFormat) {
2817                 expandAffixes();
2818             }
2819         }
2820     }
2821 
2822     /**
2823      * Gets the {@link java.math.RoundingMode} used in this DecimalFormat.
2824      *
2825      * @return The <code>RoundingMode</code> used for this DecimalFormat.
2826      * @see #setRoundingMode(RoundingMode)
2827      * @since 1.6
2828      */
2829     public RoundingMode getRoundingMode() {
2830         return roundingMode;
2831     }
2832 
2833     /**
2834      * Sets the {@link java.math.RoundingMode} used in this DecimalFormat.
2835      *
2836      * @param roundingMode The <code>RoundingMode</code> to be used
2837      * @see #getRoundingMode()
2838      * @exception NullPointerException if <code>roundingMode</code> is null.
2839      * @since 1.6
2840      */
2841     public void setRoundingMode(RoundingMode roundingMode) {
2842         if (roundingMode == null) {
2843             throw new NullPointerException();
2844         }
2845 
2846         this.roundingMode = roundingMode;
2847         digitList.setRoundingMode(roundingMode);
2848     }
2849 
2850     /**
2851      * Adjusts the minimum and maximum fraction digits to values that
2852      * are reasonable for the currency's default fraction digits.
2853      */
2854     void adjustForCurrencyDefaultFractionDigits() {
2855         Currency currency = symbols.getCurrency();
2856         if (currency == null) {
2857             try {
2858                 currency = Currency.getInstance(symbols.getInternationalCurrencySymbol());
2859             } catch (IllegalArgumentException e) {
2860             }
2861         }
2862         if (currency != null) {
2863             int digits = currency.getDefaultFractionDigits();
2864             if (digits != -1) {
2865                 int oldMinDigits = getMinimumFractionDigits();
2866                 // Common patterns are "#.##", "#.00", "#".
2867                 // Try to adjust all of them in a reasonable way.
2868                 if (oldMinDigits == getMaximumFractionDigits()) {
2869                     setMinimumFractionDigits(digits);
2870                     setMaximumFractionDigits(digits);
2871                 } else {
2872                     setMinimumFractionDigits(Math.min(digits, oldMinDigits));
2873                     setMaximumFractionDigits(digits);
2874                 }
2875             }
2876         }
2877     }
2878 
2879     /**
2880      * Reads the default serializable fields from the stream and performs
2881      * validations and adjustments for older serialized versions. The
2882      * validations and adjustments are:
2883      * <ol>
2884      * <li>
2885      * Verify that the superclass's digit count fields correctly reflect
2886      * the limits imposed on formatting numbers other than
2887      * <code>BigInteger</code> and <code>BigDecimal</code> objects. These
2888      * limits are stored in the superclass for serialization compatibility
2889      * with older versions, while the limits for <code>BigInteger</code> and
2890      * <code>BigDecimal</code> objects are kept in this class.
2891      * If, in the superclass, the minimum or maximum integer digit count is
2892      * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or
2893      * maximum fraction digit count is larger than
2894      * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid
2895      * and this method throws an <code>InvalidObjectException</code>.
2896      * <li>
2897      * If <code>serialVersionOnStream</code> is less than 4, initialize
2898      * <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN
2899      * RoundingMode.HALF_EVEN}.  This field is new with version 4.
2900      * <li>
2901      * If <code>serialVersionOnStream</code> is less than 3, then call
2902      * the setters for the minimum and maximum integer and fraction digits with
2903      * the values of the corresponding superclass getters to initialize the
2904      * fields in this class. The fields in this class are new with version 3.
2905      * <li>
2906      * If <code>serialVersionOnStream</code> is less than 1, indicating that
2907      * the stream was written by JDK 1.1, initialize
2908      * <code>useExponentialNotation</code>
2909      * to false, since it was not present in JDK 1.1.
2910      * <li>
2911      * Set <code>serialVersionOnStream</code> to the maximum allowed value so
2912      * that default serialization will work properly if this object is streamed
2913      * out again.
2914      * </ol>
2915      *
2916      * <p>Stream versions older than 2 will not have the affix pattern variables
2917      * <code>posPrefixPattern</code> etc.  As a result, they will be initialized
2918      * to <code>null</code>, which means the affix strings will be taken as
2919      * literal values.  This is exactly what we want, since that corresponds to
2920      * the pre-version-2 behavior.
2921      */
2922     private void readObject(ObjectInputStream stream)
2923          throws IOException, ClassNotFoundException
2924     {
2925         stream.defaultReadObject();
2926         digitList = new DigitList();
2927 
2928         if (serialVersionOnStream < 4) {
2929             setRoundingMode(RoundingMode.HALF_EVEN);
2930         }
2931         // We only need to check the maximum counts because NumberFormat
2932         // .readObject has already ensured that the maximum is greater than the
2933         // minimum count.
2934         if (super.getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS ||
2935             super.getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {
2936             throw new InvalidObjectException("Digit count out of range");
2937         }
2938         if (serialVersionOnStream < 3) {
2939             setMaximumIntegerDigits(super.getMaximumIntegerDigits());
2940             setMinimumIntegerDigits(super.getMinimumIntegerDigits());
2941             setMaximumFractionDigits(super.getMaximumFractionDigits());
2942             setMinimumFractionDigits(super.getMinimumFractionDigits());
2943         }
2944         if (serialVersionOnStream < 1) {
2945             // Didn't have exponential fields
2946             useExponentialNotation = false;
2947         }
2948         serialVersionOnStream = currentSerialVersion;
2949     }
2950 
2951     //----------------------------------------------------------------------
2952     // INSTANCE VARIABLES
2953     //----------------------------------------------------------------------
2954 
2955     private transient DigitList digitList = new DigitList();
2956 
2957     /**
2958      * The symbol used as a prefix when formatting positive numbers, e.g. "+".
2959      *
2960      * @serial
2961      * @see #getPositivePrefix
2962      */
2963     private String  positivePrefix = "";
2964 
2965     /**
2966      * The symbol used as a suffix when formatting positive numbers.
2967      * This is often an empty string.
2968      *
2969      * @serial
2970      * @see #getPositiveSuffix
2971      */
2972     private String  positiveSuffix = "";
2973 
2974     /**
2975      * The symbol used as a prefix when formatting negative numbers, e.g. "-".
2976      *
2977      * @serial
2978      * @see #getNegativePrefix
2979      */
2980     private String  negativePrefix = "-";
2981 
2982     /**
2983      * The symbol used as a suffix when formatting negative numbers.
2984      * This is often an empty string.
2985      *
2986      * @serial
2987      * @see #getNegativeSuffix
2988      */
2989     private String  negativeSuffix = "";
2990 
2991     /**
2992      * The prefix pattern for non-negative numbers.  This variable corresponds
2993      * to <code>positivePrefix</code>.
2994      *
2995      * <p>This pattern is expanded by the method <code>expandAffix()</code> to
2996      * <code>positivePrefix</code> to update the latter to reflect changes in
2997      * <code>symbols</code>.  If this variable is <code>null</code> then
2998      * <code>positivePrefix</code> is taken as a literal value that does not
2999      * change when <code>symbols</code> changes.  This variable is always
3000      * <code>null</code> for <code>DecimalFormat</code> objects older than
3001      * stream version 2 restored from stream.
3002      *
3003      * @serial
3004      * @since 1.3
3005      */
3006     private String posPrefixPattern;
3007 
3008     /**
3009      * The suffix pattern for non-negative numbers.  This variable corresponds
3010      * to <code>positiveSuffix</code>.  This variable is analogous to
3011      * <code>posPrefixPattern</code>; see that variable for further
3012      * documentation.
3013      *
3014      * @serial
3015      * @since 1.3
3016      */
3017     private String posSuffixPattern;
3018 
3019     /**
3020      * The prefix pattern for negative numbers.  This variable corresponds
3021      * to <code>negativePrefix</code>.  This variable is analogous to
3022      * <code>posPrefixPattern</code>; see that variable for further
3023      * documentation.
3024      *
3025      * @serial
3026      * @since 1.3
3027      */
3028     private String negPrefixPattern;
3029 
3030     /**
3031      * The suffix pattern for negative numbers.  This variable corresponds
3032      * to <code>negativeSuffix</code>.  This variable is analogous to
3033      * <code>posPrefixPattern</code>; see that variable for further
3034      * documentation.
3035      *
3036      * @serial
3037      * @since 1.3
3038      */
3039     private String negSuffixPattern;
3040 
3041     /**
3042      * The multiplier for use in percent, per mille, etc.
3043      *
3044      * @serial
3045      * @see #getMultiplier
3046      */
3047     private int     multiplier = 1;
3048 
3049     /**
3050      * The number of digits between grouping separators in the integer
3051      * portion of a number.  Must be greater than 0 if
3052      * <code>NumberFormat.groupingUsed</code> is true.
3053      *
3054      * @serial
3055      * @see #getGroupingSize
3056      * @see java.text.NumberFormat#isGroupingUsed
3057      */
3058     private byte    groupingSize = 3;  // invariant, > 0 if useThousands
3059 
3060     /**
3061      * If true, forces the decimal separator to always appear in a formatted
3062      * number, even if the fractional part of the number is zero.
3063      *
3064      * @serial
3065      * @see #isDecimalSeparatorAlwaysShown
3066      */
3067     private boolean decimalSeparatorAlwaysShown = false;
3068 
3069     /**
3070      * If true, parse returns BigDecimal wherever possible.
3071      *
3072      * @serial
3073      * @see #isParseBigDecimal
3074      * @since 1.5
3075      */
3076     private boolean parseBigDecimal = false;
3077 
3078 
3079     /**
3080      * True if this object represents a currency format.  This determines
3081      * whether the monetary decimal separator is used instead of the normal one.
3082      */
3083     private transient boolean isCurrencyFormat = false;
3084 
3085     /**
3086      * The <code>DecimalFormatSymbols</code> object used by this format.
3087      * It contains the symbols used to format numbers, e.g. the grouping separator,
3088      * decimal separator, and so on.
3089      *
3090      * @serial
3091      * @see #setDecimalFormatSymbols
3092      * @see java.text.DecimalFormatSymbols
3093      */
3094     private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols();
3095 
3096     /**
3097      * True to force the use of exponential (i.e. scientific) notation when formatting
3098      * numbers.
3099      *
3100      * @serial
3101      * @since 1.2
3102      */
3103     private boolean useExponentialNotation;  // Newly persistent in the Java 2 platform v.1.2
3104 
3105     /**
3106      * FieldPositions describing the positive prefix String. This is
3107      * lazily created. Use <code>getPositivePrefixFieldPositions</code>
3108      * when needed.
3109      */
3110     private transient FieldPosition[] positivePrefixFieldPositions;
3111 
3112     /**
3113      * FieldPositions describing the positive suffix String. This is
3114      * lazily created. Use <code>getPositiveSuffixFieldPositions</code>
3115      * when needed.
3116      */
3117     private transient FieldPosition[] positiveSuffixFieldPositions;
3118 
3119     /**
3120      * FieldPositions describing the negative prefix String. This is
3121      * lazily created. Use <code>getNegativePrefixFieldPositions</code>
3122      * when needed.
3123      */
3124     private transient FieldPosition[] negativePrefixFieldPositions;
3125 
3126     /**
3127      * FieldPositions describing the negative suffix String. This is
3128      * lazily created. Use <code>getNegativeSuffixFieldPositions</code>
3129      * when needed.
3130      */
3131     private transient FieldPosition[] negativeSuffixFieldPositions;
3132 
3133     /**
3134      * The minimum number of digits used to display the exponent when a number is
3135      * formatted in exponential notation.  This field is ignored if
3136      * <code>useExponentialNotation</code> is not true.
3137      *
3138      * @serial
3139      * @since 1.2
3140      */
3141     private byte    minExponentDigits;       // Newly persistent in the Java 2 platform v.1.2
3142 
3143     /**
3144      * The maximum number of digits allowed in the integer portion of a
3145      * <code>BigInteger</code> or <code>BigDecimal</code> number.
3146      * <code>maximumIntegerDigits</code> must be greater than or equal to
3147      * <code>minimumIntegerDigits</code>.
3148      *
3149      * @serial
3150      * @see #getMaximumIntegerDigits
3151      * @since 1.5
3152      */
3153     private int    maximumIntegerDigits = super.getMaximumIntegerDigits();
3154 
3155     /**
3156      * The minimum number of digits allowed in the integer portion of a
3157      * <code>BigInteger</code> or <code>BigDecimal</code> number.
3158      * <code>minimumIntegerDigits</code> must be less than or equal to
3159      * <code>maximumIntegerDigits</code>.
3160      *
3161      * @serial
3162      * @see #getMinimumIntegerDigits
3163      * @since 1.5
3164      */
3165     private int    minimumIntegerDigits = super.getMinimumIntegerDigits();
3166 
3167     /**
3168      * The maximum number of digits allowed in the fractional portion of a
3169      * <code>BigInteger</code> or <code>BigDecimal</code> number.
3170      * <code>maximumFractionDigits</code> must be greater than or equal to
3171      * <code>minimumFractionDigits</code>.
3172      *
3173      * @serial
3174      * @see #getMaximumFractionDigits
3175      * @since 1.5
3176      */
3177     private int    maximumFractionDigits = super.getMaximumFractionDigits();
3178 
3179     /**
3180      * The minimum number of digits allowed in the fractional portion of a
3181      * <code>BigInteger</code> or <code>BigDecimal</code> number.
3182      * <code>minimumFractionDigits</code> must be less than or equal to
3183      * <code>maximumFractionDigits</code>.
3184      *
3185      * @serial
3186      * @see #getMinimumFractionDigits
3187      * @since 1.5
3188      */
3189     private int    minimumFractionDigits = super.getMinimumFractionDigits();
3190 
3191     /**
3192      * The {@link java.math.RoundingMode} used in this DecimalFormat.
3193      *
3194      * @serial
3195      * @since 1.6
3196      */
3197     private RoundingMode roundingMode = RoundingMode.HALF_EVEN;
3198 
3199     //----------------------------------------------------------------------
3200 
3201     static final int currentSerialVersion = 4;
3202 
3203     /**
3204      * The internal serial version which says which version was written.
3205      * Possible values are:
3206      * <ul>
3207      * <li><b>0</b> (default): versions before the Java 2 platform v1.2
3208      * <li><b>1</b>: version for 1.2, which includes the two new fields
3209      *      <code>useExponentialNotation</code> and
3210      *      <code>minExponentDigits</code>.
3211      * <li><b>2</b>: version for 1.3 and later, which adds four new fields:
3212      *      <code>posPrefixPattern</code>, <code>posSuffixPattern</code>,
3213      *      <code>negPrefixPattern</code>, and <code>negSuffixPattern</code>.
3214      * <li><b>3</b>: version for 1.5 and later, which adds five new fields:
3215      *      <code>maximumIntegerDigits</code>,
3216      *      <code>minimumIntegerDigits</code>,
3217      *      <code>maximumFractionDigits</code>,
3218      *      <code>minimumFractionDigits</code>, and
3219      *      <code>parseBigDecimal</code>.
3220      * <li><b>4</b>: version for 1.6 and later, which adds one new field:
3221      *      <code>roundingMode</code>.
3222      * </ul>
3223      * @since 1.2
3224      * @serial
3225      */
3226     private int serialVersionOnStream = currentSerialVersion;
3227 
3228     //----------------------------------------------------------------------
3229     // CONSTANTS
3230     //----------------------------------------------------------------------
3231 
3232     // Constants for characters used in programmatic (unlocalized) patterns.
3233     private static final char       PATTERN_ZERO_DIGIT         = '0';
3234     private static final char       PATTERN_GROUPING_SEPARATOR = ',';
3235     private static final char       PATTERN_DECIMAL_SEPARATOR  = '.';
3236     private static final char       PATTERN_PER_MILLE          = '\u2030';
3237     private static final char       PATTERN_PERCENT            = '%';
3238     private static final char       PATTERN_DIGIT              = '#';
3239     private static final char       PATTERN_SEPARATOR          = ';';
3240     private static final String     PATTERN_EXPONENT           = "E";
3241     private static final char       PATTERN_MINUS              = '-';
3242 
3243     /**
3244      * The CURRENCY_SIGN is the standard Unicode symbol for currency.  It
3245      * is used in patterns and substituted with either the currency symbol,
3246      * or if it is doubled, with the international currency symbol.  If the
3247      * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
3248      * replaced with the monetary decimal separator.
3249      *
3250      * The CURRENCY_SIGN is not localized.
3251      */
3252     private static final char       CURRENCY_SIGN = '\u00A4';
3253 
3254     private static final char       QUOTE = '\'';
3255 
3256     private static FieldPosition[] EmptyFieldPositionArray = new FieldPosition[0];
3257 
3258     // Upper limit on integer and fraction digits for a Java double
3259     static final int DOUBLE_INTEGER_DIGITS  = 309;
3260     static final int DOUBLE_FRACTION_DIGITS = 340;
3261 
3262     // Upper limit on integer and fraction digits for BigDecimal and BigInteger
3263     static final int MAXIMUM_INTEGER_DIGITS  = Integer.MAX_VALUE;
3264     static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE;
3265 
3266     // Proclaim JDK 1.1 serial compatibility.
3267     static final long serialVersionUID = 864413376551465018L;
3268 
3269     /**
3270      * Cache to hold the NumberPattern of a Locale.
3271      */
3272     private static final ConcurrentMap<Locale, String> cachedLocaleData
3273         = new ConcurrentHashMap<Locale, String>(3);
3274 }