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