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