Home | History | Annotate | Download | only in text
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
      4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      5  *
      6  * This code is free software; you can redistribute it and/or modify it
      7  * under the terms of the GNU General Public License version 2 only, as
      8  * published by the Free Software Foundation.  Oracle designates this
      9  * particular file as subject to the "Classpath" exception as provided
     10  * by Oracle in the LICENSE file that accompanied this code.
     11  *
     12  * This code is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  * version 2 for more details (a copy is included in the LICENSE file that
     16  * accompanied this code).
     17  *
     18  * You should have received a copy of the GNU General Public License version
     19  * 2 along with this work; if not, write to the Free Software Foundation,
     20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     21  *
     22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     23  * or visit www.oracle.com if you need additional information or have any
     24  * questions.
     25  */
     26 
     27 /*
     28  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
     29  * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
     30  *
     31  *   The original version of this source code and documentation is copyrighted
     32  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
     33  * materials are provided under terms of a License Agreement between Taligent
     34  * and Sun. This technology is protected by multiple US and International
     35  * patents. This notice and attribution to Taligent may not be removed.
     36  *   Taligent is a registered trademark of Taligent, Inc.
     37  *
     38  */
     39 
     40 package java.text;
     41 
     42 import java.io.IOException;
     43 import java.io.ObjectInputStream;
     44 import java.io.ObjectOutputStream;
     45 import java.io.ObjectStreamField;
     46 import java.math.BigDecimal;
     47 import java.math.BigInteger;
     48 import java.math.RoundingMode;
     49 import java.util.Currency;
     50 import java.util.Locale;
     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 libcore.icu.LocaleData;
     56 
     57 import android.icu.math.MathContext;
     58 
     59 /**
     60  * <code>DecimalFormat</code> is a concrete subclass of
     61  * <code>NumberFormat</code> that formats decimal numbers. It has a variety of
     62  * features designed to make it possible to parse and format numbers in any
     63  * locale, including support for Western, Arabic, and Indic digits.  It also
     64  * supports different kinds of numbers, including integers (123), fixed-point
     65  * numbers (123.4), scientific notation (1.23E4), percentages (12%), and
     66  * currency amounts ($123).  All of these can be localized.
     67  *
     68  * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the
     69  * default locale, call one of <code>NumberFormat</code>'s factory methods, such
     70  * as <code>getInstance()</code>.  In general, do not call the
     71  * <code>DecimalFormat</code> constructors directly, since the
     72  * <code>NumberFormat</code> factory methods may return subclasses other than
     73  * <code>DecimalFormat</code>. If you need to customize the format object, do
     74  * something like this:
     75  *
     76  * <blockquote><pre>
     77  * NumberFormat f = NumberFormat.getInstance(loc);
     78  * if (f instanceof DecimalFormat) {
     79  *     ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
     80  * }
     81  * </pre></blockquote>
     82  *
     83  * <p>A <code>DecimalFormat</code> comprises a <em>pattern</em> and a set of
     84  * <em>symbols</em>.  The pattern may be set directly using
     85  * <code>applyPattern()</code>, or indirectly using the API methods.  The
     86  * symbols are stored in a <code>DecimalFormatSymbols</code> object.  When using
     87  * the <code>NumberFormat</code> factory methods, the pattern and symbols are
     88  * read from localized <code>ResourceBundle</code>s.
     89  *
     90  * <h3>Patterns</h3>
     91  *
     92  * <code>DecimalFormat</code> patterns have the following syntax:
     93  * <blockquote><pre>
     94  * <i>Pattern:</i>
     95  *         <i>PositivePattern</i>
     96  *         <i>PositivePattern</i> ; <i>NegativePattern</i>
     97  * <i>PositivePattern:</i>
     98  *         <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
     99  * <i>NegativePattern:</i>
    100  *         <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
    101  * <i>Prefix:</i>
    102  *         any Unicode characters except &#92;uFFFE, &#92;uFFFF, and special characters
    103  * <i>Suffix:</i>
    104  *         any Unicode characters except &#92;uFFFE, &#92;uFFFF, and special characters
    105  * <i>Number:</i>
    106  *         <i>Integer</i> <i>Exponent<sub>opt</sub></i>
    107  *         <i>Integer</i> . <i>Fraction</i> <i>Exponent<sub>opt</sub></i>
    108  * <i>Integer:</i>
    109  *         <i>MinimumInteger</i>
    110  *         #
    111  *         # <i>Integer</i>
    112  *         # , <i>Integer</i>
    113  * <i>MinimumInteger:</i>
    114  *         0
    115  *         0 <i>MinimumInteger</i>
    116  *         0 , <i>MinimumInteger</i>
    117  * <i>Fraction:</i>
    118  *         <i>MinimumFraction<sub>opt</sub></i> <i>OptionalFraction<sub>opt</sub></i>
    119  * <i>MinimumFraction:</i>
    120  *         0 <i>MinimumFraction<sub>opt</sub></i>
    121  * <i>OptionalFraction:</i>
    122  *         # <i>OptionalFraction<sub>opt</sub></i>
    123  * <i>Exponent:</i>
    124  *         E <i>MinimumExponent</i>
    125  * <i>MinimumExponent:</i>
    126  *         0 <i>MinimumExponent<sub>opt</sub></i>
    127  * </pre></blockquote>
    128  *
    129  * <p>A <code>DecimalFormat</code> pattern contains a positive and negative
    130  * subpattern, for example, <code>"#,##0.00;(#,##0.00)"</code>.  Each
    131  * subpattern has a prefix, numeric part, and suffix. The negative subpattern
    132  * is optional; if absent, then the positive subpattern prefixed with the
    133  * localized minus sign (<code>'-'</code> in most locales) is used as the
    134  * negative subpattern. That is, <code>"0.00"</code> alone is equivalent to
    135  * <code>"0.00;-0.00"</code>.  If there is an explicit negative subpattern, it
    136  * serves only to specify the negative prefix and suffix; the number of digits,
    137  * minimal digits, and other characteristics are all the same as the positive
    138  * pattern. That means that <code>"#,##0.0#;(#)"</code> produces precisely
    139  * the same behavior as <code>"#,##0.0#;(#,##0.0#)"</code>.
    140  *
    141  * <p>The prefixes, suffixes, and various symbols used for infinity, digits,
    142  * thousands separators, decimal separators, etc. may be set to arbitrary
    143  * values, and they will appear properly during formatting.  However, care must
    144  * be taken that the symbols and strings do not conflict, or parsing will be
    145  * unreliable.  For example, either the positive and negative prefixes or the
    146  * suffixes must be distinct for <code>DecimalFormat.parse()</code> to be able
    147  * to distinguish positive from negative values.  (If they are identical, then
    148  * <code>DecimalFormat</code> will behave as if no negative subpattern was
    149  * specified.)  Another example is that the decimal separator and thousands
    150  * separator should be distinct characters, or parsing will be impossible.
    151  *
    152  * <p>The grouping separator is commonly used for thousands, but in some
    153  * countries it separates ten-thousands. The grouping size is a constant number
    154  * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for
    155  * 1,0000,0000.  If you supply a pattern with multiple grouping characters, the
    156  * interval between the last one and the end of the integer is the one that is
    157  * used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> ==
    158  * <code>"##,####,####"</code>.
    159  *
    160  * <h4>Special Pattern Characters</h4>
    161  *
    162  * <p>Many characters in a pattern are taken literally; they are matched during
    163  * parsing and output unchanged during formatting.  Special characters, on the
    164  * other hand, stand for other characters, strings, or classes of characters.
    165  * They must be quoted, unless noted otherwise, if they are to appear in the
    166  * prefix or suffix as literals.
    167  *
    168  * <p>The characters listed here are used in non-localized patterns.  Localized
    169  * patterns use the corresponding characters taken from this formatter's
    170  * <code>DecimalFormatSymbols</code> object instead, and these characters lose
    171  * their special status.  Two exceptions are the currency sign and quote, which
    172  * are not localized.
    173  *
    174  * <blockquote>
    175  * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol,
    176  *  location, localized, and meaning.">
    177  *     <tr style="background-color: rgb(204, 204, 255);">
    178  *          <th align=left>Symbol
    179  *          <th align=left>Location
    180  *          <th align=left>Localized?
    181  *          <th align=left>Meaning
    182  *     <tr valign=top>
    183  *          <td><code>0</code>
    184  *          <td>Number
    185  *          <td>Yes
    186  *          <td>Digit
    187  *     <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">
    188  *          <td><code>#</code>
    189  *          <td>Number
    190  *          <td>Yes
    191  *          <td>Digit, zero shows as absent
    192  *     <tr valign=top>
    193  *          <td><code>.</code>
    194  *          <td>Number
    195  *          <td>Yes
    196  *          <td>Decimal separator or monetary decimal separator
    197  *     <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">
    198  *          <td><code>-</code>
    199  *          <td>Number
    200  *          <td>Yes
    201  *          <td>Minus sign
    202  *     <tr valign=top>
    203  *          <td><code>,</code>
    204  *          <td>Number
    205  *          <td>Yes
    206  *          <td>Grouping separator
    207  *     <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">
    208  *          <td><code>E</code>
    209  *          <td>Number
    210  *          <td>Yes
    211  *          <td>Separates mantissa and exponent in scientific notation.
    212  *              <em>Need not be quoted in prefix or suffix.</em>
    213  *     <tr valign=top>
    214  *          <td><code>;</code>
    215  *          <td>Subpattern boundary
    216  *          <td>Yes
    217  *          <td>Separates positive and negative subpatterns
    218  *     <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">
    219  *          <td><code>%</code>
    220  *          <td>Prefix or suffix
    221  *          <td>Yes
    222  *          <td>Multiply by 100 and show as percentage
    223  *     <tr valign=top>
    224  *          <td><code>&#92;u2030</code>
    225  *          <td>Prefix or suffix
    226  *          <td>Yes
    227  *          <td>Multiply by 1000 and show as per mille value
    228  *     <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">
    229  *          <td><code>&#164;</code> (<code>&#92;u00A4</code>)
    230  *          <td>Prefix or suffix
    231  *          <td>No
    232  *          <td>Currency sign, replaced by currency symbol.  If
    233  *              doubled, replaced by international currency symbol.
    234  *              If present in a pattern, the monetary decimal separator
    235  *              is used instead of the decimal separator.
    236  *     <tr valign=top>
    237  *          <td><code>'</code>
    238  *          <td>Prefix or suffix
    239  *          <td>No
    240  *          <td>Used to quote special characters in a prefix or suffix,
    241  *              for example, <code>"'#'#"</code> formats 123 to
    242  *              <code>"#123"</code>.  To create a single quote
    243  *              itself, use two in a row: <code>"# o''clock"</code>.
    244  * </table>
    245  * </blockquote>
    246  *
    247  * <h4>Scientific Notation</h4>
    248  *
    249  * <p>Numbers in scientific notation are expressed as the product of a mantissa
    250  * and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3.  The
    251  * mantissa is often in the range 1.0 &le; x {@literal <} 10.0, but it need not
    252  * be.
    253  * <code>DecimalFormat</code> can be instructed to format and parse scientific
    254  * notation <em>only via a pattern</em>; there is currently no factory method
    255  * that creates a scientific notation format.  In a pattern, the exponent
    256  * character immediately followed by one or more digit characters indicates
    257  * scientific notation.  Example: <code>"0.###E0"</code> formats the number
    258  * 1234 as <code>"1.234E3"</code>.
    259  *
    260  * <ul>
    261  * <li>The number of digit characters after the exponent character gives the
    262  * minimum exponent digit count.  There is no maximum.  Negative exponents are
    263  * formatted using the localized minus sign, <em>not</em> the prefix and suffix
    264  * from the pattern.  This allows patterns such as <code>"0.###E0 m/s"</code>.
    265  *
    266  * <li>The minimum and maximum number of integer digits are interpreted
    267  * together:
    268  *
    269  * <ul>
    270  * <li>If the maximum number of integer digits is greater than their minimum number
    271  * and greater than 1, it forces the exponent to be a multiple of the maximum
    272  * number of integer digits, and the minimum number of integer digits to be
    273  * interpreted as 1.  The most common use of this is to generate
    274  * <em>engineering notation</em>, in which the exponent is a multiple of three,
    275  * e.g., <code>"##0.#####E0"</code>. Using this pattern, the number 12345
    276  * formats to <code>"12.345E3"</code>, and 123456 formats to
    277  * <code>"123.456E3"</code>.
    278  *
    279  * <li>Otherwise, the minimum number of integer digits is achieved by adjusting the
    280  * exponent.  Example: 0.00123 formatted with <code>"00.###E0"</code> yields
    281  * <code>"12.3E-4"</code>.
    282  * </ul>
    283  *
    284  * <li>The number of significant digits in the mantissa is the sum of the
    285  * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is
    286  * unaffected by the maximum integer digits.  For example, 12345 formatted with
    287  * <code>"##0.##E0"</code> is <code>"12.3E3"</code>. To show all digits, set
    288  * the significant digits count to zero.  The number of significant digits
    289  * does not affect parsing.
    290  *
    291  * <li>Exponential patterns may not contain grouping separators.
    292  * </ul>
    293  *
    294  * <h4>Rounding</h4>
    295  *
    296  * <code>DecimalFormat</code> provides rounding modes defined in
    297  * {@link java.math.RoundingMode} for formatting.  By default, it uses
    298  * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
    299  *
    300  * <h4>Digits</h4>
    301  *
    302  * For formatting, <code>DecimalFormat</code> uses the ten consecutive
    303  * characters starting with the localized zero digit defined in the
    304  * <code>DecimalFormatSymbols</code> object as digits. For parsing, these
    305  * digits as well as all Unicode decimal digits, as defined by
    306  * {@link Character#digit Character.digit}, are recognized.
    307  *
    308  * <h4>Special Values</h4>
    309  *
    310  * <p><code>NaN</code> is formatted as a string, which typically has a single character
    311  * <code>&#92;uFFFD</code>.  This string is determined by the
    312  * <code>DecimalFormatSymbols</code> object.  This is the only value for which
    313  * the prefixes and suffixes are not used.
    314  *
    315  * <p>Infinity is formatted as a string, which typically has a single character
    316  * <code>&#92;u221E</code>, with the positive or negative prefixes and suffixes
    317  * applied.  The infinity string is determined by the
    318  * <code>DecimalFormatSymbols</code> object.
    319  *
    320  * <p>Negative zero (<code>"-0"</code>) parses to
    321  * <ul>
    322  * <li><code>BigDecimal(0)</code> if <code>isParseBigDecimal()</code> is
    323  * true,
    324  * <li><code>Long(0)</code> if <code>isParseBigDecimal()</code> is false
    325  *     and <code>isParseIntegerOnly()</code> is true,
    326  * <li><code>Double(-0.0)</code> if both <code>isParseBigDecimal()</code>
    327  * and <code>isParseIntegerOnly()</code> are false.
    328  * </ul>
    329  *
    330  * <h4><a name="synchronization">Synchronization</a></h4>
    331  *
    332  * <p>
    333  * Decimal formats are generally not synchronized.
    334  * It is recommended to create separate format instances for each thread.
    335  * If multiple threads access a format concurrently, it must be synchronized
    336  * externally.
    337  *
    338  * <h4>Example</h4>
    339  *
    340  * <blockquote><pre>{@code
    341  * <strong>// Print out a number using the localized number, integer, currency,
    342  * // and percent format for each locale</strong>
    343  * Locale[] locales = NumberFormat.getAvailableLocales();
    344  * double myNumber = -1234.56;
    345  * NumberFormat form;
    346  * for (int j = 0; j < 4; ++j) {
    347  *     System.out.println("FORMAT");
    348  *     for (int i = 0; i < locales.length; ++i) {
    349  *         if (locales[i].getCountry().length() == 0) {
    350  *            continue; // Skip language-only locales
    351  *         }
    352  *         System.out.print(locales[i].getDisplayName());
    353  *         switch (j) {
    354  *         case 0:
    355  *             form = NumberFormat.getInstance(locales[i]); break;
    356  *         case 1:
    357  *             form = NumberFormat.getIntegerInstance(locales[i]); break;
    358  *         case 2:
    359  *             form = NumberFormat.getCurrencyInstance(locales[i]); break;
    360  *         default:
    361  *             form = NumberFormat.getPercentInstance(locales[i]); break;
    362  *         }
    363  *         if (form instanceof DecimalFormat) {
    364  *             System.out.print(": " + ((DecimalFormat) form).toPattern());
    365  *         }
    366  *         System.out.print(" -> " + form.format(myNumber));
    367  *         try {
    368  *             System.out.println(" -> " + form.parse(form.format(myNumber)));
    369  *         } catch (ParseException e) {}
    370  *     }
    371  * }
    372  * }</pre></blockquote>
    373  *
    374  * @see          <a href="https://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a>
    375  * @see          NumberFormat
    376  * @see          DecimalFormatSymbols
    377  * @see          ParsePosition
    378  * @author       Mark Davis
    379  * @author       Alan Liu
    380  */
    381 public class DecimalFormat extends NumberFormat {
    382 
    383     private transient android.icu.text.DecimalFormat icuDecimalFormat;
    384 
    385     /**
    386      * Creates a DecimalFormat using the default pattern and symbols
    387      * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
    388      * This is a convenient way to obtain a
    389      * DecimalFormat when internationalization is not the main concern.
    390      * <p>
    391      * To obtain standard formats for a given locale, use the factory methods
    392      * on NumberFormat such as getNumberInstance. These factories will
    393      * return the most appropriate sub-class of NumberFormat for a given
    394      * locale.
    395      *
    396      * @see java.text.NumberFormat#getInstance
    397      * @see java.text.NumberFormat#getNumberInstance
    398      * @see java.text.NumberFormat#getCurrencyInstance
    399      * @see java.text.NumberFormat#getPercentInstance
    400      */
    401     public DecimalFormat() {
    402         // Get the pattern for the default locale.
    403         Locale def = Locale.getDefault(Locale.Category.FORMAT);
    404         // try to get the pattern from the cache
    405         String pattern = cachedLocaleData.get(def);
    406         if (pattern == null) {  /* cache miss */
    407             // Get the pattern for the default locale.
    408             pattern = LocaleData.get(def).numberPattern;
    409             /* update cache */
    410             cachedLocaleData.putIfAbsent(def, pattern);
    411         }
    412         this.symbols = new DecimalFormatSymbols(def);
    413         init(pattern);
    414     }
    415 
    416 
    417     /**
    418      * Creates a DecimalFormat using the given pattern and the symbols
    419      * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
    420      * This is a convenient way to obtain a
    421      * DecimalFormat when internationalization is not the main concern.
    422      * <p>
    423      * To obtain standard formats for a given locale, use the factory methods
    424      * on NumberFormat such as getNumberInstance. These factories will
    425      * return the most appropriate sub-class of NumberFormat for a given
    426      * locale.
    427      *
    428      * @param pattern a non-localized pattern string.
    429      * @exception NullPointerException if <code>pattern</code> is null
    430      * @exception IllegalArgumentException if the given pattern is invalid.
    431      * @see java.text.NumberFormat#getInstance
    432      * @see java.text.NumberFormat#getNumberInstance
    433      * @see java.text.NumberFormat#getCurrencyInstance
    434      * @see java.text.NumberFormat#getPercentInstance
    435      */
    436     public DecimalFormat(String pattern) {
    437         this.symbols = new DecimalFormatSymbols(Locale.getDefault(Locale.Category.FORMAT));
    438         init(pattern);
    439     }
    440 
    441 
    442     /**
    443      * Creates a DecimalFormat using the given pattern and symbols.
    444      * Use this constructor when you need to completely customize the
    445      * behavior of the format.
    446      * <p>
    447      * To obtain standard formats for a given
    448      * locale, use the factory methods on NumberFormat such as
    449      * getInstance or getCurrencyInstance. If you need only minor adjustments
    450      * to a standard format, you can modify the format returned by
    451      * a NumberFormat factory method.
    452      *
    453      * @param pattern a non-localized pattern string
    454      * @param symbols the set of symbols to be used
    455      * @exception NullPointerException if any of the given arguments is null
    456      * @exception IllegalArgumentException if the given pattern is invalid
    457      * @see java.text.NumberFormat#getInstance
    458      * @see java.text.NumberFormat#getNumberInstance
    459      * @see java.text.NumberFormat#getCurrencyInstance
    460      * @see java.text.NumberFormat#getPercentInstance
    461      * @see java.text.DecimalFormatSymbols
    462      */
    463     public DecimalFormat (String pattern, DecimalFormatSymbols symbols) {
    464         // Always applyPattern after the symbols are set
    465         this.symbols = (DecimalFormatSymbols)symbols.clone();
    466         init(pattern);
    467     }
    468 
    469     private void init(String pattern) {
    470         this.icuDecimalFormat =  new android.icu.text.DecimalFormat(pattern,
    471                 symbols.getIcuDecimalFormatSymbols());
    472         updateFieldsFromIcu();
    473     }
    474 
    475     /**
    476      * Converts between field positions used by Java/ICU.
    477      * @param fp The java.text.NumberFormat.Field field position
    478      * @return The android.icu.text.NumberFormat.Field field position
    479      */
    480     private static FieldPosition getIcuFieldPosition(FieldPosition fp) {
    481         if (fp.getFieldAttribute() == null) return fp;
    482 
    483         android.icu.text.NumberFormat.Field attribute;
    484         if (fp.getFieldAttribute() == Field.INTEGER) {
    485             attribute = android.icu.text.NumberFormat.Field.INTEGER;
    486         } else if (fp.getFieldAttribute() == Field.FRACTION) {
    487             attribute = android.icu.text.NumberFormat.Field.FRACTION;
    488         } else if (fp.getFieldAttribute() == Field.DECIMAL_SEPARATOR) {
    489             attribute = android.icu.text.NumberFormat.Field.DECIMAL_SEPARATOR;
    490         } else if (fp.getFieldAttribute() == Field.EXPONENT_SYMBOL) {
    491             attribute = android.icu.text.NumberFormat.Field.EXPONENT_SYMBOL;
    492         } else if (fp.getFieldAttribute() == Field.EXPONENT_SIGN) {
    493             attribute = android.icu.text.NumberFormat.Field.EXPONENT_SIGN;
    494         } else if (fp.getFieldAttribute() == Field.EXPONENT) {
    495             attribute = android.icu.text.NumberFormat.Field.EXPONENT;
    496         } else if (fp.getFieldAttribute() == Field.GROUPING_SEPARATOR) {
    497             attribute = android.icu.text.NumberFormat.Field.GROUPING_SEPARATOR;
    498         } else if (fp.getFieldAttribute() == Field.CURRENCY) {
    499             attribute = android.icu.text.NumberFormat.Field.CURRENCY;
    500         } else if (fp.getFieldAttribute() == Field.PERCENT) {
    501             attribute = android.icu.text.NumberFormat.Field.PERCENT;
    502         } else if (fp.getFieldAttribute() == Field.PERMILLE) {
    503             attribute = android.icu.text.NumberFormat.Field.PERMILLE;
    504         } else if (fp.getFieldAttribute() == Field.SIGN) {
    505             attribute = android.icu.text.NumberFormat.Field.SIGN;
    506         } else {
    507             throw new IllegalArgumentException("Unexpected field position attribute type.");
    508         }
    509 
    510         FieldPosition icuFieldPosition = new FieldPosition(attribute);
    511         icuFieldPosition.setBeginIndex(fp.getBeginIndex());
    512         icuFieldPosition.setEndIndex(fp.getEndIndex());
    513         return icuFieldPosition;
    514     }
    515 
    516     /**
    517      * Converts the Attribute that ICU returns in its AttributedCharacterIterator
    518      * responses to the type that java uses.
    519      * @param icuAttribute The AttributedCharacterIterator.Attribute field.
    520      * @return Field converted to a java.text.NumberFormat.Field field.
    521      */
    522     private static Field toJavaFieldAttribute(AttributedCharacterIterator.Attribute icuAttribute) {
    523         if (icuAttribute.getName().equals(Field.INTEGER.getName())) {
    524             return Field.INTEGER;
    525         }
    526         if (icuAttribute.getName().equals(Field.CURRENCY.getName())) {
    527             return Field.CURRENCY;
    528         }
    529         if (icuAttribute.getName().equals(Field.DECIMAL_SEPARATOR.getName())) {
    530             return Field.DECIMAL_SEPARATOR;
    531         }
    532         if (icuAttribute.getName().equals(Field.EXPONENT.getName())) {
    533             return Field.EXPONENT;
    534         }
    535         if (icuAttribute.getName().equals(Field.EXPONENT_SIGN.getName())) {
    536             return Field.EXPONENT_SIGN;
    537         }
    538         if (icuAttribute.getName().equals(Field.EXPONENT_SYMBOL.getName())) {
    539             return Field.EXPONENT_SYMBOL;
    540         }
    541         if (icuAttribute.getName().equals(Field.FRACTION.getName())) {
    542             return Field.FRACTION;
    543         }
    544         if (icuAttribute.getName().equals(Field.GROUPING_SEPARATOR.getName())) {
    545             return Field.GROUPING_SEPARATOR;
    546         }
    547         if (icuAttribute.getName().equals(Field.SIGN.getName())) {
    548             return Field.SIGN;
    549         }
    550         if (icuAttribute.getName().equals(Field.PERCENT.getName())) {
    551             return Field.PERCENT;
    552         }
    553         if (icuAttribute.getName().equals(Field.PERMILLE.getName())) {
    554             return Field.PERMILLE;
    555         }
    556         throw new IllegalArgumentException("Unrecognized attribute: " + icuAttribute.getName());
    557    }
    558 
    559     // Overrides
    560     /**
    561      * Formats a number and appends the resulting text to the given string
    562      * buffer.
    563      * The number can be of any subclass of {@link java.lang.Number}.
    564      * <p>
    565      * This implementation uses the maximum precision permitted.
    566      * @param number     the number to format
    567      * @param toAppendTo the <code>StringBuffer</code> to which the formatted
    568      *                   text is to be appended
    569      * @param pos        On input: an alignment field, if desired.
    570      *                   On output: the offsets of the alignment field.
    571      * @return           the value passed in as <code>toAppendTo</code>
    572      * @exception        IllegalArgumentException if <code>number</code> is
    573      *                   null or not an instance of <code>Number</code>.
    574      * @exception        NullPointerException if <code>toAppendTo</code> or
    575      *                   <code>pos</code> is null
    576      * @exception        ArithmeticException if rounding is needed with rounding
    577      *                   mode being set to RoundingMode.UNNECESSARY
    578      * @see              java.text.FieldPosition
    579      */
    580     @Override
    581     public final StringBuffer format(Object number,
    582                                      StringBuffer toAppendTo,
    583                                      FieldPosition pos) {
    584         if (number instanceof Long || number instanceof Integer ||
    585                    number instanceof Short || number instanceof Byte ||
    586                    number instanceof AtomicInteger ||
    587                    number instanceof AtomicLong ||
    588                    (number instanceof BigInteger &&
    589                     ((BigInteger)number).bitLength () < 64)) {
    590             return format(((Number)number).longValue(), toAppendTo, pos);
    591         } else if (number instanceof BigDecimal) {
    592             return format((BigDecimal)number, toAppendTo, pos);
    593         } else if (number instanceof BigInteger) {
    594             return format((BigInteger)number, toAppendTo, pos);
    595         } else if (number instanceof Number) {
    596             return format(((Number)number).doubleValue(), toAppendTo, pos);
    597         } else {
    598             throw new IllegalArgumentException("Cannot format given Object as a Number");
    599         }
    600     }
    601 
    602     /**
    603      * Formats a double to produce a string.
    604      * @param number    The double to format
    605      * @param result    where the text is to be appended
    606      * @param fieldPosition    On input: an alignment field, if desired.
    607      * On output: the offsets of the alignment field.
    608      * @exception ArithmeticException if rounding is needed with rounding
    609      *            mode being set to RoundingMode.UNNECESSARY
    610      * @return The formatted number string
    611      * @see java.text.FieldPosition
    612      */
    613     @Override
    614     public StringBuffer format(double number, StringBuffer result,
    615                                FieldPosition fieldPosition) {
    616         FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition);
    617         icuDecimalFormat.format(number, result, icuFieldPosition);
    618         fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex());
    619         fieldPosition.setEndIndex(icuFieldPosition.getEndIndex());
    620         return result;
    621     }
    622 
    623     /**
    624      * Format a long to produce a string.
    625      * @param number    The long to format
    626      * @param result    where the text is to be appended
    627      * @param fieldPosition    On input: an alignment field, if desired.
    628      * On output: the offsets of the alignment field.
    629      * @exception       ArithmeticException if rounding is needed with rounding
    630      *                  mode being set to RoundingMode.UNNECESSARY
    631      * @return The formatted number string
    632      * @see java.text.FieldPosition
    633      */
    634     @Override
    635     public StringBuffer format(long number, StringBuffer result,
    636                                FieldPosition fieldPosition) {
    637         FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition);
    638         icuDecimalFormat.format(number, result, icuFieldPosition);
    639         fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex());
    640         fieldPosition.setEndIndex(icuFieldPosition.getEndIndex());
    641         return result;
    642     }
    643 
    644     /**
    645      * Formats a BigDecimal to produce a string.
    646      * @param number    The BigDecimal to format
    647      * @param result    where the text is to be appended
    648      * @param fieldPosition    On input: an alignment field, if desired.
    649      * On output: the offsets of the alignment field.
    650      * @return The formatted number string
    651      * @exception        ArithmeticException if rounding is needed with rounding
    652      *                   mode being set to RoundingMode.UNNECESSARY
    653      * @see java.text.FieldPosition
    654      */
    655     private StringBuffer format(BigDecimal number, StringBuffer result,
    656                                 FieldPosition fieldPosition) {
    657         FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition);
    658         icuDecimalFormat.format(number, result, fieldPosition);
    659         fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex());
    660         fieldPosition.setEndIndex(icuFieldPosition.getEndIndex());
    661         return result;
    662     }
    663 
    664     /**
    665      * Format a BigInteger to produce a string.
    666      * @param number    The BigInteger to format
    667      * @param result    where the text is to be appended
    668      * @param fieldPosition    On input: an alignment field, if desired.
    669      * On output: the offsets of the alignment field.
    670      * @return The formatted number string
    671      * @exception        ArithmeticException if rounding is needed with rounding
    672      *                   mode being set to RoundingMode.UNNECESSARY
    673      * @see java.text.FieldPosition
    674      */
    675     private StringBuffer format(BigInteger number, StringBuffer result,
    676                                FieldPosition fieldPosition) {
    677         FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition);
    678         icuDecimalFormat.format(number, result, fieldPosition);
    679         fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex());
    680         fieldPosition.setEndIndex(icuFieldPosition.getEndIndex());
    681         return result;
    682     }
    683 
    684     /**
    685      * Formats an Object producing an <code>AttributedCharacterIterator</code>.
    686      * You can use the returned <code>AttributedCharacterIterator</code>
    687      * to build the resulting String, as well as to determine information
    688      * about the resulting String.
    689      * <p>
    690      * Each attribute key of the AttributedCharacterIterator will be of type
    691      * <code>NumberFormat.Field</code>, with the attribute value being the
    692      * same as the attribute key.
    693      *
    694      * @exception NullPointerException if obj is null.
    695      * @exception IllegalArgumentException when the Format cannot format the
    696      *            given object.
    697      * @exception        ArithmeticException if rounding is needed with rounding
    698      *                   mode being set to RoundingMode.UNNECESSARY
    699      * @param obj The object to format
    700      * @return AttributedCharacterIterator describing the formatted value.
    701      * @since 1.4
    702      */
    703     @Override
    704     public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
    705         if (obj == null) {
    706             throw new NullPointerException("object == null");
    707         }
    708         // Note: formatToCharacterIterator cannot be used directly because it returns attributes
    709         // in terms of its own class: icu.text.NumberFormat instead of java.text.NumberFormat.
    710         // http://bugs.icu-project.org/trac/ticket/11931 Proposes to use the NumberFormat constants.
    711 
    712         AttributedCharacterIterator original = icuDecimalFormat.formatToCharacterIterator(obj);
    713 
    714         // Extract the text out of the ICU iterator.
    715         StringBuilder textBuilder = new StringBuilder(
    716                 original.getEndIndex() - original.getBeginIndex());
    717 
    718         for (int i = original.getBeginIndex(); i < original.getEndIndex(); i++) {
    719             textBuilder.append(original.current());
    720             original.next();
    721         }
    722 
    723         AttributedString result = new AttributedString(textBuilder.toString());
    724 
    725         for (int i = original.getBeginIndex(); i < original.getEndIndex(); i++) {
    726             original.setIndex(i);
    727 
    728             for (AttributedCharacterIterator.Attribute attribute
    729                     : original.getAttributes().keySet()) {
    730                     int start = original.getRunStart();
    731                     int end = original.getRunLimit();
    732                     Field javaAttr = toJavaFieldAttribute(attribute);
    733                     result.addAttribute(javaAttr, javaAttr, start, end);
    734             }
    735         }
    736 
    737         return result.getIterator();
    738     }
    739 
    740     /**
    741      * Parses text from a string to produce a <code>Number</code>.
    742      * <p>
    743      * The method attempts to parse text starting at the index given by
    744      * <code>pos</code>.
    745      * If parsing succeeds, then the index of <code>pos</code> is updated
    746      * to the index after the last character used (parsing does not necessarily
    747      * use all characters up to the end of the string), and the parsed
    748      * number is returned. The updated <code>pos</code> can be used to
    749      * indicate the starting point for the next call to this method.
    750      * If an error occurs, then the index of <code>pos</code> is not
    751      * changed, the error index of <code>pos</code> is set to the index of
    752      * the character where the error occurred, and null is returned.
    753      * <p>
    754      * The subclass returned depends on the value of {@link #isParseBigDecimal}
    755      * as well as on the string being parsed.
    756      * <ul>
    757      *   <li>If <code>isParseBigDecimal()</code> is false (the default),
    758      *       most integer values are returned as <code>Long</code>
    759      *       objects, no matter how they are written: <code>"17"</code> and
    760      *       <code>"17.000"</code> both parse to <code>Long(17)</code>.
    761      *       Values that cannot fit into a <code>Long</code> are returned as
    762      *       <code>Double</code>s. This includes values with a fractional part,
    763      *       infinite values, <code>NaN</code>, and the value -0.0.
    764      *       <code>DecimalFormat</code> does <em>not</em> decide whether to
    765      *       return a <code>Double</code> or a <code>Long</code> based on the
    766      *       presence of a decimal separator in the source string. Doing so
    767      *       would prevent integers that overflow the mantissa of a double,
    768      *       such as <code>"-9,223,372,036,854,775,808.00"</code>, from being
    769      *       parsed accurately.
    770      *       <p>
    771      *       Callers may use the <code>Number</code> methods
    772      *       <code>doubleValue</code>, <code>longValue</code>, etc., to obtain
    773      *       the type they want.
    774      *   <li>If <code>isParseBigDecimal()</code> is true, values are returned
    775      *       as <code>BigDecimal</code> objects. The values are the ones
    776      *       constructed by {@link java.math.BigDecimal#BigDecimal(String)}
    777      *       for corresponding strings in locale-independent format. The
    778      *       special cases negative and positive infinity and NaN are returned
    779      *       as <code>Double</code> instances holding the values of the
    780      *       corresponding <code>Double</code> constants.
    781      * </ul>
    782      * <p>
    783      * <code>DecimalFormat</code> parses all Unicode characters that represent
    784      * decimal digits, as defined by <code>Character.digit()</code>. In
    785      * addition, <code>DecimalFormat</code> also recognizes as digits the ten
    786      * consecutive characters starting with the localized zero digit defined in
    787      * the <code>DecimalFormatSymbols</code> object.
    788      *
    789      * @param text the string to be parsed
    790      * @param pos  A <code>ParsePosition</code> object with index and error
    791      *             index information as described above.
    792      * @return     the parsed value, or <code>null</code> if the parse fails
    793      * @exception  NullPointerException if <code>text</code> or
    794      *             <code>pos</code> is null.
    795      */
    796     @Override
    797     public Number parse(String text, ParsePosition pos) {
    798         // Return early if the parse position is bogus.
    799         if (pos.index < 0 || pos.index >= text.length()) {
    800             return null;
    801         }
    802 
    803         // This might return android.icu.math.BigDecimal, java.math.BigInteger or a primitive type.
    804         Number number = icuDecimalFormat.parse(text, pos);
    805         if (number == null) {
    806             return null;
    807         }
    808         if (isParseBigDecimal()) {
    809             if (number instanceof Long) {
    810                 return new BigDecimal(number.longValue());
    811             }
    812             if ((number instanceof Double) && !((Double) number).isInfinite()
    813                     && !((Double) number).isNaN()) {
    814                 return new BigDecimal(number.toString());
    815             }
    816             if ((number instanceof Double) &&
    817                     (((Double) number).isNaN() || ((Double) number).isInfinite())) {
    818                 return number;
    819             }
    820             if (number instanceof android.icu.math.BigDecimal) {
    821                 return ((android.icu.math.BigDecimal) number).toBigDecimal();
    822             }
    823         }
    824         if ((number instanceof android.icu.math.BigDecimal) || (number instanceof BigInteger)) {
    825             return number.doubleValue();
    826         }
    827         if (isParseIntegerOnly() && number.equals(new Double(-0.0))) {
    828             return 0L;
    829         }
    830         return number;
    831     }
    832 
    833     /**
    834      * Returns a copy of the decimal format symbols, which is generally not
    835      * changed by the programmer or user.
    836      * @return a copy of the desired DecimalFormatSymbols
    837      * @see java.text.DecimalFormatSymbols
    838      */
    839     public DecimalFormatSymbols getDecimalFormatSymbols() {
    840         return DecimalFormatSymbols.fromIcuInstance(icuDecimalFormat.getDecimalFormatSymbols());
    841     }
    842 
    843 
    844     /**
    845      * Sets the decimal format symbols, which is generally not changed
    846      * by the programmer or user.
    847      * @param newSymbols desired DecimalFormatSymbols
    848      * @see java.text.DecimalFormatSymbols
    849      */
    850     public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
    851         try {
    852             // don't allow multiple references
    853             symbols = (DecimalFormatSymbols) newSymbols.clone();
    854             icuDecimalFormat.setDecimalFormatSymbols(symbols.getIcuDecimalFormatSymbols());
    855         } catch (Exception foo) {
    856             // should never happen
    857         }
    858     }
    859 
    860     /**
    861      * Get the positive prefix.
    862      * <P>Examples: +123, $123, sFr123
    863      *
    864      * @return the positive prefix
    865      */
    866     public String getPositivePrefix () {
    867         return icuDecimalFormat.getPositivePrefix();
    868     }
    869 
    870     /**
    871      * Set the positive prefix.
    872      * <P>Examples: +123, $123, sFr123
    873      *
    874      * @param newValue the new positive prefix
    875      */
    876     public void setPositivePrefix (String newValue) {
    877         icuDecimalFormat.setPositivePrefix(newValue);
    878     }
    879 
    880     /**
    881      * Get the  prefix.
    882      * <P>Examples: -123, ($123) (with negative suffix), sFr-123
    883      *
    884      * @return the negative prefix
    885      */
    886     public String getNegativePrefix () {
    887         return icuDecimalFormat.getNegativePrefix();
    888     }
    889 
    890     /**
    891      * Set the negative prefix.
    892      * <P>Examples: -123, ($123) (with negative suffix), sFr-123
    893      *
    894      * @param newValue the new negative prefix
    895      */
    896     public void setNegativePrefix (String newValue) {
    897         icuDecimalFormat.setNegativePrefix(newValue);
    898     }
    899 
    900     /**
    901      * Get the positive suffix.
    902      * <P>Example: 123%
    903      *
    904      * @return the positive suffix
    905      */
    906     public String getPositiveSuffix () {
    907         return icuDecimalFormat.getPositiveSuffix();
    908     }
    909 
    910     /**
    911      * Set the positive suffix.
    912      * <P>Example: 123%
    913      *
    914      * @param newValue the new positive suffix
    915      */
    916     public void setPositiveSuffix (String newValue) {
    917         icuDecimalFormat.setPositiveSuffix(newValue);
    918     }
    919 
    920     /**
    921      * Get the negative suffix.
    922      * <P>Examples: -123%, ($123) (with positive suffixes)
    923      *
    924      * @return the negative suffix
    925      */
    926     public String getNegativeSuffix () {
    927         return icuDecimalFormat.getNegativeSuffix();
    928     }
    929 
    930     /**
    931      * Set the negative suffix.
    932      * <P>Examples: 123%
    933      *
    934      * @param newValue the new negative suffix
    935      */
    936     public void setNegativeSuffix (String newValue) {
    937         icuDecimalFormat.setNegativeSuffix(newValue);
    938     }
    939 
    940     /**
    941      * Gets the multiplier for use in percent, per mille, and similar
    942      * formats.
    943      *
    944      * @return the multiplier
    945      * @see #setMultiplier(int)
    946      */
    947     public int getMultiplier () {
    948         return icuDecimalFormat.getMultiplier();
    949     }
    950 
    951     /**
    952      * Sets the multiplier for use in percent, per mille, and similar
    953      * formats.
    954      * For a percent format, set the multiplier to 100 and the suffixes to
    955      * have '%' (for Arabic, use the Arabic percent sign).
    956      * For a per mille format, set the multiplier to 1000 and the suffixes to
    957      * have '&#92;u2030'.
    958      *
    959      * <P>Example: with multiplier 100, 1.23 is formatted as "123", and
    960      * "123" is parsed into 1.23.
    961      *
    962      * @param newValue the new multiplier
    963      * @see #getMultiplier
    964      */
    965     public void setMultiplier (int newValue) {
    966         icuDecimalFormat.setMultiplier(newValue);
    967     }
    968 
    969     /**
    970      * Return the grouping size. Grouping size is the number of digits between
    971      * grouping separators in the integer portion of a number.  For example,
    972      * in the number "123,456.78", the grouping size is 3.
    973      *
    974      * @return the grouping size
    975      * @see #setGroupingSize
    976      * @see java.text.NumberFormat#isGroupingUsed
    977      * @see java.text.DecimalFormatSymbols#getGroupingSeparator
    978      */
    979     public int getGroupingSize () {
    980         return icuDecimalFormat.getGroupingSize();
    981     }
    982 
    983     /**
    984      * Set the grouping size. Grouping size is the number of digits between
    985      * grouping separators in the integer portion of a number.  For example,
    986      * in the number "123,456.78", the grouping size is 3.
    987      * <br>
    988      * The value passed in is converted to a byte, which may lose information.
    989      *
    990      * @param newValue the new grouping size
    991      * @see #getGroupingSize
    992      * @see java.text.NumberFormat#setGroupingUsed
    993      * @see java.text.DecimalFormatSymbols#setGroupingSeparator
    994      */
    995     public void setGroupingSize (int newValue) {
    996         icuDecimalFormat.setGroupingSize(newValue);
    997     }
    998 
    999     /**
   1000      * Returns true if grouping is used in this format. For example, in the
   1001      * English locale, with grouping on, the number 1234567 might be formatted
   1002      * as "1,234,567". The grouping separator as well as the size of each group
   1003      * is locale dependant and is determined by sub-classes of NumberFormat.
   1004      * @see #setGroupingUsed
   1005      */
   1006     public boolean isGroupingUsed() {
   1007         return icuDecimalFormat.isGroupingUsed();
   1008     }
   1009 
   1010     /**
   1011      * Set whether or not grouping will be used in this format.
   1012      * @see #isGroupingUsed
   1013      */
   1014     public void setGroupingUsed(boolean newValue) {
   1015         icuDecimalFormat.setGroupingUsed(newValue);
   1016     }
   1017 
   1018     /**
   1019      * Allows you to get the behavior of the decimal separator with integers.
   1020      * (The decimal separator will always appear with decimals.)
   1021      * <P>Example: Decimal ON: 12345 &rarr; 12345.; OFF: 12345 &rarr; 12345
   1022      *
   1023      * @return {@code true} if the decimal separator is always shown;
   1024      *         {@code false} otherwise
   1025      */
   1026     public boolean isDecimalSeparatorAlwaysShown() {
   1027         return icuDecimalFormat.isDecimalSeparatorAlwaysShown();
   1028     }
   1029 
   1030     /**
   1031      * Allows you to set the behavior of the decimal separator with integers.
   1032      * (The decimal separator will always appear with decimals.)
   1033      * <P>Example: Decimal ON: 12345 &rarr; 12345.; OFF: 12345 &rarr; 12345
   1034      *
   1035      * @param newValue {@code true} if the decimal separator is always shown;
   1036      *                 {@code false} otherwise
   1037      */
   1038     public void setDecimalSeparatorAlwaysShown(boolean newValue) {
   1039         icuDecimalFormat.setDecimalSeparatorAlwaysShown(newValue);
   1040     }
   1041 
   1042     /**
   1043      * Returns whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
   1044      * method returns <code>BigDecimal</code>. The default value is false.
   1045      *
   1046      * @return {@code true} if the parse method returns BigDecimal;
   1047      *         {@code false} otherwise
   1048      * @see #setParseBigDecimal
   1049      * @since 1.5
   1050      */
   1051     public boolean isParseBigDecimal() {
   1052         return icuDecimalFormat.isParseBigDecimal();
   1053     }
   1054 
   1055     /**
   1056      * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
   1057      * method returns <code>BigDecimal</code>.
   1058      *
   1059      * @param newValue {@code true} if the parse method returns BigDecimal;
   1060      *                 {@code false} otherwise
   1061      * @see #isParseBigDecimal
   1062      * @since 1.5
   1063      */
   1064     public void setParseBigDecimal(boolean newValue) {
   1065         icuDecimalFormat.setParseBigDecimal(newValue);
   1066     }
   1067 
   1068     /**
   1069      * Sets whether or not numbers should be parsed as integers only.
   1070      * @see #isParseIntegerOnly
   1071      */
   1072     public void setParseIntegerOnly(boolean value) {
   1073         super.setParseIntegerOnly(value);
   1074         icuDecimalFormat.setParseIntegerOnly(value);
   1075     }
   1076 
   1077     /**
   1078      * Returns true if this format will parse numbers as integers only.
   1079      * For example in the English locale, with ParseIntegerOnly true, the
   1080      * string "1234." would be parsed as the integer value 1234 and parsing
   1081      * would stop at the "." character.  Of course, the exact format accepted
   1082      * by the parse operation is locale dependant and determined by sub-classes
   1083      * of NumberFormat.
   1084      */
   1085     public boolean isParseIntegerOnly() {
   1086         return icuDecimalFormat.isParseIntegerOnly();
   1087     }
   1088 
   1089     /**
   1090      * Standard override; no change in semantics.
   1091      */
   1092     @Override
   1093     public Object clone() {
   1094         try {
   1095             DecimalFormat other = (DecimalFormat) super.clone();
   1096             other.icuDecimalFormat = (android.icu.text.DecimalFormat) icuDecimalFormat.clone();
   1097             other.symbols = (DecimalFormatSymbols) symbols.clone();
   1098             return other;
   1099         } catch (Exception e) {
   1100             throw new InternalError();
   1101         }
   1102     }
   1103 
   1104     /**
   1105      * Overrides equals
   1106      */
   1107     @Override
   1108     public boolean equals(Object obj)
   1109     {
   1110         if (obj == null) {
   1111             return false;
   1112         }
   1113         if (this == obj) {
   1114             return true;
   1115         }
   1116         if (!(obj instanceof DecimalFormat)) {
   1117             return false;
   1118         }
   1119         DecimalFormat other = (DecimalFormat) obj;
   1120         return icuDecimalFormat.equals(other.icuDecimalFormat)
   1121             && compareIcuRoundingIncrement(other.icuDecimalFormat);
   1122     }
   1123 
   1124     private boolean compareIcuRoundingIncrement(android.icu.text.DecimalFormat other) {
   1125         BigDecimal increment = this.icuDecimalFormat.getRoundingIncrement();
   1126         if (increment != null) {
   1127             return (other.getRoundingIncrement() != null)
   1128                 && increment.equals(other.getRoundingIncrement());
   1129         }
   1130         return other.getRoundingIncrement() == null;
   1131     }
   1132 
   1133     /**
   1134      * Overrides hashCode
   1135      */
   1136     @Override
   1137     public int hashCode() {
   1138         return super.hashCode() * 37 + getPositivePrefix().hashCode();
   1139         // just enough fields for a reasonable distribution
   1140     }
   1141 
   1142     /**
   1143      * Synthesizes a pattern string that represents the current state
   1144      * of this Format object.
   1145      *
   1146      * @return a pattern string
   1147      * @see #applyPattern
   1148      */
   1149     public String toPattern() {
   1150         return icuDecimalFormat.toPattern();
   1151     }
   1152 
   1153     /**
   1154      * Synthesizes a localized pattern string that represents the current
   1155      * state of this Format object.
   1156      *
   1157      * @return a localized pattern string
   1158      * @see #applyPattern
   1159      */
   1160     public String toLocalizedPattern() {
   1161         return icuDecimalFormat.toLocalizedPattern();
   1162     }
   1163 
   1164     /**
   1165      * Apply the given pattern to this Format object.  A pattern is a
   1166      * short-hand specification for the various formatting properties.
   1167      * These properties can also be changed individually through the
   1168      * various setter methods.
   1169      * <p>
   1170      * There is no limit to integer digits set
   1171      * by this routine, since that is the typical end-user desire;
   1172      * use setMaximumInteger if you want to set a real value.
   1173      * For negative numbers, use a second pattern, separated by a semicolon
   1174      * <P>Example <code>"#,#00.0#"</code> &rarr; 1,234.56
   1175      * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
   1176      * a maximum of 2 fraction digits.
   1177      * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
   1178      * parentheses.
   1179      * <p>In negative patterns, the minimum and maximum counts are ignored;
   1180      * these are presumed to be set in the positive pattern.
   1181      *
   1182      * @param pattern a new pattern
   1183      * @exception NullPointerException if <code>pattern</code> is null
   1184      * @exception IllegalArgumentException if the given pattern is invalid.
   1185      */
   1186     public void applyPattern(String pattern) {
   1187         icuDecimalFormat.applyPattern(pattern);
   1188         updateFieldsFromIcu();
   1189     }
   1190 
   1191 
   1192     /**
   1193      * Apply the given pattern to this Format object.  The pattern
   1194      * is assumed to be in a localized notation. A pattern is a
   1195      * short-hand specification for the various formatting properties.
   1196      * These properties can also be changed individually through the
   1197      * various setter methods.
   1198      * <p>
   1199      * There is no limit to integer digits set
   1200      * by this routine, since that is the typical end-user desire;
   1201      * use setMaximumInteger if you want to set a real value.
   1202      * For negative numbers, use a second pattern, separated by a semicolon
   1203      * <P>Example <code>"#,#00.0#"</code> &rarr; 1,234.56
   1204      * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
   1205      * a maximum of 2 fraction digits.
   1206      * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
   1207      * parentheses.
   1208      * <p>In negative patterns, the minimum and maximum counts are ignored;
   1209      * these are presumed to be set in the positive pattern.
   1210      *
   1211      * @param pattern a new pattern
   1212      * @exception NullPointerException if <code>pattern</code> is null
   1213      * @exception IllegalArgumentException if the given pattern is invalid.
   1214      */
   1215     public void applyLocalizedPattern(String pattern) {
   1216         icuDecimalFormat.applyLocalizedPattern(pattern);
   1217         updateFieldsFromIcu();
   1218     }
   1219 
   1220     private void updateFieldsFromIcu() {
   1221         // Imitate behaviour of ICU4C NumberFormat that Android used up to M.
   1222         // If the pattern doesn't enforce a different value (some exponential
   1223         // patterns do), then set the maximum integer digits to 2 billion.
   1224         if (icuDecimalFormat.getMaximumIntegerDigits() == DOUBLE_INTEGER_DIGITS) {
   1225             icuDecimalFormat.setMaximumIntegerDigits(2000000000);
   1226         }
   1227         maximumIntegerDigits = icuDecimalFormat.getMaximumIntegerDigits();
   1228         minimumIntegerDigits = icuDecimalFormat.getMinimumIntegerDigits();
   1229         maximumFractionDigits = icuDecimalFormat.getMaximumFractionDigits();
   1230         minimumFractionDigits = icuDecimalFormat.getMinimumFractionDigits();
   1231     }
   1232 
   1233     /**
   1234      * Sets the maximum number of digits allowed in the integer portion of a
   1235      * number.
   1236      * For formatting numbers other than <code>BigInteger</code> and
   1237      * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
   1238      * 309 is used. Negative input values are replaced with 0.
   1239      * @see NumberFormat#setMaximumIntegerDigits
   1240      */
   1241     @Override
   1242     public void setMaximumIntegerDigits(int newValue) {
   1243         maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
   1244         super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
   1245             DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
   1246         if (minimumIntegerDigits > maximumIntegerDigits) {
   1247             minimumIntegerDigits = maximumIntegerDigits;
   1248             super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
   1249                 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
   1250         }
   1251         icuDecimalFormat.setMaximumIntegerDigits(getMaximumIntegerDigits());
   1252     }
   1253 
   1254     /**
   1255      * Sets the minimum number of digits allowed in the integer portion of a
   1256      * number.
   1257      * For formatting numbers other than <code>BigInteger</code> and
   1258      * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
   1259      * 309 is used. Negative input values are replaced with 0.
   1260      * @see NumberFormat#setMinimumIntegerDigits
   1261      */
   1262     @Override
   1263     public void setMinimumIntegerDigits(int newValue) {
   1264         minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
   1265         super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
   1266             DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
   1267         if (minimumIntegerDigits > maximumIntegerDigits) {
   1268             maximumIntegerDigits = minimumIntegerDigits;
   1269             super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
   1270                 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
   1271         }
   1272         icuDecimalFormat.setMinimumIntegerDigits(getMinimumIntegerDigits());
   1273     }
   1274 
   1275     /**
   1276      * Sets the maximum number of digits allowed in the fraction portion of a
   1277      * number.
   1278      * For formatting numbers other than <code>BigInteger</code> and
   1279      * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
   1280      * 340 is used. Negative input values are replaced with 0.
   1281      * @see NumberFormat#setMaximumFractionDigits
   1282      */
   1283     @Override
   1284     public void setMaximumFractionDigits(int newValue) {
   1285         maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
   1286         super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
   1287             DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
   1288         if (minimumFractionDigits > maximumFractionDigits) {
   1289             minimumFractionDigits = maximumFractionDigits;
   1290             super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
   1291                 DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
   1292         }
   1293         icuDecimalFormat.setMaximumFractionDigits(getMaximumFractionDigits());
   1294     }
   1295 
   1296     /**
   1297      * Sets the minimum number of digits allowed in the fraction portion of a
   1298      * number.
   1299      * For formatting numbers other than <code>BigInteger</code> and
   1300      * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
   1301      * 340 is used. Negative input values are replaced with 0.
   1302      * @see NumberFormat#setMinimumFractionDigits
   1303      */
   1304     @Override
   1305     public void setMinimumFractionDigits(int newValue) {
   1306         minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
   1307         super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
   1308             DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
   1309         if (minimumFractionDigits > maximumFractionDigits) {
   1310             maximumFractionDigits = minimumFractionDigits;
   1311             super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
   1312                 DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
   1313         }
   1314         icuDecimalFormat.setMinimumFractionDigits(getMinimumFractionDigits());
   1315     }
   1316 
   1317     /**
   1318      * Gets the maximum number of digits allowed in the integer portion of a
   1319      * number.
   1320      * For formatting numbers other than <code>BigInteger</code> and
   1321      * <code>BigDecimal</code> objects, the lower of the return value and
   1322      * 309 is used.
   1323      * @see #setMaximumIntegerDigits
   1324      */
   1325     @Override
   1326     public int getMaximumIntegerDigits() {
   1327         return maximumIntegerDigits;
   1328     }
   1329 
   1330     /**
   1331      * Gets the minimum number of digits allowed in the integer portion of a
   1332      * number.
   1333      * For formatting numbers other than <code>BigInteger</code> and
   1334      * <code>BigDecimal</code> objects, the lower of the return value and
   1335      * 309 is used.
   1336      * @see #setMinimumIntegerDigits
   1337      */
   1338     @Override
   1339     public int getMinimumIntegerDigits() {
   1340         return minimumIntegerDigits;
   1341     }
   1342 
   1343     /**
   1344      * Gets the maximum number of digits allowed in the fraction portion of a
   1345      * number.
   1346      * For formatting numbers other than <code>BigInteger</code> and
   1347      * <code>BigDecimal</code> objects, the lower of the return value and
   1348      * 340 is used.
   1349      * @see #setMaximumFractionDigits
   1350      */
   1351     @Override
   1352     public int getMaximumFractionDigits() {
   1353         return maximumFractionDigits;
   1354     }
   1355 
   1356     /**
   1357      * Gets the minimum number of digits allowed in the fraction portion of a
   1358      * number.
   1359      * For formatting numbers other than <code>BigInteger</code> and
   1360      * <code>BigDecimal</code> objects, the lower of the return value and
   1361      * 340 is used.
   1362      * @see #setMinimumFractionDigits
   1363      */
   1364     @Override
   1365     public int getMinimumFractionDigits() {
   1366         return minimumFractionDigits;
   1367     }
   1368 
   1369     /**
   1370      * Gets the currency used by this decimal format when formatting
   1371      * currency values.
   1372      * The currency is obtained by calling
   1373      * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency}
   1374      * on this number format's symbols.
   1375      *
   1376      * @return the currency used by this decimal format, or <code>null</code>
   1377      * @since 1.4
   1378      */
   1379     @Override
   1380     public Currency getCurrency() {
   1381         return symbols.getCurrency();
   1382     }
   1383 
   1384     /**
   1385      * Sets the currency used by this number format when formatting
   1386      * currency values. This does not update the minimum or maximum
   1387      * number of fraction digits used by the number format.
   1388      * The currency is set by calling
   1389      * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency}
   1390      * on this number format's symbols.
   1391      *
   1392      * @param currency the new currency to be used by this decimal format
   1393      * @exception NullPointerException if <code>currency</code> is null
   1394      * @since 1.4
   1395      */
   1396     @Override
   1397     public void setCurrency(Currency currency) {
   1398         // Set the international currency symbol, and currency symbol on the DecimalFormatSymbols
   1399         // object and tell ICU to use that.
   1400         if (currency != symbols.getCurrency()
   1401             || !currency.getSymbol().equals(symbols.getCurrencySymbol())) {
   1402             symbols.setCurrency(currency);
   1403             icuDecimalFormat.setDecimalFormatSymbols(symbols.getIcuDecimalFormatSymbols());
   1404             // Giving the icuDecimalFormat a new currency will cause the fractional digits to be
   1405             // updated. This class is specified to not touch the fraction digits, so we re-set them.
   1406             icuDecimalFormat.setMinimumFractionDigits(minimumFractionDigits);
   1407             icuDecimalFormat.setMaximumFractionDigits(maximumFractionDigits);
   1408         }
   1409     }
   1410 
   1411     /**
   1412      * Gets the {@link java.math.RoundingMode} used in this DecimalFormat.
   1413      *
   1414      * @return The <code>RoundingMode</code> used for this DecimalFormat.
   1415      * @see #setRoundingMode(RoundingMode)
   1416      * @since 1.6
   1417      */
   1418     @Override
   1419     public RoundingMode getRoundingMode() {
   1420         return roundingMode;
   1421     }
   1422 
   1423     private static int convertRoundingMode(RoundingMode rm) {
   1424         switch (rm) {
   1425         case UP:
   1426             return MathContext.ROUND_UP;
   1427         case DOWN:
   1428             return MathContext.ROUND_DOWN;
   1429         case CEILING:
   1430             return MathContext.ROUND_CEILING;
   1431         case FLOOR:
   1432             return MathContext.ROUND_FLOOR;
   1433         case HALF_UP:
   1434             return MathContext.ROUND_HALF_UP;
   1435         case HALF_DOWN:
   1436             return MathContext.ROUND_HALF_DOWN;
   1437         case HALF_EVEN:
   1438             return MathContext.ROUND_HALF_EVEN;
   1439         case UNNECESSARY:
   1440             return MathContext.ROUND_UNNECESSARY;
   1441         }
   1442         throw new IllegalArgumentException("Invalid rounding mode specified");
   1443     }
   1444 
   1445     /**
   1446      * Sets the {@link java.math.RoundingMode} used in this DecimalFormat.
   1447      *
   1448      * @param roundingMode The <code>RoundingMode</code> to be used
   1449      * @see #getRoundingMode()
   1450      * @exception NullPointerException if <code>roundingMode</code> is null.
   1451      * @since 1.6
   1452      */
   1453     @Override
   1454     public void setRoundingMode(RoundingMode roundingMode) {
   1455         if (roundingMode == null) {
   1456             throw new NullPointerException();
   1457         }
   1458 
   1459         this.roundingMode = roundingMode;
   1460 
   1461         icuDecimalFormat.setRoundingMode(convertRoundingMode(roundingMode));
   1462     }
   1463 
   1464     /**
   1465      * Adjusts the minimum and maximum fraction digits to values that
   1466      * are reasonable for the currency's default fraction digits.
   1467      */
   1468     void adjustForCurrencyDefaultFractionDigits() {
   1469         Currency currency = symbols.getCurrency();
   1470         if (currency == null) {
   1471             try {
   1472                 currency = Currency.getInstance(symbols.getInternationalCurrencySymbol());
   1473             } catch (IllegalArgumentException e) {
   1474             }
   1475         }
   1476         if (currency != null) {
   1477             int digits = currency.getDefaultFractionDigits();
   1478             if (digits != -1) {
   1479                 int oldMinDigits = getMinimumFractionDigits();
   1480                 // Common patterns are "#.##", "#.00", "#".
   1481                 // Try to adjust all of them in a reasonable way.
   1482                 if (oldMinDigits == getMaximumFractionDigits()) {
   1483                     setMinimumFractionDigits(digits);
   1484                     setMaximumFractionDigits(digits);
   1485                 } else {
   1486                     setMinimumFractionDigits(Math.min(digits, oldMinDigits));
   1487                     setMaximumFractionDigits(digits);
   1488                 }
   1489             }
   1490         }
   1491     }
   1492 
   1493     private static final int currentSerialVersion = 4;
   1494 
   1495     // the fields list to be serialized
   1496     private static final ObjectStreamField[] serialPersistentFields = {
   1497             new ObjectStreamField("positivePrefix", String.class),
   1498             new ObjectStreamField("positiveSuffix", String.class),
   1499             new ObjectStreamField("negativePrefix", String.class),
   1500             new ObjectStreamField("negativeSuffix", String.class),
   1501             new ObjectStreamField("posPrefixPattern", String.class),
   1502             new ObjectStreamField("posSuffixPattern", String.class),
   1503             new ObjectStreamField("negPrefixPattern", String.class),
   1504             new ObjectStreamField("negSuffixPattern", String.class),
   1505             new ObjectStreamField("multiplier", int.class),
   1506             new ObjectStreamField("groupingSize", byte.class),
   1507             new ObjectStreamField("groupingUsed", boolean.class),
   1508             new ObjectStreamField("decimalSeparatorAlwaysShown", boolean.class),
   1509             new ObjectStreamField("parseBigDecimal", boolean.class),
   1510             new ObjectStreamField("roundingMode", RoundingMode.class),
   1511             new ObjectStreamField("symbols", DecimalFormatSymbols.class),
   1512             new ObjectStreamField("useExponentialNotation", boolean.class),
   1513             new ObjectStreamField("minExponentDigits", byte.class),
   1514             new ObjectStreamField("maximumIntegerDigits", int.class),
   1515             new ObjectStreamField("minimumIntegerDigits", int.class),
   1516             new ObjectStreamField("maximumFractionDigits", int.class),
   1517             new ObjectStreamField("minimumFractionDigits", int.class),
   1518             new ObjectStreamField("serialVersionOnStream", int.class),
   1519     };
   1520 
   1521     private void writeObject(ObjectOutputStream stream) throws IOException, ClassNotFoundException {
   1522         ObjectOutputStream.PutField fields = stream.putFields();
   1523         fields.put("positivePrefix", icuDecimalFormat.getPositivePrefix());
   1524         fields.put("positiveSuffix", icuDecimalFormat.getPositiveSuffix());
   1525         fields.put("negativePrefix", icuDecimalFormat.getNegativePrefix());
   1526         fields.put("negativeSuffix", icuDecimalFormat.getNegativeSuffix());
   1527         fields.put("posPrefixPattern", (String) null);
   1528         fields.put("posSuffixPattern", (String) null);
   1529         fields.put("negPrefixPattern", (String) null);
   1530         fields.put("negSuffixPattern", (String) null);
   1531         fields.put("multiplier", icuDecimalFormat.getMultiplier());
   1532         fields.put("groupingSize", (byte) icuDecimalFormat.getGroupingSize());
   1533         fields.put("groupingUsed", icuDecimalFormat.isGroupingUsed());
   1534         fields.put("decimalSeparatorAlwaysShown", icuDecimalFormat.isDecimalSeparatorAlwaysShown());
   1535         fields.put("parseBigDecimal", icuDecimalFormat.isParseBigDecimal());
   1536         fields.put("roundingMode", roundingMode);
   1537         fields.put("symbols", symbols);
   1538         fields.put("useExponentialNotation", false);
   1539         fields.put("minExponentDigits", (byte) 0);
   1540         fields.put("maximumIntegerDigits", icuDecimalFormat.getMaximumIntegerDigits());
   1541         fields.put("minimumIntegerDigits", icuDecimalFormat.getMinimumIntegerDigits());
   1542         fields.put("maximumFractionDigits", icuDecimalFormat.getMaximumFractionDigits());
   1543         fields.put("minimumFractionDigits", icuDecimalFormat.getMinimumFractionDigits());
   1544         fields.put("serialVersionOnStream", currentSerialVersion);
   1545         stream.writeFields();
   1546     }
   1547 
   1548     /**
   1549      * Reads the default serializable fields from the stream and performs
   1550      * validations and adjustments for older serialized versions. The
   1551      * validations and adjustments are:
   1552      * <ol>
   1553      * <li>
   1554      * Verify that the superclass's digit count fields correctly reflect
   1555      * the limits imposed on formatting numbers other than
   1556      * <code>BigInteger</code> and <code>BigDecimal</code> objects. These
   1557      * limits are stored in the superclass for serialization compatibility
   1558      * with older versions, while the limits for <code>BigInteger</code> and
   1559      * <code>BigDecimal</code> objects are kept in this class.
   1560      * If, in the superclass, the minimum or maximum integer digit count is
   1561      * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or
   1562      * maximum fraction digit count is larger than
   1563      * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid
   1564      * and this method throws an <code>InvalidObjectException</code>.
   1565      * <li>
   1566      * If <code>serialVersionOnStream</code> is less than 4, initialize
   1567      * <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN
   1568      * RoundingMode.HALF_EVEN}.  This field is new with version 4.
   1569      * <li>
   1570      * If <code>serialVersionOnStream</code> is less than 3, then call
   1571      * the setters for the minimum and maximum integer and fraction digits with
   1572      * the values of the corresponding superclass getters to initialize the
   1573      * fields in this class. The fields in this class are new with version 3.
   1574      * <li>
   1575      * If <code>serialVersionOnStream</code> is less than 1, indicating that
   1576      * the stream was written by JDK 1.1, initialize
   1577      * <code>useExponentialNotation</code>
   1578      * to false, since it was not present in JDK 1.1.
   1579      * <li>
   1580      * Set <code>serialVersionOnStream</code> to the maximum allowed value so
   1581      * that default serialization will work properly if this object is streamed
   1582      * out again.
   1583      * </ol>
   1584      *
   1585      * <p>Stream versions older than 2 will not have the affix pattern variables
   1586      * <code>posPrefixPattern</code> etc.  As a result, they will be initialized
   1587      * to <code>null</code>, which means the affix strings will be taken as
   1588      * literal values.  This is exactly what we want, since that corresponds to
   1589      * the pre-version-2 behavior.
   1590      */
   1591     private void readObject(ObjectInputStream stream)
   1592             throws IOException, ClassNotFoundException {
   1593         ObjectInputStream.GetField fields = stream.readFields();
   1594         this.symbols = (DecimalFormatSymbols) fields.get("symbols", null);
   1595 
   1596         init("");
   1597 
   1598         icuDecimalFormat.setPositivePrefix((String) fields.get("positivePrefix", ""));
   1599         icuDecimalFormat.setPositiveSuffix((String) fields.get("positiveSuffix", ""));
   1600         icuDecimalFormat.setNegativePrefix((String) fields.get("negativePrefix", "-"));
   1601         icuDecimalFormat.setNegativeSuffix((String) fields.get("negativeSuffix", ""));
   1602         icuDecimalFormat.setMultiplier(fields.get("multiplier", 1));
   1603         icuDecimalFormat.setGroupingSize(fields.get("groupingSize", (byte) 3));
   1604         icuDecimalFormat.setGroupingUsed(fields.get("groupingUsed", true));
   1605         icuDecimalFormat.setDecimalSeparatorAlwaysShown(fields.get("decimalSeparatorAlwaysShown",
   1606                 false));
   1607 
   1608         setRoundingMode((RoundingMode) fields.get("roundingMode", RoundingMode.HALF_EVEN));
   1609 
   1610         final int maximumIntegerDigits = fields.get("maximumIntegerDigits", 309);
   1611         final int minimumIntegerDigits = fields.get("minimumIntegerDigits", 309);
   1612         final int maximumFractionDigits = fields.get("maximumFractionDigits", 340);
   1613         final int minimumFractionDigits = fields.get("minimumFractionDigits", 340);
   1614         // Tell ICU what we want, then ask it what we can have, and then
   1615         // set that in our Java object. This isn't RI-compatible, but then very little of our
   1616         // behavior in this area is, and it's not obvious how we can second-guess ICU (or tell
   1617         // it to just do exactly what we ask). We only need to do this with maximumIntegerDigits
   1618         // because ICU doesn't seem to have its own ideas about the other options.
   1619         icuDecimalFormat.setMaximumIntegerDigits(maximumIntegerDigits);
   1620         super.setMaximumIntegerDigits(icuDecimalFormat.getMaximumIntegerDigits());
   1621 
   1622         setMinimumIntegerDigits(minimumIntegerDigits);
   1623         setMinimumFractionDigits(minimumFractionDigits);
   1624         setMaximumFractionDigits(maximumFractionDigits);
   1625         setParseBigDecimal(fields.get("parseBigDecimal", false));
   1626 
   1627         if (fields.get("serialVersionOnStream", 0) < 3) {
   1628             setMaximumIntegerDigits(super.getMaximumIntegerDigits());
   1629             setMinimumIntegerDigits(super.getMinimumIntegerDigits());
   1630             setMaximumFractionDigits(super.getMaximumFractionDigits());
   1631             setMinimumFractionDigits(super.getMinimumFractionDigits());
   1632         }
   1633     }
   1634 
   1635     //----------------------------------------------------------------------
   1636     // INSTANCE VARIABLES
   1637     //----------------------------------------------------------------------
   1638 
   1639     /**
   1640      * The <code>DecimalFormatSymbols</code> object used by this format.
   1641      * It contains the symbols used to format numbers, e.g. the grouping separator,
   1642      * decimal separator, and so on.
   1643      *
   1644      * @serial
   1645      * @see #setDecimalFormatSymbols
   1646      * @see java.text.DecimalFormatSymbols
   1647      */
   1648     private DecimalFormatSymbols symbols;
   1649 
   1650     /**
   1651      * The maximum number of digits allowed in the integer portion of a
   1652      * <code>BigInteger</code> or <code>BigDecimal</code> number.
   1653      * <code>maximumIntegerDigits</code> must be greater than or equal to
   1654      * <code>minimumIntegerDigits</code>.
   1655      *
   1656      * @serial
   1657      * @see #getMaximumIntegerDigits
   1658      * @since 1.5
   1659      */
   1660     private int    maximumIntegerDigits;
   1661 
   1662     /**
   1663      * The minimum number of digits allowed in the integer portion of a
   1664      * <code>BigInteger</code> or <code>BigDecimal</code> number.
   1665      * <code>minimumIntegerDigits</code> must be less than or equal to
   1666      * <code>maximumIntegerDigits</code>.
   1667      *
   1668      * @serial
   1669      * @see #getMinimumIntegerDigits
   1670      * @since 1.5
   1671      */
   1672     private int    minimumIntegerDigits;
   1673 
   1674     /**
   1675      * The maximum number of digits allowed in the fractional portion of a
   1676      * <code>BigInteger</code> or <code>BigDecimal</code> number.
   1677      * <code>maximumFractionDigits</code> must be greater than or equal to
   1678      * <code>minimumFractionDigits</code>.
   1679      *
   1680      * @serial
   1681      * @see #getMaximumFractionDigits
   1682      * @since 1.5
   1683      */
   1684     private int    maximumFractionDigits;
   1685 
   1686     /**
   1687      * The minimum number of digits allowed in the fractional portion of a
   1688      * <code>BigInteger</code> or <code>BigDecimal</code> number.
   1689      * <code>minimumFractionDigits</code> must be less than or equal to
   1690      * <code>maximumFractionDigits</code>.
   1691      *
   1692      * @serial
   1693      * @see #getMinimumFractionDigits
   1694      * @since 1.5
   1695      */
   1696     private int    minimumFractionDigits;
   1697 
   1698     /**
   1699      * The {@link java.math.RoundingMode} used in this DecimalFormat.
   1700      *
   1701      * @serial
   1702      * @since 1.6
   1703      */
   1704     private RoundingMode roundingMode = RoundingMode.HALF_EVEN;
   1705 
   1706 
   1707 
   1708     //----------------------------------------------------------------------
   1709     // CONSTANTS
   1710     //----------------------------------------------------------------------
   1711 
   1712     // Upper limit on integer and fraction digits for a Java double
   1713     static final int DOUBLE_INTEGER_DIGITS  = 309;
   1714     static final int DOUBLE_FRACTION_DIGITS = 340;
   1715 
   1716     // Upper limit on integer and fraction digits for BigDecimal and BigInteger
   1717     static final int MAXIMUM_INTEGER_DIGITS  = Integer.MAX_VALUE;
   1718     static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE;
   1719 
   1720     // Proclaim JDK 1.1 serial compatibility.
   1721     static final long serialVersionUID = 864413376551465018L;
   1722 
   1723     /**
   1724      * Cache to hold the NumberPattern of a Locale.
   1725      */
   1726     private static final ConcurrentMap<Locale, String> cachedLocaleData
   1727         = new ConcurrentHashMap<Locale, String>(3);
   1728 }
   1729