Source Code Cross Referenced for DecimalFormat.java in  » 6.0-JDK-Core » text » java » text » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » text » java.text 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        /*
0027         * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
0028         * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
0029         *
0030         *   The original version of this source code and documentation is copyrighted
0031         * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
0032         * materials are provided under terms of a License Agreement between Taligent
0033         * and Sun. This technology is protected by multiple US and International
0034         * patents. This notice and attribution to Taligent may not be removed.
0035         *   Taligent is a registered trademark of Taligent, Inc.
0036         *
0037         */
0038
0039        package java.text;
0040
0041        import java.io.InvalidObjectException;
0042        import java.io.IOException;
0043        import java.io.ObjectInputStream;
0044        import java.math.BigDecimal;
0045        import java.math.BigInteger;
0046        import java.math.RoundingMode;
0047        import java.util.ArrayList;
0048        import java.util.Currency;
0049        import java.util.Hashtable;
0050        import java.util.Locale;
0051        import java.util.ResourceBundle;
0052        import java.util.concurrent.atomic.AtomicInteger;
0053        import java.util.concurrent.atomic.AtomicLong;
0054        import sun.util.resources.LocaleData;
0055
0056        /**
0057         * <code>DecimalFormat</code> is a concrete subclass of
0058         * <code>NumberFormat</code> that formats decimal numbers. It has a variety of
0059         * features designed to make it possible to parse and format numbers in any
0060         * locale, including support for Western, Arabic, and Indic digits.  It also
0061         * supports different kinds of numbers, including integers (123), fixed-point
0062         * numbers (123.4), scientific notation (1.23E4), percentages (12%), and
0063         * currency amounts ($123).  All of these can be localized.
0064         *
0065         * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the
0066         * default locale, call one of <code>NumberFormat</code>'s factory methods, such
0067         * as <code>getInstance()</code>.  In general, do not call the
0068         * <code>DecimalFormat</code> constructors directly, since the
0069         * <code>NumberFormat</code> factory methods may return subclasses other than
0070         * <code>DecimalFormat</code>. If you need to customize the format object, do
0071         * something like this:
0072         *
0073         * <blockquote><pre>
0074         * NumberFormat f = NumberFormat.getInstance(loc);
0075         * if (f instanceof DecimalFormat) {
0076         *     ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
0077         * }
0078         * </pre></blockquote>
0079         *
0080         * <p>A <code>DecimalFormat</code> comprises a <em>pattern</em> and a set of
0081         * <em>symbols</em>.  The pattern may be set directly using
0082         * <code>applyPattern()</code>, or indirectly using the API methods.  The
0083         * symbols are stored in a <code>DecimalFormatSymbols</code> object.  When using
0084         * the <code>NumberFormat</code> factory methods, the pattern and symbols are
0085         * read from localized <code>ResourceBundle</code>s.
0086         *
0087         * <h4>Patterns</h4>
0088         *
0089         * <code>DecimalFormat</code> patterns have the following syntax:
0090         * <blockquote><pre>
0091         * <i>Pattern:</i>
0092         *         <i>PositivePattern</i>
0093         *         <i>PositivePattern</i> ; <i>NegativePattern</i>
0094         * <i>PositivePattern:</i>
0095         *         <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
0096         * <i>NegativePattern:</i>
0097         *         <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
0098         * <i>Prefix:</i>
0099         *         any Unicode characters except &#92;uFFFE, &#92;uFFFF, and special characters
0100         * <i>Suffix:</i>
0101         *         any Unicode characters except &#92;uFFFE, &#92;uFFFF, and special characters
0102         * <i>Number:</i>
0103         *         <i>Integer</i> <i>Exponent<sub>opt</sub></i>
0104         *         <i>Integer</i> . <i>Fraction</i> <i>Exponent<sub>opt</sub></i>
0105         * <i>Integer:</i>
0106         *         <i>MinimumInteger</i>
0107         *         #
0108         *         # <i>Integer</i>
0109         *         # , <i>Integer</i>
0110         * <i>MinimumInteger:</i>
0111         *         0
0112         *         0 <i>MinimumInteger</i>
0113         *         0 , <i>MinimumInteger</i>
0114         * <i>Fraction:</i>
0115         *         <i>MinimumFraction<sub>opt</sub></i> <i>OptionalFraction<sub>opt</sub></i>
0116         * <i>MinimumFraction:</i>
0117         *         0 <i>MinimumFraction<sub>opt</sub></i>
0118         * <i>OptionalFraction:</i>
0119         *         # <i>OptionalFraction<sub>opt</sub></i>
0120         * <i>Exponent:</i>
0121         *         E <i>MinimumExponent</i>
0122         * <i>MinimumExponent:</i>
0123         *         0 <i>MinimumExponent<sub>opt</sub></i>
0124         * </pre></blockquote>
0125         *
0126         * <p>A <code>DecimalFormat</code> pattern contains a positive and negative
0127         * subpattern, for example, <code>"#,##0.00;(#,##0.00)"</code>.  Each
0128         * subpattern has a prefix, numeric part, and suffix. The negative subpattern
0129         * is optional; if absent, then the positive subpattern prefixed with the
0130         * localized minus sign (<code>'-'</code> in most locales) is used as the
0131         * negative subpattern. That is, <code>"0.00"</code> alone is equivalent to
0132         * <code>"0.00;-0.00"</code>.  If there is an explicit negative subpattern, it
0133         * serves only to specify the negative prefix and suffix; the number of digits,
0134         * minimal digits, and other characteristics are all the same as the positive
0135         * pattern. That means that <code>"#,##0.0#;(#)"</code> produces precisely
0136         * the same behavior as <code>"#,##0.0#;(#,##0.0#)"</code>.
0137         *
0138         * <p>The prefixes, suffixes, and various symbols used for infinity, digits,
0139         * thousands separators, decimal separators, etc. may be set to arbitrary
0140         * values, and they will appear properly during formatting.  However, care must
0141         * be taken that the symbols and strings do not conflict, or parsing will be
0142         * unreliable.  For example, either the positive and negative prefixes or the
0143         * suffixes must be distinct for <code>DecimalFormat.parse()</code> to be able
0144         * to distinguish positive from negative values.  (If they are identical, then
0145         * <code>DecimalFormat</code> will behave as if no negative subpattern was
0146         * specified.)  Another example is that the decimal separator and thousands
0147         * separator should be distinct characters, or parsing will be impossible.
0148         *
0149         * <p>The grouping separator is commonly used for thousands, but in some
0150         * countries it separates ten-thousands. The grouping size is a constant number
0151         * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for
0152         * 1,0000,0000.  If you supply a pattern with multiple grouping characters, the
0153         * interval between the last one and the end of the integer is the one that is
0154         * used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> ==
0155         * <code>"##,####,####"</code>.
0156         *
0157         * <h4>Special Pattern Characters</h4>
0158         *
0159         * <p>Many characters in a pattern are taken literally; they are matched during
0160         * parsing and output unchanged during formatting.  Special characters, on the
0161         * other hand, stand for other characters, strings, or classes of characters.
0162         * They must be quoted, unless noted otherwise, if they are to appear in the
0163         * prefix or suffix as literals.
0164         *
0165         * <p>The characters listed here are used in non-localized patterns.  Localized
0166         * patterns use the corresponding characters taken from this formatter's
0167         * <code>DecimalFormatSymbols</code> object instead, and these characters lose
0168         * their special status.  Two exceptions are the currency sign and quote, which
0169         * are not localized.
0170         *
0171         * <blockquote>
0172         * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol,
0173         *  location, localized, and meaning.">
0174         *     <tr bgcolor="#ccccff">
0175         *          <th align=left>Symbol
0176         *          <th align=left>Location
0177         *          <th align=left>Localized?
0178         *          <th align=left>Meaning
0179         *     <tr valign=top>
0180         *          <td><code>0</code>
0181         *          <td>Number
0182         *          <td>Yes
0183         *          <td>Digit
0184         *     <tr valign=top bgcolor="#eeeeff">
0185         *          <td><code>#</code>
0186         *          <td>Number
0187         *          <td>Yes
0188         *          <td>Digit, zero shows as absent
0189         *     <tr valign=top>
0190         *          <td><code>.</code>
0191         *          <td>Number
0192         *          <td>Yes
0193         *          <td>Decimal separator or monetary decimal separator
0194         *     <tr valign=top bgcolor="#eeeeff">
0195         *          <td><code>-</code>
0196         *          <td>Number
0197         *          <td>Yes
0198         *          <td>Minus sign
0199         *     <tr valign=top>
0200         *          <td><code>,</code>
0201         *          <td>Number
0202         *          <td>Yes
0203         *          <td>Grouping separator
0204         *     <tr valign=top bgcolor="#eeeeff">
0205         *          <td><code>E</code>
0206         *          <td>Number
0207         *          <td>Yes
0208         *          <td>Separates mantissa and exponent in scientific notation.
0209         *              <em>Need not be quoted in prefix or suffix.</em>
0210         *     <tr valign=top>
0211         *          <td><code>;</code>
0212         *          <td>Subpattern boundary
0213         *          <td>Yes
0214         *          <td>Separates positive and negative subpatterns
0215         *     <tr valign=top bgcolor="#eeeeff">
0216         *          <td><code>%</code>
0217         *          <td>Prefix or suffix
0218         *          <td>Yes
0219         *          <td>Multiply by 100 and show as percentage
0220         *     <tr valign=top>
0221         *          <td><code>&#92;u2030</code>
0222         *          <td>Prefix or suffix
0223         *          <td>Yes
0224         *          <td>Multiply by 1000 and show as per mille value
0225         *     <tr valign=top bgcolor="#eeeeff">
0226         *          <td><code>&#164;</code> (<code>&#92;u00A4</code>)
0227         *          <td>Prefix or suffix
0228         *          <td>No
0229         *          <td>Currency sign, replaced by currency symbol.  If
0230         *              doubled, replaced by international currency symbol.
0231         *              If present in a pattern, the monetary decimal separator
0232         *              is used instead of the decimal separator.
0233         *     <tr valign=top>
0234         *          <td><code>'</code>
0235         *          <td>Prefix or suffix
0236         *          <td>No
0237         *          <td>Used to quote special characters in a prefix or suffix,
0238         *              for example, <code>"'#'#"</code> formats 123 to
0239         *              <code>"#123"</code>.  To create a single quote
0240         *              itself, use two in a row: <code>"# o''clock"</code>.
0241         * </table>
0242         * </blockquote>
0243         *
0244         * <h4>Scientific Notation</h4>
0245         *
0246         * <p>Numbers in scientific notation are expressed as the product of a mantissa
0247         * and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3.  The
0248         * mantissa is often in the range 1.0 <= x < 10.0, but it need not be.
0249         * <code>DecimalFormat</code> can be instructed to format and parse scientific
0250         * notation <em>only via a pattern</em>; there is currently no factory method
0251         * that creates a scientific notation format.  In a pattern, the exponent
0252         * character immediately followed by one or more digit characters indicates
0253         * scientific notation.  Example: <code>"0.###E0"</code> formats the number
0254         * 1234 as <code>"1.234E3"</code>.
0255         *
0256         * <ul>
0257         * <li>The number of digit characters after the exponent character gives the
0258         * minimum exponent digit count.  There is no maximum.  Negative exponents are
0259         * formatted using the localized minus sign, <em>not</em> the prefix and suffix
0260         * from the pattern.  This allows patterns such as <code>"0.###E0 m/s"</code>.
0261         *
0262         * <li>The minimum and maximum number of integer digits are interpreted
0263         * together:
0264         *
0265         * <ul>
0266         * <li>If the maximum number of integer digits is greater than their minimum number
0267         * and greater than 1, it forces the exponent to be a multiple of the maximum
0268         * number of integer digits, and the minimum number of integer digits to be
0269         * interpreted as 1.  The most common use of this is to generate
0270         * <em>engineering notation</em>, in which the exponent is a multiple of three,
0271         * e.g., <code>"##0.#####E0"</code>. Using this pattern, the number 12345
0272         * formats to <code>"12.345E3"</code>, and 123456 formats to
0273         * <code>"123.456E3"</code>.
0274         *
0275         * <li>Otherwise, the minimum number of integer digits is achieved by adjusting the
0276         * exponent.  Example: 0.00123 formatted with <code>"00.###E0"</code> yields
0277         * <code>"12.3E-4"</code>.
0278         * </ul>
0279         *
0280         * <li>The number of significant digits in the mantissa is the sum of the
0281         * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is
0282         * unaffected by the maximum integer digits.  For example, 12345 formatted with
0283         * <code>"##0.##E0"</code> is <code>"12.3E3"</code>. To show all digits, set
0284         * the significant digits count to zero.  The number of significant digits
0285         * does not affect parsing.
0286         *
0287         * <li>Exponential patterns may not contain grouping separators.
0288         * </ul>
0289         *
0290         * <h4>Rounding</h4>
0291         *
0292         * <code>DecimalFormat</code> provides rounding modes defined in 
0293         * {@link java.math.RoundingMode} for formatting.  By default, it uses 
0294         * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
0295         *
0296         * <h4>Digits</h4>
0297         *
0298         * For formatting, <code>DecimalFormat</code> uses the ten consecutive
0299         * characters starting with the localized zero digit defined in the
0300         * <code>DecimalFormatSymbols</code> object as digits. For parsing, these
0301         * digits as well as all Unicode decimal digits, as defined by
0302         * {@link Character#digit Character.digit}, are recognized.
0303         *
0304         * <h4>Special Values</h4>
0305         *
0306         * <p><code>NaN</code> is formatted as a string, which typically has a single character 
0307         * <code>&#92;uFFFD</code>.  This string is determined by the
0308         * <code>DecimalFormatSymbols</code> object.  This is the only value for which
0309         * the prefixes and suffixes are not used.
0310         *
0311         * <p>Infinity is formatted as a string, which typically has a single character 
0312         * <code>&#92;u221E</code>, with the positive or negative prefixes and suffixes
0313         * applied.  The infinity string is determined by the
0314         * <code>DecimalFormatSymbols</code> object.
0315         *
0316         * <p>Negative zero (<code>"-0"</code>) parses to
0317         * <ul>
0318         * <li><code>BigDecimal(0)</code> if <code>isParseBigDecimal()</code> is
0319         * true,
0320         * <li><code>Long(0)</code> if <code>isParseBigDecimal()</code> is false
0321         *     and <code>isParseIntegerOnly()</code> is true,
0322         * <li><code>Double(-0.0)</code> if both <code>isParseBigDecimal()</code>
0323         * and <code>isParseIntegerOnly()</code> are false.
0324         * </ul>
0325         *
0326         * <h4><a name="synchronization">Synchronization</a></h4>
0327         *
0328         * <p>
0329         * Decimal formats are generally not synchronized.
0330         * It is recommended to create separate format instances for each thread.
0331         * If multiple threads access a format concurrently, it must be synchronized
0332         * externally.
0333         *
0334         * <h4>Example</h4>
0335         *
0336         * <blockquote><pre>
0337         * <strong>// Print out a number using the localized number, integer, currency,
0338         * // and percent format for each locale</strong>
0339         * Locale[] locales = NumberFormat.getAvailableLocales();
0340         * double myNumber = -1234.56;
0341         * NumberFormat form;
0342         * for (int j=0; j<4; ++j) {
0343         *     System.out.println("FORMAT");
0344         *     for (int i = 0; i < locales.length; ++i) {
0345         *         if (locales[i].getCountry().length() == 0) {
0346         *            continue; // Skip language-only locales
0347         *         }
0348         *         System.out.print(locales[i].getDisplayName());
0349         *         switch (j) {
0350         *         case 0:
0351         *             form = NumberFormat.getInstance(locales[i]); break;
0352         *         case 1:
0353         *             form = NumberFormat.getIntegerInstance(locales[i]); break;
0354         *         case 2:
0355         *             form = NumberFormat.getCurrencyInstance(locales[i]); break;
0356         *         default:
0357         *             form = NumberFormat.getPercentInstance(locales[i]); break;
0358         *         }
0359         *         if (form instanceof DecimalFormat) {
0360         *             System.out.print(": " + ((DecimalFormat) form).toPattern());
0361         *         }
0362         *         System.out.print(" -> " + form.format(myNumber));
0363         *         try {
0364         *             System.out.println(" -> " + form.parse(form.format(myNumber)));
0365         *         } catch (ParseException e) {}
0366         *     }
0367         * }
0368         * </pre></blockquote>
0369         *
0370         * @see          <a href="http://java.sun.com/docs/books/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a>
0371         * @see          NumberFormat
0372         * @see          DecimalFormatSymbols
0373         * @see          ParsePosition
0374         * @version      1.94 05/05/07
0375         * @author       Mark Davis
0376         * @author       Alan Liu
0377         */
0378        public class DecimalFormat extends NumberFormat {
0379
0380            /**
0381             * Creates a DecimalFormat using the default pattern and symbols
0382             * for the default locale. This is a convenient way to obtain a
0383             * DecimalFormat when internationalization is not the main concern.
0384             * <p>
0385             * To obtain standard formats for a given locale, use the factory methods
0386             * on NumberFormat such as getNumberInstance. These factories will
0387             * return the most appropriate sub-class of NumberFormat for a given
0388             * locale.
0389             *
0390             * @see java.text.NumberFormat#getInstance
0391             * @see java.text.NumberFormat#getNumberInstance
0392             * @see java.text.NumberFormat#getCurrencyInstance
0393             * @see java.text.NumberFormat#getPercentInstance
0394             */
0395            public DecimalFormat() {
0396                Locale def = Locale.getDefault();
0397                // try to get the pattern from the cache
0398                String pattern = (String) cachedLocaleData.get(def);
0399                if (pattern == null) { /* cache miss */
0400                    // Get the pattern for the default locale.
0401                    ResourceBundle rb = LocaleData.getNumberFormatData(def);
0402                    String[] all = rb.getStringArray("NumberPatterns");
0403                    pattern = all[0];
0404                    /* update cache */
0405                    cachedLocaleData.put(def, pattern);
0406                }
0407
0408                // Always applyPattern after the symbols are set
0409                this .symbols = new DecimalFormatSymbols(def);
0410                applyPattern(pattern, false);
0411            }
0412
0413            /**
0414             * Creates a DecimalFormat using the given pattern and the symbols
0415             * for the default locale. This is a convenient way to obtain a
0416             * DecimalFormat when internationalization is not the main concern.
0417             * <p>
0418             * To obtain standard formats for a given locale, use the factory methods
0419             * on NumberFormat such as getNumberInstance. These factories will
0420             * return the most appropriate sub-class of NumberFormat for a given
0421             * locale.
0422             *
0423             * @param pattern A non-localized pattern string.
0424             * @exception NullPointerException if <code>pattern</code> is null
0425             * @exception IllegalArgumentException if the given pattern is invalid.
0426             * @see java.text.NumberFormat#getInstance
0427             * @see java.text.NumberFormat#getNumberInstance
0428             * @see java.text.NumberFormat#getCurrencyInstance
0429             * @see java.text.NumberFormat#getPercentInstance
0430             */
0431            public DecimalFormat(String pattern) {
0432                // Always applyPattern after the symbols are set
0433                this .symbols = new DecimalFormatSymbols(Locale.getDefault());
0434                applyPattern(pattern, false);
0435            }
0436
0437            /**
0438             * Creates a DecimalFormat using the given pattern and symbols.
0439             * Use this constructor when you need to completely customize the
0440             * behavior of the format.
0441             * <p>
0442             * To obtain standard formats for a given
0443             * locale, use the factory methods on NumberFormat such as
0444             * getInstance or getCurrencyInstance. If you need only minor adjustments
0445             * to a standard format, you can modify the format returned by
0446             * a NumberFormat factory method.
0447             *
0448             * @param pattern a non-localized pattern string
0449             * @param symbols the set of symbols to be used
0450             * @exception NullPointerException if any of the given arguments is null
0451             * @exception IllegalArgumentException if the given pattern is invalid
0452             * @see java.text.NumberFormat#getInstance
0453             * @see java.text.NumberFormat#getNumberInstance
0454             * @see java.text.NumberFormat#getCurrencyInstance
0455             * @see java.text.NumberFormat#getPercentInstance
0456             * @see java.text.DecimalFormatSymbols
0457             */
0458            public DecimalFormat(String pattern, DecimalFormatSymbols symbols) {
0459                // Always applyPattern after the symbols are set
0460                this .symbols = (DecimalFormatSymbols) symbols.clone();
0461                applyPattern(pattern, false);
0462            }
0463
0464            // Overrides
0465            /**
0466             * Formats a number and appends the resulting text to the given string 
0467             * buffer.
0468             * The number can be of any subclass of {@link java.lang.Number}.
0469             * <p>
0470             * This implementation uses the maximum precision permitted.
0471             * @param number     the number to format
0472             * @param toAppendTo the <code>StringBuffer</code> to which the formatted
0473             *                   text is to be appended
0474             * @param pos        On input: an alignment field, if desired.
0475             *                   On output: the offsets of the alignment field.
0476             * @return           the value passed in as <code>toAppendTo</code>
0477             * @exception        IllegalArgumentException if <code>number</code> is
0478             *                   null or not an instance of <code>Number</code>.
0479             * @exception        NullPointerException if <code>toAppendTo</code> or 
0480             *                   <code>pos</code> is null
0481             * @exception        ArithmeticException if rounding is needed with rounding
0482             *                   mode being set to RoundingMode.UNNECESSARY
0483             * @see              java.text.FieldPosition
0484             */
0485            public final StringBuffer format(Object number,
0486                    StringBuffer toAppendTo, FieldPosition pos) {
0487                if (number instanceof  Long
0488                        || number instanceof  Integer
0489                        || number instanceof  Short
0490                        || number instanceof  Byte
0491                        || number instanceof  AtomicInteger
0492                        || number instanceof  AtomicLong
0493                        || (number instanceof  BigInteger && ((BigInteger) number)
0494                                .bitLength() < 64)) {
0495                    return format(((Number) number).longValue(), toAppendTo,
0496                            pos);
0497                } else if (number instanceof  BigDecimal) {
0498                    return format((BigDecimal) number, toAppendTo, pos);
0499                } else if (number instanceof  BigInteger) {
0500                    return format((BigInteger) number, toAppendTo, pos);
0501                } else if (number instanceof  Number) {
0502                    return format(((Number) number).doubleValue(), toAppendTo,
0503                            pos);
0504                } else {
0505                    throw new IllegalArgumentException(
0506                            "Cannot format given Object as a Number");
0507                }
0508            }
0509
0510            /**
0511             * Formats a double to produce a string.
0512             * @param number    The double to format
0513             * @param result    where the text is to be appended
0514             * @param fieldPosition    On input: an alignment field, if desired.
0515             * On output: the offsets of the alignment field.
0516             * @exception ArithmeticException if rounding is needed with rounding
0517             *            mode being set to RoundingMode.UNNECESSARY
0518             * @return The formatted number string
0519             * @see java.text.FieldPosition
0520             */
0521            public StringBuffer format(double number, StringBuffer result,
0522                    FieldPosition fieldPosition) {
0523                fieldPosition.setBeginIndex(0);
0524                fieldPosition.setEndIndex(0);
0525
0526                return format(number, result, fieldPosition.getFieldDelegate());
0527            }
0528
0529            /**
0530             * Formats a double to produce a string.
0531             * @param number    The double to format
0532             * @param result    where the text is to be appended
0533             * @param delegate notified of locations of sub fields
0534             * @exception       ArithmeticException if rounding is needed with rounding
0535             *                  mode being set to RoundingMode.UNNECESSARY
0536             * @return The formatted number string
0537             */
0538            private StringBuffer format(double number, StringBuffer result,
0539                    FieldDelegate delegate) {
0540                if (Double.isNaN(number)
0541                        || (Double.isInfinite(number) && multiplier == 0)) {
0542                    int iFieldStart = result.length();
0543                    result.append(symbols.getNaN());
0544                    delegate
0545                            .formatted(INTEGER_FIELD, Field.INTEGER,
0546                                    Field.INTEGER, iFieldStart,
0547                                    result.length(), result);
0548                    return result;
0549                }
0550
0551                /* Detecting whether a double is negative is easy with the exception of
0552                 * the value -0.0.  This is a double which has a zero mantissa (and
0553                 * exponent), but a negative sign bit.  It is semantically distinct from
0554                 * a zero with a positive sign bit, and this distinction is important
0555                 * to certain kinds of computations.  However, it's a little tricky to
0556                 * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0).  How then, you may
0557                 * ask, does it behave distinctly from +0.0?  Well, 1/(-0.0) ==
0558                 * -Infinity.  Proper detection of -0.0 is needed to deal with the
0559                 * issues raised by bugs 4106658, 4106667, and 4147706.  Liu 7/6/98.
0560                 */
0561                boolean isNegative = ((number < 0.0) || (number == 0.0 && 1 / number < 0.0))
0562                        ^ (multiplier < 0);
0563
0564                if (multiplier != 1) {
0565                    number *= multiplier;
0566                }
0567
0568                if (Double.isInfinite(number)) {
0569                    if (isNegative) {
0570                        append(result, negativePrefix, delegate,
0571                                getNegativePrefixFieldPositions(), Field.SIGN);
0572                    } else {
0573                        append(result, positivePrefix, delegate,
0574                                getPositivePrefixFieldPositions(), Field.SIGN);
0575                    }
0576
0577                    int iFieldStart = result.length();
0578                    result.append(symbols.getInfinity());
0579                    delegate
0580                            .formatted(INTEGER_FIELD, Field.INTEGER,
0581                                    Field.INTEGER, iFieldStart,
0582                                    result.length(), result);
0583
0584                    if (isNegative) {
0585                        append(result, negativeSuffix, delegate,
0586                                getNegativeSuffixFieldPositions(), Field.SIGN);
0587                    } else {
0588                        append(result, positiveSuffix, delegate,
0589                                getPositiveSuffixFieldPositions(), Field.SIGN);
0590                    }
0591
0592                    return result;
0593                }
0594
0595                if (isNegative) {
0596                    number = -number;
0597                }
0598
0599                // at this point we are guaranteed a nonnegative finite number.
0600                assert (number >= 0 && !Double.isInfinite(number));
0601
0602                synchronized (digitList) {
0603                    int maxIntDigits = super .getMaximumIntegerDigits();
0604                    int minIntDigits = super .getMinimumIntegerDigits();
0605                    int maxFraDigits = super .getMaximumFractionDigits();
0606                    int minFraDigits = super .getMinimumFractionDigits();
0607
0608                    digitList.set(isNegative, number,
0609                            useExponentialNotation ? maxIntDigits
0610                                    + maxFraDigits : maxFraDigits,
0611                            !useExponentialNotation);
0612                    return subformat(result, delegate, isNegative, false,
0613                            maxIntDigits, minIntDigits, maxFraDigits,
0614                            minFraDigits);
0615                }
0616            }
0617
0618            /**
0619             * Format a long to produce a string.
0620             * @param number    The long to format
0621             * @param result    where the text is to be appended
0622             * @param fieldPosition    On input: an alignment field, if desired.
0623             * On output: the offsets of the alignment field.
0624             * @exception       ArithmeticException if rounding is needed with rounding
0625             *                  mode being set to RoundingMode.UNNECESSARY
0626             * @return The formatted number string
0627             * @see java.text.FieldPosition
0628             */
0629            public StringBuffer format(long number, StringBuffer result,
0630                    FieldPosition fieldPosition) {
0631                fieldPosition.setBeginIndex(0);
0632                fieldPosition.setEndIndex(0);
0633
0634                return format(number, result, fieldPosition.getFieldDelegate());
0635            }
0636
0637            /**
0638             * Format a long to produce a string.
0639             * @param number    The long to format
0640             * @param result    where the text is to be appended
0641             * @param delegate notified of locations of sub fields
0642             * @return The formatted number string
0643             * @exception        ArithmeticException if rounding is needed with rounding
0644             *                   mode being set to RoundingMode.UNNECESSARY
0645             * @see java.text.FieldPosition
0646             */
0647            private StringBuffer format(long number, StringBuffer result,
0648                    FieldDelegate delegate) {
0649                boolean isNegative = (number < 0);
0650                if (isNegative) {
0651                    number = -number;
0652                }
0653
0654                // In general, long values always represent real finite numbers, so
0655                // we don't have to check for +/- Infinity or NaN.  However, there
0656                // is one case we have to be careful of:  The multiplier can push
0657                // a number near MIN_VALUE or MAX_VALUE outside the legal range.  We
0658                // check for this before multiplying, and if it happens we use
0659                // BigInteger instead.
0660                boolean useBigInteger = false;
0661                if (number < 0) { // This can only happen if number == Long.MIN_VALUE.
0662                    if (multiplier != 0) {
0663                        useBigInteger = true;
0664                    }
0665                } else if (multiplier != 1 && multiplier != 0) {
0666                    long cutoff = Long.MAX_VALUE / multiplier;
0667                    if (cutoff < 0) {
0668                        cutoff = -cutoff;
0669                    }
0670                    useBigInteger = (number > cutoff);
0671                }
0672
0673                if (useBigInteger) {
0674                    if (isNegative) {
0675                        number = -number;
0676                    }
0677                    BigInteger bigIntegerValue = BigInteger.valueOf(number);
0678                    return format(bigIntegerValue, result, delegate, true);
0679                }
0680
0681                number *= multiplier;
0682                if (number == 0) {
0683                    isNegative = false;
0684                } else {
0685                    if (multiplier < 0) {
0686                        number = -number;
0687                        isNegative = !isNegative;
0688                    }
0689                }
0690
0691                synchronized (digitList) {
0692                    int maxIntDigits = super .getMaximumIntegerDigits();
0693                    int minIntDigits = super .getMinimumIntegerDigits();
0694                    int maxFraDigits = super .getMaximumFractionDigits();
0695                    int minFraDigits = super .getMinimumFractionDigits();
0696
0697                    digitList.set(isNegative, number,
0698                            useExponentialNotation ? maxIntDigits
0699                                    + maxFraDigits : 0);
0700
0701                    return subformat(result, delegate, isNegative, true,
0702                            maxIntDigits, minIntDigits, maxFraDigits,
0703                            minFraDigits);
0704                }
0705            }
0706
0707            /**
0708             * Formats a BigDecimal to produce a string.
0709             * @param number    The BigDecimal to format
0710             * @param result    where the text is to be appended
0711             * @param fieldPosition    On input: an alignment field, if desired.
0712             * On output: the offsets of the alignment field.
0713             * @return The formatted number string
0714             * @exception        ArithmeticException if rounding is needed with rounding
0715             *                   mode being set to RoundingMode.UNNECESSARY
0716             * @see java.text.FieldPosition
0717             */
0718            private StringBuffer format(BigDecimal number, StringBuffer result,
0719                    FieldPosition fieldPosition) {
0720                fieldPosition.setBeginIndex(0);
0721                fieldPosition.setEndIndex(0);
0722                return format(number, result, fieldPosition.getFieldDelegate());
0723            }
0724
0725            /**
0726             * Formats a BigDecimal to produce a string.
0727             * @param number    The BigDecimal to format
0728             * @param result    where the text is to be appended
0729             * @param delegate notified of locations of sub fields
0730             * @exception        ArithmeticException if rounding is needed with rounding
0731             *                   mode being set to RoundingMode.UNNECESSARY
0732             * @return The formatted number string
0733             */
0734            private StringBuffer format(BigDecimal number, StringBuffer result,
0735                    FieldDelegate delegate) {
0736                if (multiplier != 1) {
0737                    number = number.multiply(getBigDecimalMultiplier());
0738                }
0739                boolean isNegative = number.signum() == -1;
0740                if (isNegative) {
0741                    number = number.negate();
0742                }
0743
0744                synchronized (digitList) {
0745                    int maxIntDigits = getMaximumIntegerDigits();
0746                    int minIntDigits = getMinimumIntegerDigits();
0747                    int maxFraDigits = getMaximumFractionDigits();
0748                    int minFraDigits = getMinimumFractionDigits();
0749                    int maximumDigits = maxIntDigits + maxFraDigits;
0750
0751                    digitList
0752                            .set(
0753                                    isNegative,
0754                                    number,
0755                                    useExponentialNotation ? ((maximumDigits < 0) ? Integer.MAX_VALUE
0756                                            : maximumDigits)
0757                                            : maxFraDigits,
0758                                    !useExponentialNotation);
0759
0760                    return subformat(result, delegate, isNegative, false,
0761                            maxIntDigits, minIntDigits, maxFraDigits,
0762                            minFraDigits);
0763                }
0764            }
0765
0766            /**
0767             * Format a BigInteger to produce a string.
0768             * @param number    The BigInteger to format
0769             * @param result    where the text is to be appended
0770             * @param fieldPosition    On input: an alignment field, if desired.
0771             * On output: the offsets of the alignment field.
0772             * @return The formatted number string
0773             * @exception        ArithmeticException if rounding is needed with rounding
0774             *                   mode being set to RoundingMode.UNNECESSARY
0775             * @see java.text.FieldPosition
0776             */
0777            private StringBuffer format(BigInteger number, StringBuffer result,
0778                    FieldPosition fieldPosition) {
0779                fieldPosition.setBeginIndex(0);
0780                fieldPosition.setEndIndex(0);
0781
0782                return format(number, result, fieldPosition.getFieldDelegate(),
0783                        false);
0784            }
0785
0786            /**
0787             * Format a BigInteger to produce a string.
0788             * @param number    The BigInteger to format
0789             * @param result    where the text is to be appended
0790             * @param delegate notified of locations of sub fields
0791             * @return The formatted number string
0792             * @exception        ArithmeticException if rounding is needed with rounding
0793             *                   mode being set to RoundingMode.UNNECESSARY
0794             * @see java.text.FieldPosition
0795             */
0796            private StringBuffer format(BigInteger number, StringBuffer result,
0797                    FieldDelegate delegate, boolean formatLong) {
0798                if (multiplier != 1) {
0799                    number = number.multiply(getBigIntegerMultiplier());
0800                }
0801                boolean isNegative = number.signum() == -1;
0802                if (isNegative) {
0803                    number = number.negate();
0804                }
0805
0806                synchronized (digitList) {
0807                    int maxIntDigits, minIntDigits, maxFraDigits, minFraDigits, maximumDigits;
0808                    if (formatLong) {
0809                        maxIntDigits = super .getMaximumIntegerDigits();
0810                        minIntDigits = super .getMinimumIntegerDigits();
0811                        maxFraDigits = super .getMaximumFractionDigits();
0812                        minFraDigits = super .getMinimumFractionDigits();
0813                        maximumDigits = maxIntDigits + maxFraDigits;
0814                    } else {
0815                        maxIntDigits = getMaximumIntegerDigits();
0816                        minIntDigits = getMinimumIntegerDigits();
0817                        maxFraDigits = getMaximumFractionDigits();
0818                        minFraDigits = getMinimumFractionDigits();
0819                        maximumDigits = maxIntDigits + maxFraDigits;
0820                        if (maximumDigits < 0) {
0821                            maximumDigits = Integer.MAX_VALUE;
0822                        }
0823                    }
0824
0825                    digitList.set(isNegative, number,
0826                            useExponentialNotation ? maximumDigits : 0);
0827
0828                    return subformat(result, delegate, isNegative, true,
0829                            maxIntDigits, minIntDigits, maxFraDigits,
0830                            minFraDigits);
0831                }
0832            }
0833
0834            /**
0835             * Formats an Object producing an <code>AttributedCharacterIterator</code>.
0836             * You can use the returned <code>AttributedCharacterIterator</code>
0837             * to build the resulting String, as well as to determine information
0838             * about the resulting String.
0839             * <p>
0840             * Each attribute key of the AttributedCharacterIterator will be of type
0841             * <code>NumberFormat.Field</code>, with the attribute value being the
0842             * same as the attribute key.
0843             *
0844             * @exception NullPointerException if obj is null.
0845             * @exception IllegalArgumentException when the Format cannot format the
0846             *            given object.
0847             * @exception        ArithmeticException if rounding is needed with rounding
0848             *                   mode being set to RoundingMode.UNNECESSARY
0849             * @param obj The object to format
0850             * @return AttributedCharacterIterator describing the formatted value.
0851             * @since 1.4
0852             */
0853            public AttributedCharacterIterator formatToCharacterIterator(
0854                    Object obj) {
0855                CharacterIteratorFieldDelegate delegate = new CharacterIteratorFieldDelegate();
0856                StringBuffer sb = new StringBuffer();
0857
0858                if (obj instanceof  Double || obj instanceof  Float) {
0859                    format(((Number) obj).doubleValue(), sb, delegate);
0860                } else if (obj instanceof  Long || obj instanceof  Integer
0861                        || obj instanceof  Short || obj instanceof  Byte
0862                        || obj instanceof  AtomicInteger
0863                        || obj instanceof  AtomicLong) {
0864                    format(((Number) obj).longValue(), sb, delegate);
0865                } else if (obj instanceof  BigDecimal) {
0866                    format((BigDecimal) obj, sb, delegate);
0867                } else if (obj instanceof  BigInteger) {
0868                    format((BigInteger) obj, sb, delegate, false);
0869                } else if (obj == null) {
0870                    throw new NullPointerException(
0871                            "formatToCharacterIterator must be passed non-null object");
0872                } else {
0873                    throw new IllegalArgumentException(
0874                            "Cannot format given Object as a Number");
0875                }
0876                return delegate.getIterator(sb.toString());
0877            }
0878
0879            /**
0880             * Complete the formatting of a finite number.  On entry, the digitList must
0881             * be filled in with the correct digits.
0882             */
0883            private StringBuffer subformat(StringBuffer result,
0884                    FieldDelegate delegate, boolean isNegative,
0885                    boolean isInteger, int maxIntDigits, int minIntDigits,
0886                    int maxFraDigits, int minFraDigits) {
0887                // NOTE: This isn't required anymore because DigitList takes care of this.
0888                //
0889                //  // The negative of the exponent represents the number of leading
0890                //  // zeros between the decimal and the first non-zero digit, for
0891                //  // a value < 0.1 (e.g., for 0.00123, -fExponent == 2).  If this
0892                //  // is more than the maximum fraction digits, then we have an underflow
0893                //  // for the printed representation.  We recognize this here and set
0894                //  // the DigitList representation to zero in this situation.
0895                //
0896                //  if (-digitList.decimalAt >= getMaximumFractionDigits())
0897                //  {
0898                //      digitList.count = 0;
0899                //  }
0900
0901                char zero = symbols.getZeroDigit();
0902                int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
0903                char grouping = symbols.getGroupingSeparator();
0904                char decimal = isCurrencyFormat ? symbols
0905                        .getMonetaryDecimalSeparator() : symbols
0906                        .getDecimalSeparator();
0907
0908                /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
0909                 * format as zero.  This allows sensible computations and preserves
0910                 * relations such as signum(1/x) = signum(x), where x is +Infinity or
0911                 * -Infinity.  Prior to this fix, we always formatted zero values as if
0912                 * they were positive.  Liu 7/6/98.
0913                 */
0914                if (digitList.isZero()) {
0915                    digitList.decimalAt = 0; // Normalize
0916                }
0917
0918                if (isNegative) {
0919                    append(result, negativePrefix, delegate,
0920                            getNegativePrefixFieldPositions(), Field.SIGN);
0921                } else {
0922                    append(result, positivePrefix, delegate,
0923                            getPositivePrefixFieldPositions(), Field.SIGN);
0924                }
0925
0926                if (useExponentialNotation) {
0927                    int iFieldStart = result.length();
0928                    int iFieldEnd = -1;
0929                    int fFieldStart = -1;
0930
0931                    // Minimum integer digits are handled in exponential format by
0932                    // adjusting the exponent.  For example, 0.01234 with 3 minimum
0933                    // integer digits is "123.4E-4".
0934
0935                    // Maximum integer digits are interpreted as indicating the
0936                    // repeating range.  This is useful for engineering notation, in
0937                    // which the exponent is restricted to a multiple of 3.  For
0938                    // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
0939                    // If maximum integer digits are > 1 and are larger than
0940                    // minimum integer digits, then minimum integer digits are
0941                    // ignored.
0942                    int exponent = digitList.decimalAt;
0943                    int repeat = maxIntDigits;
0944                    int minimumIntegerDigits = minIntDigits;
0945                    if (repeat > 1 && repeat > minIntDigits) {
0946                        // A repeating range is defined; adjust to it as follows.
0947                        // If repeat == 3, we have 6,5,4=>3; 3,2,1=>0; 0,-1,-2=>-3;
0948                        // -3,-4,-5=>-6, etc. This takes into account that the
0949                        // exponent we have here is off by one from what we expect;
0950                        // it is for the format 0.MMMMMx10^n.
0951                        if (exponent >= 1) {
0952                            exponent = ((exponent - 1) / repeat) * repeat;
0953                        } else {
0954                            // integer division rounds towards 0
0955                            exponent = ((exponent - repeat) / repeat) * repeat;
0956                        }
0957                        minimumIntegerDigits = 1;
0958                    } else {
0959                        // No repeating range is defined; use minimum integer digits.
0960                        exponent -= minimumIntegerDigits;
0961                    }
0962
0963                    // We now output a minimum number of digits, and more if there
0964                    // are more digits, up to the maximum number of digits.  We
0965                    // place the decimal point after the "integer" digits, which
0966                    // are the first (decimalAt - exponent) digits.
0967                    int minimumDigits = minIntDigits + minFraDigits;
0968                    if (minimumDigits < 0) { // overflow?
0969                        minimumDigits = Integer.MAX_VALUE;
0970                    }
0971
0972                    // The number of integer digits is handled specially if the number
0973                    // is zero, since then there may be no digits.
0974                    int integerDigits = digitList.isZero() ? minimumIntegerDigits
0975                            : digitList.decimalAt - exponent;
0976                    if (minimumDigits < integerDigits) {
0977                        minimumDigits = integerDigits;
0978                    }
0979                    int totalDigits = digitList.count;
0980                    if (minimumDigits > totalDigits) {
0981                        totalDigits = minimumDigits;
0982                    }
0983                    boolean addedDecimalSeparator = false;
0984
0985                    for (int i = 0; i < totalDigits; ++i) {
0986                        if (i == integerDigits) {
0987                            // Record field information for caller.
0988                            iFieldEnd = result.length();
0989
0990                            result.append(decimal);
0991                            addedDecimalSeparator = true;
0992
0993                            // Record field information for caller.
0994                            fFieldStart = result.length();
0995                        }
0996                        result
0997                                .append((i < digitList.count) ? (char) (digitList.digits[i] + zeroDelta)
0998                                        : zero);
0999                    }
1000
1001                    if (decimalSeparatorAlwaysShown
1002                            && totalDigits == integerDigits) {
1003                        // Record field information for caller.
1004                        iFieldEnd = result.length();
1005
1006                        result.append(decimal);
1007                        addedDecimalSeparator = true;
1008
1009                        // Record field information for caller.
1010                        fFieldStart = result.length();
1011                    }
1012
1013                    // Record field information
1014                    if (iFieldEnd == -1) {
1015                        iFieldEnd = result.length();
1016                    }
1017                    delegate.formatted(INTEGER_FIELD, Field.INTEGER,
1018                            Field.INTEGER, iFieldStart, iFieldEnd, result);
1019                    if (addedDecimalSeparator) {
1020                        delegate.formatted(Field.DECIMAL_SEPARATOR,
1021                                Field.DECIMAL_SEPARATOR, iFieldEnd,
1022                                fFieldStart, result);
1023                    }
1024                    if (fFieldStart == -1) {
1025                        fFieldStart = result.length();
1026                    }
1027                    delegate.formatted(FRACTION_FIELD, Field.FRACTION,
1028                            Field.FRACTION, fFieldStart, result.length(),
1029                            result);
1030
1031                    // The exponent is output using the pattern-specified minimum
1032                    // exponent digits.  There is no maximum limit to the exponent
1033                    // digits, since truncating the exponent would result in an
1034                    // unacceptable inaccuracy.
1035                    int fieldStart = result.length();
1036
1037                    result.append(symbols.getExponentSeparator());
1038
1039                    delegate.formatted(Field.EXPONENT_SYMBOL,
1040                            Field.EXPONENT_SYMBOL, fieldStart, result.length(),
1041                            result);
1042
1043                    // For zero values, we force the exponent to zero.  We
1044                    // must do this here, and not earlier, because the value
1045                    // is used to determine integer digit count above.
1046                    if (digitList.isZero()) {
1047                        exponent = 0;
1048                    }
1049
1050                    boolean negativeExponent = exponent < 0;
1051                    if (negativeExponent) {
1052                        exponent = -exponent;
1053                        fieldStart = result.length();
1054                        result.append(symbols.getMinusSign());
1055                        delegate.formatted(Field.EXPONENT_SIGN,
1056                                Field.EXPONENT_SIGN, fieldStart, result
1057                                        .length(), result);
1058                    }
1059                    digitList.set(negativeExponent, exponent);
1060
1061                    int eFieldStart = result.length();
1062
1063                    for (int i = digitList.decimalAt; i < minExponentDigits; ++i) {
1064                        result.append(zero);
1065                    }
1066                    for (int i = 0; i < digitList.decimalAt; ++i) {
1067                        result
1068                                .append((i < digitList.count) ? (char) (digitList.digits[i] + zeroDelta)
1069                                        : zero);
1070                    }
1071                    delegate.formatted(Field.EXPONENT, Field.EXPONENT,
1072                            eFieldStart, result.length(), result);
1073                } else {
1074                    int iFieldStart = result.length();
1075
1076                    // Output the integer portion.  Here 'count' is the total
1077                    // number of integer digits we will display, including both
1078                    // leading zeros required to satisfy getMinimumIntegerDigits,
1079                    // and actual digits present in the number.
1080                    int count = minIntDigits;
1081                    int digitIndex = 0; // Index into digitList.fDigits[]
1082                    if (digitList.decimalAt > 0 && count < digitList.decimalAt) {
1083                        count = digitList.decimalAt;
1084                    }
1085
1086                    // Handle the case where getMaximumIntegerDigits() is smaller
1087                    // than the real number of integer digits.  If this is so, we
1088                    // output the least significant max integer digits.  For example,
1089                    // the value 1997 printed with 2 max integer digits is just "97".
1090                    if (count > maxIntDigits) {
1091                        count = maxIntDigits;
1092                        digitIndex = digitList.decimalAt - count;
1093                    }
1094
1095                    int sizeBeforeIntegerPart = result.length();
1096                    for (int i = count - 1; i >= 0; --i) {
1097                        if (i < digitList.decimalAt
1098                                && digitIndex < digitList.count) {
1099                            // Output a real digit
1100                            result
1101                                    .append((char) (digitList.digits[digitIndex++] + zeroDelta));
1102                        } else {
1103                            // Output a leading zero
1104                            result.append(zero);
1105                        }
1106
1107                        // Output grouping separator if necessary.  Don't output a
1108                        // grouping separator if i==0 though; that's at the end of
1109                        // the integer part.
1110                        if (isGroupingUsed() && i > 0 && (groupingSize != 0)
1111                                && (i % groupingSize == 0)) {
1112                            int gStart = result.length();
1113                            result.append(grouping);
1114                            delegate.formatted(Field.GROUPING_SEPARATOR,
1115                                    Field.GROUPING_SEPARATOR, gStart, result
1116                                            .length(), result);
1117                        }
1118                    }
1119
1120                    // Determine whether or not there are any printable fractional
1121                    // digits.  If we've used up the digits we know there aren't.
1122                    boolean fractionPresent = (minFraDigits > 0)
1123                            || (!isInteger && digitIndex < digitList.count);
1124
1125                    // If there is no fraction present, and we haven't printed any
1126                    // integer digits, then print a zero.  Otherwise we won't print
1127                    // _any_ digits, and we won't be able to parse this string.
1128                    if (!fractionPresent
1129                            && result.length() == sizeBeforeIntegerPart) {
1130                        result.append(zero);
1131                    }
1132
1133                    delegate
1134                            .formatted(INTEGER_FIELD, Field.INTEGER,
1135                                    Field.INTEGER, iFieldStart,
1136                                    result.length(), result);
1137
1138                    // Output the decimal separator if we always do so.
1139                    int sStart = result.length();
1140                    if (decimalSeparatorAlwaysShown || fractionPresent) {
1141                        result.append(decimal);
1142                    }
1143
1144                    if (sStart != result.length()) {
1145                        delegate.formatted(Field.DECIMAL_SEPARATOR,
1146                                Field.DECIMAL_SEPARATOR, sStart, result
1147                                        .length(), result);
1148                    }
1149                    int fFieldStart = result.length();
1150
1151                    for (int i = 0; i < maxFraDigits; ++i) {
1152                        // Here is where we escape from the loop.  We escape if we've
1153                        // output the maximum fraction digits (specified in the for
1154                        // expression above).
1155                        // We also stop when we've output the minimum digits and either:
1156                        // we have an integer, so there is no fractional stuff to
1157                        // display, or we're out of significant digits.
1158                        if (i >= minFraDigits
1159                                && (isInteger || digitIndex >= digitList.count)) {
1160                            break;
1161                        }
1162
1163                        // Output leading fractional zeros. These are zeros that come
1164                        // after the decimal but before any significant digits. These
1165                        // are only output if abs(number being formatted) < 1.0.
1166                        if (-1 - i > (digitList.decimalAt - 1)) {
1167                            result.append(zero);
1168                            continue;
1169                        }
1170
1171                        // Output a digit, if we have any precision left, or a
1172                        // zero if we don't.  We don't want to output noise digits.
1173                        if (!isInteger && digitIndex < digitList.count) {
1174                            result
1175                                    .append((char) (digitList.digits[digitIndex++] + zeroDelta));
1176                        } else {
1177                            result.append(zero);
1178                        }
1179                    }
1180
1181                    // Record field information for caller.
1182                    delegate.formatted(FRACTION_FIELD, Field.FRACTION,
1183                            Field.FRACTION, fFieldStart, result.length(),
1184                            result);
1185                }
1186
1187                if (isNegative) {
1188                    append(result, negativeSuffix, delegate,
1189                            getNegativeSuffixFieldPositions(), Field.SIGN);
1190                } else {
1191                    append(result, positiveSuffix, delegate,
1192                            getPositiveSuffixFieldPositions(), Field.SIGN);
1193                }
1194
1195                return result;
1196            }
1197
1198            /**
1199             * Appends the String <code>string</code> to <code>result</code>.
1200             * <code>delegate</code> is notified of all  the
1201             * <code>FieldPosition</code>s in <code>positions</code>.
1202             * <p>
1203             * If one of the <code>FieldPosition</code>s in <code>positions</code>
1204             * identifies a <code>SIGN</code> attribute, it is mapped to
1205             * <code>signAttribute</code>. This is used
1206             * to map the <code>SIGN</code> attribute to the <code>EXPONENT</code>
1207             * attribute as necessary.
1208             * <p>
1209             * This is used by <code>subformat</code> to add the prefix/suffix.
1210             */
1211            private void append(StringBuffer result, String string,
1212                    FieldDelegate delegate, FieldPosition[] positions,
1213                    Format.Field signAttribute) {
1214                int start = result.length();
1215
1216                if (string.length() > 0) {
1217                    result.append(string);
1218                    for (int counter = 0, max = positions.length; counter < max; counter++) {
1219                        FieldPosition fp = positions[counter];
1220                        Format.Field attribute = fp.getFieldAttribute();
1221
1222                        if (attribute == Field.SIGN) {
1223                            attribute = signAttribute;
1224                        }
1225                        delegate.formatted(attribute, attribute, start
1226                                + fp.getBeginIndex(), start + fp.getEndIndex(),
1227                                result);
1228                    }
1229                }
1230            }
1231
1232            /**
1233             * Parses text from a string to produce a <code>Number</code>.
1234             * <p>
1235             * The method attempts to parse text starting at the index given by
1236             * <code>pos</code>.
1237             * If parsing succeeds, then the index of <code>pos</code> is updated
1238             * to the index after the last character used (parsing does not necessarily
1239             * use all characters up to the end of the string), and the parsed
1240             * number is returned. The updated <code>pos</code> can be used to
1241             * indicate the starting point for the next call to this method.
1242             * If an error occurs, then the index of <code>pos</code> is not
1243             * changed, the error index of <code>pos</code> is set to the index of
1244             * the character where the error occurred, and null is returned.
1245             * <p>
1246             * The subclass returned depends on the value of {@link #isParseBigDecimal}
1247             * as well as on the string being parsed.
1248             * <ul>
1249             *   <li>If <code>isParseBigDecimal()</code> is false (the default),
1250             *       most integer values are returned as <code>Long</code>
1251             *       objects, no matter how they are written: <code>"17"</code> and
1252             *       <code>"17.000"</code> both parse to <code>Long(17)</code>.
1253             *       Values that cannot fit into a <code>Long</code> are returned as
1254             *       <code>Double</code>s. This includes values with a fractional part,
1255             *       infinite values, <code>NaN</code>, and the value -0.0.
1256             *       <code>DecimalFormat</code> does <em>not</em> decide whether to
1257             *       return a <code>Double</code> or a <code>Long</code> based on the
1258             *       presence of a decimal separator in the source string. Doing so
1259             *       would prevent integers that overflow the mantissa of a double,
1260             *       such as <code>"-9,223,372,036,854,775,808.00"</code>, from being
1261             *       parsed accurately.
1262             *       <p>
1263             *       Callers may use the <code>Number</code> methods 
1264             *       <code>doubleValue</code>, <code>longValue</code>, etc., to obtain
1265             *       the type they want.
1266             *   <li>If <code>isParseBigDecimal()</code> is true, values are returned
1267             *       as <code>BigDecimal</code> objects. The values are the ones
1268             *       constructed by {@link java.math.BigDecimal#BigDecimal(String)}
1269             *       for corresponding strings in locale-independent format. The
1270             *       special cases negative and positive infinity and NaN are returned
1271             *       as <code>Double</code> instances holding the values of the
1272             *       corresponding <code>Double</code> constants.
1273             * </ul>
1274             * <p>
1275             * <code>DecimalFormat</code> parses all Unicode characters that represent
1276             * decimal digits, as defined by <code>Character.digit()</code>. In
1277             * addition, <code>DecimalFormat</code> also recognizes as digits the ten
1278             * consecutive characters starting with the localized zero digit defined in
1279             * the <code>DecimalFormatSymbols</code> object.
1280             *
1281             * @param text the string to be parsed
1282             * @param pos  A <code>ParsePosition</code> object with index and error
1283             *             index information as described above.
1284             * @return     the parsed value, or <code>null</code> if the parse fails
1285             * @exception  NullPointerException if <code>text</code> or
1286             *             <code>pos</code> is null.
1287             */
1288            public Number parse(String text, ParsePosition pos) {
1289                // special case NaN
1290                if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols
1291                        .getNaN().length())) {
1292                    pos.index = pos.index + symbols.getNaN().length();
1293                    return new Double(Double.NaN);
1294                }
1295
1296                boolean[] status = new boolean[STATUS_LENGTH];
1297                if (!subparse(text, pos, positivePrefix, negativePrefix,
1298                        digitList, false, status)) {
1299                    return null;
1300                }
1301
1302                // special case INFINITY
1303                if (status[STATUS_INFINITE]) {
1304                    if (status[STATUS_POSITIVE] == (multiplier >= 0)) {
1305                        return new Double(Double.POSITIVE_INFINITY);
1306                    } else {
1307                        return new Double(Double.NEGATIVE_INFINITY);
1308                    }
1309                }
1310
1311                if (multiplier == 0) {
1312                    if (digitList.isZero()) {
1313                        return new Double(Double.NaN);
1314                    } else if (status[STATUS_POSITIVE]) {
1315                        return new Double(Double.POSITIVE_INFINITY);
1316                    } else {
1317                        return new Double(Double.NEGATIVE_INFINITY);
1318                    }
1319                }
1320
1321                if (isParseBigDecimal()) {
1322                    BigDecimal bigDecimalResult = digitList.getBigDecimal();
1323
1324                    if (multiplier != 1) {
1325                        try {
1326                            bigDecimalResult = bigDecimalResult
1327                                    .divide(getBigDecimalMultiplier());
1328                        } catch (ArithmeticException e) { // non-terminating decimal expansion
1329                            bigDecimalResult = bigDecimalResult.divide(
1330                                    getBigDecimalMultiplier(), roundingMode);
1331                        }
1332                    }
1333
1334                    if (!status[STATUS_POSITIVE]) {
1335                        bigDecimalResult = bigDecimalResult.negate();
1336                    }
1337                    return bigDecimalResult;
1338                } else {
1339                    boolean gotDouble = true;
1340                    boolean gotLongMinimum = false;
1341                    double doubleResult = 0.0;
1342                    long longResult = 0;
1343
1344                    // Finally, have DigitList parse the digits into a value.
1345                    if (digitList.fitsIntoLong(status[STATUS_POSITIVE],
1346                            isParseIntegerOnly())) {
1347                        gotDouble = false;
1348                        longResult = digitList.getLong();
1349                        if (longResult < 0) { // got Long.MIN_VALUE
1350                            gotLongMinimum = true;
1351                        }
1352                    } else {
1353                        doubleResult = digitList.getDouble();
1354                    }
1355
1356                    // Divide by multiplier. We have to be careful here not to do
1357                    // unneeded conversions between double and long.
1358                    if (multiplier != 1) {
1359                        if (gotDouble) {
1360                            doubleResult /= multiplier;
1361                        } else {
1362                            // Avoid converting to double if we can
1363                            if (longResult % multiplier == 0) {
1364                                longResult /= multiplier;
1365                            } else {
1366                                doubleResult = ((double) longResult)
1367                                        / multiplier;
1368                                gotDouble = true;
1369                            }
1370                        }
1371                    }
1372
1373                    if (!status[STATUS_POSITIVE] && !gotLongMinimum) {
1374                        doubleResult = -doubleResult;
1375                        longResult = -longResult;
1376                    }
1377
1378                    // At this point, if we divided the result by the multiplier, the
1379                    // result may fit into a long.  We check for this case and return
1380                    // a long if possible.
1381                    // We must do this AFTER applying the negative (if appropriate)
1382                    // in order to handle the case of LONG_MIN; otherwise, if we do
1383                    // this with a positive value -LONG_MIN, the double is > 0, but
1384                    // the long is < 0. We also must retain a double in the case of
1385                    // -0.0, which will compare as == to a long 0 cast to a double
1386                    // (bug 4162852).
1387                    if (multiplier != 1 && gotDouble) {
1388                        longResult = (long) doubleResult;
1389                        gotDouble = ((doubleResult != (double) longResult) || (doubleResult == 0.0 && 1 / doubleResult < 0.0))
1390                                && !isParseIntegerOnly();
1391                    }
1392
1393                    return gotDouble ? (Number) new Double(doubleResult)
1394                            : (Number) new Long(longResult);
1395                }
1396            }
1397
1398            /**
1399             * Return a BigInteger multiplier.
1400             */
1401            private BigInteger getBigIntegerMultiplier() {
1402                if (bigIntegerMultiplier == null) {
1403                    bigIntegerMultiplier = BigInteger.valueOf(multiplier);
1404                }
1405                return bigIntegerMultiplier;
1406            }
1407
1408            private transient BigInteger bigIntegerMultiplier;
1409
1410            /**
1411             * Return a BigDecimal multiplier.
1412             */
1413            private BigDecimal getBigDecimalMultiplier() {
1414                if (bigDecimalMultiplier == null) {
1415                    bigDecimalMultiplier = new BigDecimal(multiplier);
1416                }
1417                return bigDecimalMultiplier;
1418            }
1419
1420            private transient BigDecimal bigDecimalMultiplier;
1421
1422            private static final int STATUS_INFINITE = 0;
1423            private static final int STATUS_POSITIVE = 1;
1424            private static final int STATUS_LENGTH = 2;
1425
1426            /**
1427             * Parse the given text into a number.  The text is parsed beginning at
1428             * parsePosition, until an unparseable character is seen.
1429             * @param text The string to parse.
1430             * @param parsePosition The position at which to being parsing.  Upon
1431             * return, the first unparseable character.
1432             * @param digits The DigitList to set to the parsed value.
1433             * @param isExponent If true, parse an exponent.  This means no
1434             * infinite values and integer only.
1435             * @param status Upon return contains boolean status flags indicating
1436             * whether the value was infinite and whether it was positive.
1437             */
1438            private final boolean subparse(String text,
1439                    ParsePosition parsePosition, String positivePrefix,
1440                    String negativePrefix, DigitList digits,
1441                    boolean isExponent, boolean status[]) {
1442                int position = parsePosition.index;
1443                int oldStart = parsePosition.index;
1444                int backup;
1445                boolean gotPositive, gotNegative;
1446
1447                // check for positivePrefix; take longest
1448                gotPositive = text.regionMatches(position, positivePrefix, 0,
1449                        positivePrefix.length());
1450                gotNegative = text.regionMatches(position, negativePrefix, 0,
1451                        negativePrefix.length());
1452
1453                if (gotPositive && gotNegative) {
1454                    if (positivePrefix.length() > negativePrefix.length()) {
1455                        gotNegative = false;
1456                    } else if (positivePrefix.length() < negativePrefix
1457                            .length()) {
1458                        gotPositive = false;
1459                    }
1460                }
1461
1462                if (gotPositive) {
1463                    position += positivePrefix.length();
1464                } else if (gotNegative) {
1465                    position += negativePrefix.length();
1466                } else {
1467                    parsePosition.errorIndex = position;
1468                    return false;
1469                }
1470
1471                // process digits or Inf, find decimal position
1472                status[STATUS_INFINITE] = false;
1473                if (!isExponent
1474                        && text.regionMatches(position, symbols.getInfinity(),
1475                                0, symbols.getInfinity().length())) {
1476                    position += symbols.getInfinity().length();
1477                    status[STATUS_INFINITE] = true;
1478                } else {
1479                    // We now have a string of digits, possibly with grouping symbols,
1480                    // and decimal points.  We want to process these into a DigitList.
1481                    // We don't want to put a bunch of leading zeros into the DigitList
1482                    // though, so we keep track of the location of the decimal point,
1483                    // put only significant digits into the DigitList, and adjust the
1484                    // exponent as needed.
1485
1486                    digits.decimalAt = digits.count = 0;
1487                    char zero = symbols.getZeroDigit();
1488                    char decimal = isCurrencyFormat ? symbols
1489                            .getMonetaryDecimalSeparator() : symbols
1490                            .getDecimalSeparator();
1491                    char grouping = symbols.getGroupingSeparator();
1492                    String exponentString = symbols.getExponentSeparator();
1493                    boolean sawDecimal = false;
1494                    boolean sawExponent = false;
1495                    boolean sawDigit = false;
1496                    int exponent = 0; // Set to the exponent value, if any
1497
1498                    // We have to track digitCount ourselves, because digits.count will
1499                    // pin when the maximum allowable digits is reached.
1500                    int digitCount = 0;
1501
1502                    backup = -1;
1503                    for (; position < text.length(); ++position) {
1504                        char ch = text.charAt(position);
1505
1506                        /* We recognize all digit ranges, not only the Latin digit range
1507                         * '0'..'9'.  We do so by using the Character.digit() method,
1508                         * which converts a valid Unicode digit to the range 0..9.
1509                         *
1510                         * The character 'ch' may be a digit.  If so, place its value
1511                         * from 0 to 9 in 'digit'.  First try using the locale digit,
1512                         * which may or MAY NOT be a standard Unicode digit range.  If
1513                         * this fails, try using the standard Unicode digit ranges by
1514                         * calling Character.digit().  If this also fails, digit will
1515                         * have a value outside the range 0..9.
1516                         */
1517                        int digit = ch - zero;
1518                        if (digit < 0 || digit > 9) {
1519                            digit = Character.digit(ch, 10);
1520                        }
1521
1522                        if (digit == 0) {
1523                            // Cancel out backup setting (see grouping handler below)
1524                            backup = -1; // Do this BEFORE continue statement below!!!
1525                            sawDigit = true;
1526
1527                            // Handle leading zeros
1528                            if (digits.count == 0) {
1529                                // Ignore leading zeros in integer part of number.
1530                                if (!sawDecimal) {
1531                                    continue;
1532                                }
1533
1534                                // If we have seen the decimal, but no significant
1535                                // digits yet, then we account for leading zeros by
1536                                // decrementing the digits.decimalAt into negative
1537                                // values.
1538                                --digits.decimalAt;
1539                            } else {
1540                                ++digitCount;
1541                                digits.append((char) (digit + '0'));
1542                            }
1543                        } else if (digit > 0 && digit <= 9) { // [sic] digit==0 handled above
1544                            sawDigit = true;
1545                            ++digitCount;
1546                            digits.append((char) (digit + '0'));
1547
1548                            // Cancel out backup setting (see grouping handler below)
1549                            backup = -1;
1550                        } else if (!isExponent && ch == decimal) {
1551                            // If we're only parsing integers, or if we ALREADY saw the
1552                            // decimal, then don't parse this one.
1553                            if (isParseIntegerOnly() || sawDecimal) {
1554                                break;
1555                            }
1556                            digits.decimalAt = digitCount; // Not digits.count!
1557                            sawDecimal = true;
1558                        } else if (!isExponent && ch == grouping
1559                                && isGroupingUsed()) {
1560                            if (sawDecimal) {
1561                                break;
1562                            }
1563                            // Ignore grouping characters, if we are using them, but
1564                            // require that they be followed by a digit.  Otherwise
1565                            // we backup and reprocess them.
1566                            backup = position;
1567                        } else if (!isExponent
1568                                && text.regionMatches(position, exponentString,
1569                                        0, exponentString.length())
1570                                && !sawExponent) {
1571                            // Process the exponent by recursively calling this method.
1572                            ParsePosition pos = new ParsePosition(position
1573                                    + exponentString.length());
1574                            boolean[] stat = new boolean[STATUS_LENGTH];
1575                            DigitList exponentDigits = new DigitList();
1576
1577                            if (subparse(text, pos, "", Character
1578                                    .toString(symbols.getMinusSign()),
1579                                    exponentDigits, true, stat)
1580                                    && exponentDigits.fitsIntoLong(
1581                                            stat[STATUS_POSITIVE], true)) {
1582                                position = pos.index; // Advance past the exponent
1583                                exponent = (int) exponentDigits.getLong();
1584                                if (!stat[STATUS_POSITIVE]) {
1585                                    exponent = -exponent;
1586                                }
1587                                sawExponent = true;
1588                            }
1589                            break; // Whether we fail or succeed, we exit this loop
1590                        } else {
1591                            break;
1592                        }
1593                    }
1594
1595                    if (backup != -1) {
1596                        position = backup;
1597                    }
1598
1599                    // If there was no decimal point we have an integer
1600                    if (!sawDecimal) {
1601                        digits.decimalAt = digitCount; // Not digits.count!
1602                    }
1603
1604                    // Adjust for exponent, if any
1605                    digits.decimalAt += exponent;
1606
1607                    // If none of the text string was recognized.  For example, parse
1608                    // "x" with pattern "#0.00" (return index and error index both 0)
1609                    // parse "$" with pattern "$#0.00". (return index 0 and error
1610                    // index 1).
1611                    if (!sawDigit && digitCount == 0) {
1612                        parsePosition.index = oldStart;
1613                        parsePosition.errorIndex = oldStart;
1614                        return false;
1615                    }
1616                }
1617
1618                // check for suffix
1619                if (!isExponent) {
1620                    if (gotPositive) {
1621                        gotPositive = text.regionMatches(position,
1622                                positiveSuffix, 0, positiveSuffix.length());
1623                    }
1624                    if (gotNegative) {
1625                        gotNegative = text.regionMatches(position,
1626                                negativeSuffix, 0, negativeSuffix.length());
1627                    }
1628
1629                    // if both match, take longest
1630                    if (gotPositive && gotNegative) {
1631                        if (positiveSuffix.length() > negativeSuffix.length()) {
1632                            gotNegative = false;
1633                        } else if (positiveSuffix.length() < negativeSuffix
1634                                .length()) {
1635                            gotPositive = false;
1636                        }
1637                    }
1638
1639                    // fail if neither or both
1640                    if (gotPositive == gotNegative) {
1641                        parsePosition.errorIndex = position;
1642                        return false;
1643                    }
1644
1645                    parsePosition.index = position
1646                            + (gotPositive ? positiveSuffix.length()
1647                                    : negativeSuffix.length()); // mark success!
1648                } else {
1649                    parsePosition.index = position;
1650                }
1651
1652                status[STATUS_POSITIVE] = gotPositive;
1653                if (parsePosition.index == oldStart) {
1654                    parsePosition.errorIndex = position;
1655                    return false;
1656                }
1657                return true;
1658            }
1659
1660            /**
1661             * Returns a copy of the decimal format symbols, which is generally not
1662             * changed by the programmer or user.
1663             * @return a copy of the desired DecimalFormatSymbols
1664             * @see java.text.DecimalFormatSymbols
1665             */
1666            public DecimalFormatSymbols getDecimalFormatSymbols() {
1667                try {
1668                    // don't allow multiple references
1669                    return (DecimalFormatSymbols) symbols.clone();
1670                } catch (Exception foo) {
1671                    return null; // should never happen
1672                }
1673            }
1674
1675            /**
1676             * Sets the decimal format symbols, which is generally not changed
1677             * by the programmer or user.
1678             * @param newSymbols desired DecimalFormatSymbols
1679             * @see java.text.DecimalFormatSymbols
1680             */
1681            public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
1682                try {
1683                    // don't allow multiple references
1684                    symbols = (DecimalFormatSymbols) newSymbols.clone();
1685                    expandAffixes();
1686                } catch (Exception foo) {
1687                    // should never happen
1688                }
1689            }
1690
1691            /**
1692             * Get the positive prefix.
1693             * <P>Examples: +123, $123, sFr123
1694             */
1695            public String getPositivePrefix() {
1696                return positivePrefix;
1697            }
1698
1699            /**
1700             * Set the positive prefix.
1701             * <P>Examples: +123, $123, sFr123
1702             */
1703            public void setPositivePrefix(String newValue) {
1704                positivePrefix = newValue;
1705                posPrefixPattern = null;
1706                positivePrefixFieldPositions = null;
1707            }
1708
1709            /**
1710             * Returns the FieldPositions of the fields in the prefix used for
1711             * positive numbers. This is not used if the user has explicitly set
1712             * a positive prefix via <code>setPositivePrefix</code>. This is
1713             * lazily created.
1714             *
1715             * @return FieldPositions in positive prefix
1716             */
1717            private FieldPosition[] getPositivePrefixFieldPositions() {
1718                if (positivePrefixFieldPositions == null) {
1719                    if (posPrefixPattern != null) {
1720                        positivePrefixFieldPositions = expandAffix(posPrefixPattern);
1721                    } else {
1722                        positivePrefixFieldPositions = EmptyFieldPositionArray;
1723                    }
1724                }
1725                return positivePrefixFieldPositions;
1726            }
1727
1728            /**
1729             * Get the negative prefix.
1730             * <P>Examples: -123, ($123) (with negative suffix), sFr-123
1731             */
1732            public String getNegativePrefix() {
1733                return negativePrefix;
1734            }
1735
1736            /**
1737             * Set the negative prefix.
1738             * <P>Examples: -123, ($123) (with negative suffix), sFr-123
1739             */
1740            public void setNegativePrefix(String newValue) {
1741                negativePrefix = newValue;
1742                negPrefixPattern = null;
1743            }
1744
1745            /**
1746             * Returns the FieldPositions of the fields in the prefix used for
1747             * negative numbers. This is not used if the user has explicitly set
1748             * a negative prefix via <code>setNegativePrefix</code>. This is
1749             * lazily created.
1750             *
1751             * @return FieldPositions in positive prefix
1752             */
1753            private FieldPosition[] getNegativePrefixFieldPositions() {
1754                if (negativePrefixFieldPositions == null) {
1755                    if (negPrefixPattern != null) {
1756                        negativePrefixFieldPositions = expandAffix(negPrefixPattern);
1757                    } else {
1758                        negativePrefixFieldPositions = EmptyFieldPositionArray;
1759                    }
1760                }
1761                return negativePrefixFieldPositions;
1762            }
1763
1764            /**
1765             * Get the positive suffix.
1766             * <P>Example: 123%
1767             */
1768            public String getPositiveSuffix() {
1769                return positiveSuffix;
1770            }
1771
1772            /**
1773             * Set the positive suffix.
1774             * <P>Example: 123%
1775             */
1776            public void setPositiveSuffix(String newValue) {
1777                positiveSuffix = newValue;
1778                posSuffixPattern = null;
1779            }
1780
1781            /**
1782             * Returns the FieldPositions of the fields in the suffix used for
1783             * positive numbers. This is not used if the user has explicitly set
1784             * a positive suffix via <code>setPositiveSuffix</code>. This is
1785             * lazily created.
1786             *
1787             * @return FieldPositions in positive prefix
1788             */
1789            private FieldPosition[] getPositiveSuffixFieldPositions() {
1790                if (positiveSuffixFieldPositions == null) {
1791                    if (posSuffixPattern != null) {
1792                        positiveSuffixFieldPositions = expandAffix(posSuffixPattern);
1793                    } else {
1794                        positiveSuffixFieldPositions = EmptyFieldPositionArray;
1795                    }
1796                }
1797                return positiveSuffixFieldPositions;
1798            }
1799
1800            /**
1801             * Get the negative suffix.
1802             * <P>Examples: -123%, ($123) (with positive suffixes)
1803             */
1804            public String getNegativeSuffix() {
1805                return negativeSuffix;
1806            }
1807
1808            /**
1809             * Set the negative suffix.
1810             * <P>Examples: 123%
1811             */
1812            public void setNegativeSuffix(String newValue) {
1813                negativeSuffix = newValue;
1814                negSuffixPattern = null;
1815            }
1816
1817            /**
1818             * Returns the FieldPositions of the fields in the suffix used for
1819             * negative numbers. This is not used if the user has explicitly set
1820             * a negative suffix via <code>setNegativeSuffix</code>. This is
1821             * lazily created.
1822             *
1823             * @return FieldPositions in positive prefix
1824             */
1825            private FieldPosition[] getNegativeSuffixFieldPositions() {
1826                if (negativeSuffixFieldPositions == null) {
1827                    if (negSuffixPattern != null) {
1828                        negativeSuffixFieldPositions = expandAffix(negSuffixPattern);
1829                    } else {
1830                        negativeSuffixFieldPositions = EmptyFieldPositionArray;
1831                    }
1832                }
1833                return negativeSuffixFieldPositions;
1834            }
1835
1836            /**
1837             * Gets the multiplier for use in percent, per mille, and similar
1838             * formats.
1839             *
1840             * @see #setMultiplier(int)
1841             */
1842            public int getMultiplier() {
1843                return multiplier;
1844            }
1845
1846            /**
1847             * Sets the multiplier for use in percent, per mille, and similar
1848             * formats.
1849             * For a percent format, set the multiplier to 100 and the suffixes to
1850             * have '%' (for Arabic, use the Arabic percent sign).
1851             * For a per mille format, set the multiplier to 1000 and the suffixes to
1852             * have '&#92;u2030'.
1853             *
1854             * <P>Example: with multiplier 100, 1.23 is formatted as "123", and
1855             * "123" is parsed into 1.23.
1856             *
1857             * @see #getMultiplier
1858             */
1859            public void setMultiplier(int newValue) {
1860                multiplier = newValue;
1861                bigDecimalMultiplier = null;
1862                bigIntegerMultiplier = null;
1863            }
1864
1865            /**
1866             * Return the grouping size. Grouping size is the number of digits between
1867             * grouping separators in the integer portion of a number.  For example,
1868             * in the number "123,456.78", the grouping size is 3. 
1869             * @see #setGroupingSize
1870             * @see java.text.NumberFormat#isGroupingUsed
1871             * @see java.text.DecimalFormatSymbols#getGroupingSeparator
1872             */
1873            public int getGroupingSize() {
1874                return groupingSize;
1875            }
1876
1877            /**
1878             * Set the grouping size. Grouping size is the number of digits between
1879             * grouping separators in the integer portion of a number.  For example,
1880             * in the number "123,456.78", the grouping size is 3.
1881             * <br>
1882             * The value passed in is converted to a byte, which may lose information.
1883             * @see #getGroupingSize
1884             * @see java.text.NumberFormat#setGroupingUsed
1885             * @see java.text.DecimalFormatSymbols#setGroupingSeparator
1886             */
1887            public void setGroupingSize(int newValue) {
1888                groupingSize = (byte) newValue;
1889            }
1890
1891            /**
1892             * Allows you to get the behavior of the decimal separator with integers.
1893             * (The decimal separator will always appear with decimals.)
1894             * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
1895             */
1896            public boolean isDecimalSeparatorAlwaysShown() {
1897                return decimalSeparatorAlwaysShown;
1898            }
1899
1900            /**
1901             * Allows you to set the behavior of the decimal separator with integers.
1902             * (The decimal separator will always appear with decimals.)
1903             * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
1904             */
1905            public void setDecimalSeparatorAlwaysShown(boolean newValue) {
1906                decimalSeparatorAlwaysShown = newValue;
1907            }
1908
1909            /**
1910             * Returns whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1911             * method returns <code>BigDecimal</code>. The default value is false.
1912             * @see #setParseBigDecimal
1913             * @since 1.5
1914             */
1915            public boolean isParseBigDecimal() {
1916                return parseBigDecimal;
1917            }
1918
1919            /**
1920             * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1921             * method returns <code>BigDecimal</code>. 
1922             * @see #isParseBigDecimal
1923             * @since 1.5
1924             */
1925            public void setParseBigDecimal(boolean newValue) {
1926                parseBigDecimal = newValue;
1927            }
1928
1929            /**
1930             * Standard override; no change in semantics.
1931             */
1932            public Object clone() {
1933                try {
1934                    DecimalFormat other = (DecimalFormat) super .clone();
1935                    other.symbols = (DecimalFormatSymbols) symbols.clone();
1936                    other.digitList = (DigitList) digitList.clone();
1937                    return other;
1938                } catch (Exception e) {
1939                    throw new InternalError();
1940                }
1941            }
1942
1943            /**
1944             * Overrides equals
1945             */
1946            public boolean equals(Object obj) {
1947                if (obj == null)
1948                    return false;
1949                if (!super .equals(obj))
1950                    return false; // super does class check
1951                DecimalFormat other = (DecimalFormat) obj;
1952                return ((posPrefixPattern == other.posPrefixPattern && positivePrefix
1953                        .equals(other.positivePrefix)) || (posPrefixPattern != null && posPrefixPattern
1954                        .equals(other.posPrefixPattern)))
1955                        && ((posSuffixPattern == other.posSuffixPattern && positiveSuffix
1956                                .equals(other.positiveSuffix)) || (posSuffixPattern != null && posSuffixPattern
1957                                .equals(other.posSuffixPattern)))
1958                        && ((negPrefixPattern == other.negPrefixPattern && negativePrefix
1959                                .equals(other.negativePrefix)) || (negPrefixPattern != null && negPrefixPattern
1960                                .equals(other.negPrefixPattern)))
1961                        && ((negSuffixPattern == other.negSuffixPattern && negativeSuffix
1962                                .equals(other.negativeSuffix)) || (negSuffixPattern != null && negSuffixPattern
1963                                .equals(other.negSuffixPattern)))
1964                        && multiplier == other.multiplier
1965                        && groupingSize == other.groupingSize
1966                        && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown
1967                        && parseBigDecimal == other.parseBigDecimal
1968                        && useExponentialNotation == other.useExponentialNotation
1969                        && (!useExponentialNotation || minExponentDigits == other.minExponentDigits)
1970                        && maximumIntegerDigits == other.maximumIntegerDigits
1971                        && minimumIntegerDigits == other.minimumIntegerDigits
1972                        && maximumFractionDigits == other.maximumFractionDigits
1973                        && minimumFractionDigits == other.minimumFractionDigits
1974                        && roundingMode == other.roundingMode
1975                        && symbols.equals(other.symbols);
1976            }
1977
1978            /**
1979             * Overrides hashCode
1980             */
1981            public int hashCode() {
1982                return super .hashCode() * 37 + positivePrefix.hashCode();
1983                // just enough fields for a reasonable distribution
1984            }
1985
1986            /**
1987             * Synthesizes a pattern string that represents the current state
1988             * of this Format object.
1989             * @see #applyPattern
1990             */
1991            public String toPattern() {
1992                return toPattern(false);
1993            }
1994
1995            /**
1996             * Synthesizes a localized pattern string that represents the current
1997             * state of this Format object.
1998             * @see #applyPattern
1999             */
2000            public String toLocalizedPattern() {
2001                return toPattern(true);
2002            }
2003
2004            /**
2005             * Expand the affix pattern strings into the expanded affix strings.  If any
2006             * affix pattern string is null, do not expand it.  This method should be
2007             * called any time the symbols or the affix patterns change in order to keep
2008             * the expanded affix strings up to date.
2009             */
2010            private void expandAffixes() {
2011                // Reuse one StringBuffer for better performance
2012                StringBuffer buffer = new StringBuffer();
2013                if (posPrefixPattern != null) {
2014                    positivePrefix = expandAffix(posPrefixPattern, buffer);
2015                    positivePrefixFieldPositions = null;
2016                }
2017                if (posSuffixPattern != null) {
2018                    positiveSuffix = expandAffix(posSuffixPattern, buffer);
2019                    positiveSuffixFieldPositions = null;
2020                }
2021                if (negPrefixPattern != null) {
2022                    negativePrefix = expandAffix(negPrefixPattern, buffer);
2023                    negativePrefixFieldPositions = null;
2024                }
2025                if (negSuffixPattern != null) {
2026                    negativeSuffix = expandAffix(negSuffixPattern, buffer);
2027                    negativeSuffixFieldPositions = null;
2028                }
2029            }
2030
2031            /**
2032             * Expand an affix pattern into an affix string.  All characters in the
2033             * pattern are literal unless prefixed by QUOTE.  The following characters
2034             * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2035             * PATTERN_MINUS, and CURRENCY_SIGN.  If CURRENCY_SIGN is doubled (QUOTE +
2036             * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
2037             * currency code.  Any other character after a QUOTE represents itself.
2038             * QUOTE must be followed by another character; QUOTE may not occur by
2039             * itself at the end of the pattern.
2040             *
2041             * @param pattern the non-null, possibly empty pattern
2042             * @param buffer a scratch StringBuffer; its contents will be lost
2043             * @return the expanded equivalent of pattern
2044             */
2045            private String expandAffix(String pattern, StringBuffer buffer) {
2046                buffer.setLength(0);
2047                for (int i = 0; i < pattern.length();) {
2048                    char c = pattern.charAt(i++);
2049                    if (c == QUOTE) {
2050                        c = pattern.charAt(i++);
2051                        switch (c) {
2052                        case CURRENCY_SIGN:
2053                            if (i < pattern.length()
2054                                    && pattern.charAt(i) == CURRENCY_SIGN) {
2055                                ++i;
2056                                buffer.append(symbols
2057                                        .getInternationalCurrencySymbol());
2058                            } else {
2059                                buffer.append(symbols.getCurrencySymbol());
2060                            }
2061                            continue;
2062                        case PATTERN_PERCENT:
2063                            c = symbols.getPercent();
2064                            break;
2065                        case PATTERN_PER_MILLE:
2066                            c = symbols.getPerMill();
2067                            break;
2068                        case PATTERN_MINUS:
2069                            c = symbols.getMinusSign();
2070                            break;
2071                        }
2072                    }
2073                    buffer.append(c);
2074                }
2075                return buffer.toString();
2076            }
2077
2078            /**
2079             * Expand an affix pattern into an array of FieldPositions describing
2080             * how the pattern would be expanded.
2081             * All characters in the
2082             * pattern are literal unless prefixed by QUOTE.  The following characters
2083             * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2084             * PATTERN_MINUS, and CURRENCY_SIGN.  If CURRENCY_SIGN is doubled (QUOTE +
2085             * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
2086             * currency code.  Any other character after a QUOTE represents itself.
2087             * QUOTE must be followed by another character; QUOTE may not occur by
2088             * itself at the end of the pattern.
2089             *
2090             * @param pattern the non-null, possibly empty pattern
2091             * @return FieldPosition array of the resulting fields.
2092             */
2093            private FieldPosition[] expandAffix(String pattern) {
2094                ArrayList positions = null;
2095                int stringIndex = 0;
2096                for (int i = 0; i < pattern.length();) {
2097                    char c = pattern.charAt(i++);
2098                    if (c == QUOTE) {
2099                        int field = -1;
2100                        Format.Field fieldID = null;
2101                        c = pattern.charAt(i++);
2102                        switch (c) {
2103                        case CURRENCY_SIGN:
2104                            String string;
2105                            if (i < pattern.length()
2106                                    && pattern.charAt(i) == CURRENCY_SIGN) {
2107                                ++i;
2108                                string = symbols
2109                                        .getInternationalCurrencySymbol();
2110                            } else {
2111                                string = symbols.getCurrencySymbol();
2112                            }
2113                            if (string.length() > 0) {
2114                                if (positions == null) {
2115                                    positions = new ArrayList(2);
2116                                }
2117                                FieldPosition fp = new FieldPosition(
2118                                        Field.CURRENCY);
2119                                fp.setBeginIndex(stringIndex);
2120                                fp.setEndIndex(stringIndex + string.length());
2121                                positions.add(fp);
2122                                stringIndex += string.length();
2123                            }
2124                            continue;
2125                        case PATTERN_PERCENT:
2126                            c = symbols.getPercent();
2127                            field = -1;
2128                            fieldID = Field.PERCENT;
2129                            break;
2130                        case PATTERN_PER_MILLE:
2131                            c = symbols.getPerMill();
2132                            field = -1;
2133                            fieldID = Field.PERMILLE;
2134                            break;
2135                        case PATTERN_MINUS:
2136                            c = symbols.getMinusSign();
2137                            field = -1;
2138                            fieldID = Field.SIGN;
2139                            break;
2140                        }
2141                        if (fieldID != null) {
2142                            if (positions == null) {
2143                                positions = new ArrayList(2);
2144                            }
2145                            FieldPosition fp = new FieldPosition(fieldID, field);
2146                            fp.setBeginIndex(stringIndex);
2147                            fp.setEndIndex(stringIndex + 1);
2148                            positions.add(fp);
2149                        }
2150                    }
2151                    stringIndex++;
2152                }
2153                if (positions != null) {
2154                    return (FieldPosition[]) positions
2155                            .toArray(EmptyFieldPositionArray);
2156                }
2157                return EmptyFieldPositionArray;
2158            }
2159
2160            /**
2161             * Appends an affix pattern to the given StringBuffer, quoting special
2162             * characters as needed.  Uses the internal affix pattern, if that exists,
2163             * or the literal affix, if the internal affix pattern is null.  The
2164             * appended string will generate the same affix pattern (or literal affix)
2165             * when passed to toPattern().
2166             * 
2167             * @param buffer the affix string is appended to this
2168             * @param affixPattern a pattern such as posPrefixPattern; may be null
2169             * @param expAffix a corresponding expanded affix, such as positivePrefix.
2170             * Ignored unless affixPattern is null.  If affixPattern is null, then
2171             * expAffix is appended as a literal affix.
2172             * @param localized true if the appended pattern should contain localized
2173             * pattern characters; otherwise, non-localized pattern chars are appended
2174             */
2175            private void appendAffix(StringBuffer buffer, String affixPattern,
2176                    String expAffix, boolean localized) {
2177                if (affixPattern == null) {
2178                    appendAffix(buffer, expAffix, localized);
2179                } else {
2180                    int i;
2181                    for (int pos = 0; pos < affixPattern.length(); pos = i) {
2182                        i = affixPattern.indexOf(QUOTE, pos);
2183                        if (i < 0) {
2184                            appendAffix(buffer, affixPattern.substring(pos),
2185                                    localized);
2186                            break;
2187                        }
2188                        if (i > pos) {
2189                            appendAffix(buffer, affixPattern.substring(pos, i),
2190                                    localized);
2191                        }
2192                        char c = affixPattern.charAt(++i);
2193                        ++i;
2194                        if (c == QUOTE) {
2195                            buffer.append(c);
2196                            // Fall through and append another QUOTE below
2197                        } else if (c == CURRENCY_SIGN
2198                                && i < affixPattern.length()
2199                                && affixPattern.charAt(i) == CURRENCY_SIGN) {
2200                            ++i;
2201                            buffer.append(c);
2202                            // Fall through and append another CURRENCY_SIGN below
2203                        } else if (localized) {
2204                            switch (c) {
2205                            case PATTERN_PERCENT:
2206                                c = symbols.getPercent();
2207                                break;
2208                            case PATTERN_PER_MILLE:
2209                                c = symbols.getPerMill();
2210                                break;
2211                            case PATTERN_MINUS:
2212                                c = symbols.getMinusSign();
2213                                break;
2214                            }
2215                        }
2216                        buffer.append(c);
2217                    }
2218                }
2219            }
2220
2221            /**
2222             * Append an affix to the given StringBuffer, using quotes if
2223             * there are special characters.  Single quotes themselves must be
2224             * escaped in either case.
2225             */
2226            private void appendAffix(StringBuffer buffer, String affix,
2227                    boolean localized) {
2228                boolean needQuote;
2229                if (localized) {
2230                    needQuote = affix.indexOf(symbols.getZeroDigit()) >= 0
2231                            || affix.indexOf(symbols.getGroupingSeparator()) >= 0
2232                            || affix.indexOf(symbols.getDecimalSeparator()) >= 0
2233                            || affix.indexOf(symbols.getPercent()) >= 0
2234                            || affix.indexOf(symbols.getPerMill()) >= 0
2235                            || affix.indexOf(symbols.getDigit()) >= 0
2236                            || affix.indexOf(symbols.getPatternSeparator()) >= 0
2237                            || affix.indexOf(symbols.getMinusSign()) >= 0
2238                            || affix.indexOf(CURRENCY_SIGN) >= 0;
2239                } else {
2240                    needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 0
2241                            || affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 0
2242                            || affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 0
2243                            || affix.indexOf(PATTERN_PERCENT) >= 0
2244                            || affix.indexOf(PATTERN_PER_MILLE) >= 0
2245                            || affix.indexOf(PATTERN_DIGIT) >= 0
2246                            || affix.indexOf(PATTERN_SEPARATOR) >= 0
2247                            || affix.indexOf(PATTERN_MINUS) >= 0
2248                            || affix.indexOf(CURRENCY_SIGN) >= 0;
2249                }
2250                if (needQuote)
2251                    buffer.append('\'');
2252                if (affix.indexOf('\'') < 0)
2253                    buffer.append(affix);
2254                else {
2255                    for (int j = 0; j < affix.length(); ++j) {
2256                        char c = affix.charAt(j);
2257                        buffer.append(c);
2258                        if (c == '\'')
2259                            buffer.append(c);
2260                    }
2261                }
2262                if (needQuote)
2263                    buffer.append('\'');
2264            }
2265
2266            /**
2267             * Does the real work of generating a pattern.  */
2268            private String toPattern(boolean localized) {
2269                StringBuffer result = new StringBuffer();
2270                for (int j = 1; j >= 0; --j) {
2271                    if (j == 1)
2272                        appendAffix(result, posPrefixPattern, positivePrefix,
2273                                localized);
2274                    else
2275                        appendAffix(result, negPrefixPattern, negativePrefix,
2276                                localized);
2277                    int i;
2278                    int digitCount = useExponentialNotation ? getMaximumIntegerDigits()
2279                            : Math.max(groupingSize, getMinimumIntegerDigits()) + 1;
2280                    for (i = digitCount; i > 0; --i) {
2281                        if (i != digitCount && isGroupingUsed()
2282                                && groupingSize != 0 && i % groupingSize == 0) {
2283                            result.append(localized ? symbols
2284                                    .getGroupingSeparator()
2285                                    : PATTERN_GROUPING_SEPARATOR);
2286                        }
2287                        result
2288                                .append(i <= getMinimumIntegerDigits() ? (localized ? symbols
2289                                        .getZeroDigit()
2290                                        : PATTERN_ZERO_DIGIT)
2291                                        : (localized ? symbols.getDigit()
2292                                                : PATTERN_DIGIT));
2293                    }
2294                    if (getMaximumFractionDigits() > 0
2295                            || decimalSeparatorAlwaysShown)
2296                        result.append(localized ? symbols.getDecimalSeparator()
2297                                : PATTERN_DECIMAL_SEPARATOR);
2298                    for (i = 0; i < getMaximumFractionDigits(); ++i) {
2299                        if (i < getMinimumFractionDigits()) {
2300                            result.append(localized ? symbols.getZeroDigit()
2301                                    : PATTERN_ZERO_DIGIT);
2302                        } else {
2303                            result.append(localized ? symbols.getDigit()
2304                                    : PATTERN_DIGIT);
2305                        }
2306                    }
2307                    if (useExponentialNotation) {
2308                        result.append(localized ? symbols
2309                                .getExponentSeparator() : PATTERN_EXPONENT);
2310                        for (i = 0; i < minExponentDigits; ++i)
2311                            result.append(localized ? symbols.getZeroDigit()
2312                                    : PATTERN_ZERO_DIGIT);
2313                    }
2314                    if (j == 1) {
2315                        appendAffix(result, posSuffixPattern, positiveSuffix,
2316                                localized);
2317                        if ((negSuffixPattern == posSuffixPattern && // n == p == null
2318                                negativeSuffix.equals(positiveSuffix))
2319                                || (negSuffixPattern != null && negSuffixPattern
2320                                        .equals(posSuffixPattern))) {
2321                            if ((negPrefixPattern != null
2322                                    && posPrefixPattern != null && negPrefixPattern
2323                                    .equals("'-" + posPrefixPattern))
2324                                    || (negPrefixPattern == posPrefixPattern && // n == p == null
2325                                    negativePrefix.equals(symbols
2326                                            .getMinusSign()
2327                                            + positivePrefix)))
2328                                break;
2329                        }
2330                        result.append(localized ? symbols.getPatternSeparator()
2331                                : PATTERN_SEPARATOR);
2332                    } else
2333                        appendAffix(result, negSuffixPattern, negativeSuffix,
2334                                localized);
2335                }
2336                return result.toString();
2337            }
2338
2339            /**
2340             * Apply the given pattern to this Format object.  A pattern is a
2341             * short-hand specification for the various formatting properties.
2342             * These properties can also be changed individually through the
2343             * various setter methods.
2344             * <p>
2345             * There is no limit to integer digits set
2346             * by this routine, since that is the typical end-user desire;
2347             * use setMaximumInteger if you want to set a real value.
2348             * For negative numbers, use a second pattern, separated by a semicolon
2349             * <P>Example <code>"#,#00.0#"</code> -> 1,234.56
2350             * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
2351             * a maximum of 2 fraction digits.
2352             * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
2353             * parentheses.
2354             * <p>In negative patterns, the minimum and maximum counts are ignored;
2355             * these are presumed to be set in the positive pattern.
2356             *
2357             * @exception NullPointerException if <code>pattern</code> is null
2358             * @exception IllegalArgumentException if the given pattern is invalid.
2359             */
2360            public void applyPattern(String pattern) {
2361                applyPattern(pattern, false);
2362            }
2363
2364            /**
2365             * Apply the given pattern to this Format object.  The pattern
2366             * is assumed to be in a localized notation. A pattern is a
2367             * short-hand specification for the various formatting properties.
2368             * These properties can also be changed individually through the
2369             * various setter methods.
2370             * <p>
2371             * There is no limit to integer digits set
2372             * by this routine, since that is the typical end-user desire;
2373             * use setMaximumInteger if you want to set a real value.
2374             * For negative numbers, use a second pattern, separated by a semicolon
2375             * <P>Example <code>"#,#00.0#"</code> -> 1,234.56
2376             * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
2377             * a maximum of 2 fraction digits.
2378             * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
2379             * parentheses.
2380             * <p>In negative patterns, the minimum and maximum counts are ignored;
2381             * these are presumed to be set in the positive pattern.
2382             *
2383             * @exception NullPointerException if <code>pattern</code> is null
2384             * @exception IllegalArgumentException if the given pattern is invalid.
2385             */
2386            public void applyLocalizedPattern(String pattern) {
2387                applyPattern(pattern, true);
2388            }
2389
2390            /**
2391             * Does the real work of applying a pattern.
2392             */
2393            private void applyPattern(String pattern, boolean localized) {
2394                char zeroDigit = PATTERN_ZERO_DIGIT;
2395                char groupingSeparator = PATTERN_GROUPING_SEPARATOR;
2396                char decimalSeparator = PATTERN_DECIMAL_SEPARATOR;
2397                char percent = PATTERN_PERCENT;
2398                char perMill = PATTERN_PER_MILLE;
2399                char digit = PATTERN_DIGIT;
2400                char separator = PATTERN_SEPARATOR;
2401                String exponent = PATTERN_EXPONENT;
2402                char minus = PATTERN_MINUS;
2403                if (localized) {
2404                    zeroDigit = symbols.getZeroDigit();
2405                    groupingSeparator = symbols.getGroupingSeparator();
2406                    decimalSeparator = symbols.getDecimalSeparator();
2407                    percent = symbols.getPercent();
2408                    perMill = symbols.getPerMill();
2409                    digit = symbols.getDigit();
2410                    separator = symbols.getPatternSeparator();
2411                    exponent = symbols.getExponentSeparator();
2412                    minus = symbols.getMinusSign();
2413                }
2414                boolean gotNegative = false;
2415                decimalSeparatorAlwaysShown = false;
2416                isCurrencyFormat = false;
2417                useExponentialNotation = false;
2418
2419                // Two variables are used to record the subrange of the pattern
2420                // occupied by phase 1.  This is used during the processing of the
2421                // second pattern (the one representing negative numbers) to ensure
2422                // that no deviation exists in phase 1 between the two patterns.
2423                int phaseOneStart = 0;
2424                int phaseOneLength = 0;
2425
2426                int start = 0;
2427                for (int j = 1; j >= 0 && start < pattern.length(); --j) {
2428                    boolean inQuote = false;
2429                    StringBuffer prefix = new StringBuffer();
2430                    StringBuffer suffix = new StringBuffer();
2431                    int decimalPos = -1;
2432                    int multiplier = 1;
2433                    int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0;
2434                    byte groupingCount = -1;
2435
2436                    // The phase ranges from 0 to 2.  Phase 0 is the prefix.  Phase 1 is
2437                    // the section of the pattern with digits, decimal separator,
2438                    // grouping characters.  Phase 2 is the suffix.  In phases 0 and 2,
2439                    // percent, per mille, and currency symbols are recognized and
2440                    // translated.  The separation of the characters into phases is
2441                    // strictly enforced; if phase 1 characters are to appear in the
2442                    // suffix, for example, they must be quoted.
2443                    int phase = 0;
2444
2445                    // The affix is either the prefix or the suffix.
2446                    StringBuffer affix = prefix;
2447
2448                    for (int pos = start; pos < pattern.length(); ++pos) {
2449                        char ch = pattern.charAt(pos);
2450                        switch (phase) {
2451                        case 0:
2452                        case 2:
2453                            // Process the prefix / suffix characters
2454                            if (inQuote) {
2455                                // A quote within quotes indicates either the closing
2456                                // quote or two quotes, which is a quote literal. That
2457                                // is, we have the second quote in 'do' or 'don''t'.
2458                                if (ch == QUOTE) {
2459                                    if ((pos + 1) < pattern.length()
2460                                            && pattern.charAt(pos + 1) == QUOTE) {
2461                                        ++pos;
2462                                        affix.append("''"); // 'don''t'
2463                                    } else {
2464                                        inQuote = false; // 'do'
2465                                    }
2466                                    continue;
2467                                }
2468                            } else {
2469                                // Process unquoted characters seen in prefix or suffix
2470                                // phase.
2471                                if (ch == digit || ch == zeroDigit
2472                                        || ch == groupingSeparator
2473                                        || ch == decimalSeparator) {
2474                                    phase = 1;
2475                                    if (j == 1) {
2476                                        phaseOneStart = pos;
2477                                    }
2478                                    --pos; // Reprocess this character
2479                                    continue;
2480                                } else if (ch == CURRENCY_SIGN) {
2481                                    // Use lookahead to determine if the currency sign
2482                                    // is doubled or not.
2483                                    boolean doubled = (pos + 1) < pattern
2484                                            .length()
2485                                            && pattern.charAt(pos + 1) == CURRENCY_SIGN;
2486                                    if (doubled) { // Skip over the doubled character
2487                                        ++pos;
2488                                    }
2489                                    isCurrencyFormat = true;
2490                                    affix.append(doubled ? "'\u00A4\u00A4"
2491                                            : "'\u00A4");
2492                                    continue;
2493                                } else if (ch == QUOTE) {
2494                                    // A quote outside quotes indicates either the
2495                                    // opening quote or two quotes, which is a quote
2496                                    // literal. That is, we have the first quote in 'do'
2497                                    // or o''clock.
2498                                    if (ch == QUOTE) {
2499                                        if ((pos + 1) < pattern.length()
2500                                                && pattern.charAt(pos + 1) == QUOTE) {
2501                                            ++pos;
2502                                            affix.append("''"); // o''clock
2503                                        } else {
2504                                            inQuote = true; // 'do'
2505                                        }
2506                                        continue;
2507                                    }
2508                                } else if (ch == separator) {
2509                                    // Don't allow separators before we see digit
2510                                    // characters of phase 1, and don't allow separators
2511                                    // in the second pattern (j == 0).
2512                                    if (phase == 0 || j == 0) {
2513                                        throw new IllegalArgumentException(
2514                                                "Unquoted special character '"
2515                                                        + ch
2516                                                        + "' in pattern \""
2517                                                        + pattern + '"');
2518                                    }
2519                                    start = pos + 1;
2520                                    pos = pattern.length();
2521                                    continue;
2522                                }
2523
2524                                // Next handle characters which are appended directly.
2525                                else if (ch == percent) {
2526                                    if (multiplier != 1) {
2527                                        throw new IllegalArgumentException(
2528                                                "Too many percent/per mille characters in pattern \""
2529                                                        + pattern + '"');
2530                                    }
2531                                    multiplier = 100;
2532                                    affix.append("'%");
2533                                    continue;
2534                                } else if (ch == perMill) {
2535                                    if (multiplier != 1) {
2536                                        throw new IllegalArgumentException(
2537                                                "Too many percent/per mille characters in pattern \""
2538                                                        + pattern + '"');
2539                                    }
2540                                    multiplier = 1000;
2541                                    affix.append("'\u2030");
2542                                    continue;
2543                                } else if (ch == minus) {
2544                                    affix.append("'-");
2545                                    continue;
2546                                }
2547                            }
2548                            // Note that if we are within quotes, or if this is an
2549                            // unquoted, non-special character, then we usually fall
2550                            // through to here.
2551                            affix.append(ch);
2552                            break;
2553
2554                        case 1:
2555                            // Phase one must be identical in the two sub-patterns. We
2556                            // enforce this by doing a direct comparison. While
2557                            // processing the first sub-pattern, we just record its
2558                            // length. While processing the second, we compare
2559                            // characters.
2560                            if (j == 1) {
2561                                ++phaseOneLength;
2562                            } else {
2563                                if (--phaseOneLength == 0) {
2564                                    phase = 2;
2565                                    affix = suffix;
2566                                }
2567                                continue;
2568                            }
2569
2570                            // Process the digits, decimal, and grouping characters. We
2571                            // record five pieces of information. We expect the digits
2572                            // to occur in the pattern ####0000.####, and we record the
2573                            // number of left digits, zero (central) digits, and right
2574                            // digits. The position of the last grouping character is
2575                            // recorded (should be somewhere within the first two blocks
2576                            // of characters), as is the position of the decimal point,
2577                            // if any (should be in the zero digits). If there is no
2578                            // decimal point, then there should be no right digits.
2579                            if (ch == digit) {
2580                                if (zeroDigitCount > 0) {
2581                                    ++digitRightCount;
2582                                } else {
2583                                    ++digitLeftCount;
2584                                }
2585                                if (groupingCount >= 0 && decimalPos < 0) {
2586                                    ++groupingCount;
2587                                }
2588                            } else if (ch == zeroDigit) {
2589                                if (digitRightCount > 0) {
2590                                    throw new IllegalArgumentException(
2591                                            "Unexpected '0' in pattern \""
2592                                                    + pattern + '"');
2593                                }
2594                                ++zeroDigitCount;
2595                                if (groupingCount >= 0 && decimalPos < 0) {
2596                                    ++groupingCount;
2597                                }
2598                            } else if (ch == groupingSeparator) {
2599                                groupingCount = 0;
2600                            } else if (ch == decimalSeparator) {
2601                                if (decimalPos >= 0) {
2602                                    throw new IllegalArgumentException(
2603                                            "Multiple decimal separators in pattern \""
2604                                                    + pattern + '"');
2605                                }
2606                                decimalPos = digitLeftCount + zeroDigitCount
2607                                        + digitRightCount;
2608                            } else if (pattern.regionMatches(pos, exponent, 0,
2609                                    exponent.length())) {
2610                                if (useExponentialNotation) {
2611                                    throw new IllegalArgumentException(
2612                                            "Multiple exponential "
2613                                                    + "symbols in pattern \""
2614                                                    + pattern + '"');
2615                                }
2616                                useExponentialNotation = true;
2617                                minExponentDigits = 0;
2618
2619                                // Use lookahead to parse out the exponential part
2620                                // of the pattern, then jump into phase 2.
2621                                pos = pos + exponent.length();
2622                                while (pos < pattern.length()
2623                                        && pattern.charAt(pos) == zeroDigit) {
2624                                    ++minExponentDigits;
2625                                    ++phaseOneLength;
2626                                    ++pos;
2627                                }
2628
2629                                if ((digitLeftCount + zeroDigitCount) < 1
2630                                        || minExponentDigits < 1) {
2631                                    throw new IllegalArgumentException(
2632                                            "Malformed exponential "
2633                                                    + "pattern \"" + pattern
2634                                                    + '"');
2635                                }
2636
2637                                // Transition to phase 2
2638                                phase = 2;
2639                                affix = suffix;
2640                                --pos;
2641                                continue;
2642                            } else {
2643                                phase = 2;
2644                                affix = suffix;
2645                                --pos;
2646                                --phaseOneLength;
2647                                continue;
2648                            }
2649                            break;
2650                        }
2651                    }
2652
2653                    // Handle patterns with no '0' pattern character. These patterns
2654                    // are legal, but must be interpreted.  "##.###" -> "#0.###".
2655                    // ".###" -> ".0##".
2656                    /* We allow patterns of the form "####" to produce a zeroDigitCount
2657                     * of zero (got that?); although this seems like it might make it
2658                     * possible for format() to produce empty strings, format() checks
2659                     * for this condition and outputs a zero digit in this situation.
2660                     * Having a zeroDigitCount of zero yields a minimum integer digits
2661                     * of zero, which allows proper round-trip patterns.  That is, we
2662                     * don't want "#" to become "#0" when toPattern() is called (even
2663                     * though that's what it really is, semantically).
2664                     */
2665                    if (zeroDigitCount == 0 && digitLeftCount > 0
2666                            && decimalPos >= 0) {
2667                        // Handle "###.###" and "###." and ".###"
2668                        int n = decimalPos;
2669                        if (n == 0) { // Handle ".###"
2670                            ++n;
2671                        }
2672                        digitRightCount = digitLeftCount - n;
2673                        digitLeftCount = n - 1;
2674                        zeroDigitCount = 1;
2675                    }
2676
2677                    // Do syntax checking on the digits.
2678                    if ((decimalPos < 0 && digitRightCount > 0)
2679                            || (decimalPos >= 0 && (decimalPos < digitLeftCount || decimalPos > (digitLeftCount + zeroDigitCount)))
2680                            || groupingCount == 0 || inQuote) {
2681                        throw new IllegalArgumentException(
2682                                "Malformed pattern \"" + pattern + '"');
2683                    }
2684
2685                    if (j == 1) {
2686                        posPrefixPattern = prefix.toString();
2687                        posSuffixPattern = suffix.toString();
2688                        negPrefixPattern = posPrefixPattern; // assume these for now
2689                        negSuffixPattern = posSuffixPattern;
2690                        int digitTotalCount = digitLeftCount + zeroDigitCount
2691                                + digitRightCount;
2692                        /* The effectiveDecimalPos is the position the decimal is at or
2693                         * would be at if there is no decimal. Note that if decimalPos<0,
2694                         * then digitTotalCount == digitLeftCount + zeroDigitCount.
2695                         */
2696                        int effectiveDecimalPos = decimalPos >= 0 ? decimalPos
2697                                : digitTotalCount;
2698                        setMinimumIntegerDigits(effectiveDecimalPos
2699                                - digitLeftCount);
2700                        setMaximumIntegerDigits(useExponentialNotation ? digitLeftCount
2701                                + getMinimumIntegerDigits()
2702                                : MAXIMUM_INTEGER_DIGITS);
2703                        setMaximumFractionDigits(decimalPos >= 0 ? (digitTotalCount - decimalPos)
2704                                : 0);
2705                        setMinimumFractionDigits(decimalPos >= 0 ? (digitLeftCount
2706                                + zeroDigitCount - decimalPos)
2707                                : 0);
2708                        setGroupingUsed(groupingCount > 0);
2709                        this .groupingSize = (groupingCount > 0) ? groupingCount
2710                                : 0;
2711                        this .multiplier = multiplier;
2712                        setDecimalSeparatorAlwaysShown(decimalPos == 0
2713                                || decimalPos == digitTotalCount);
2714                    } else {
2715                        negPrefixPattern = prefix.toString();
2716                        negSuffixPattern = suffix.toString();
2717                        gotNegative = true;
2718                    }
2719                }
2720
2721                if (pattern.length() == 0) {
2722                    posPrefixPattern = posSuffixPattern = "";
2723                    setMinimumIntegerDigits(0);
2724                    setMaximumIntegerDigits(MAXIMUM_INTEGER_DIGITS);
2725                    setMinimumFractionDigits(0);
2726                    setMaximumFractionDigits(MAXIMUM_FRACTION_DIGITS);
2727                }
2728
2729                // If there was no negative pattern, or if the negative pattern is
2730                // identical to the positive pattern, then prepend the minus sign to
2731                // the positive pattern to form the negative pattern.
2732                if (!gotNegative
2733                        || (negPrefixPattern.equals(posPrefixPattern) && negSuffixPattern
2734                                .equals(posSuffixPattern))) {
2735                    negSuffixPattern = posSuffixPattern;
2736                    negPrefixPattern = "'-" + posPrefixPattern;
2737                }
2738
2739                expandAffixes();
2740            }
2741
2742            /**
2743             * Sets the maximum number of digits allowed in the integer portion of a
2744             * number.
2745             * For formatting numbers other than <code>BigInteger</code> and
2746             * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2747             * 309 is used. Negative input values are replaced with 0.
2748             * @see NumberFormat#setMaximumIntegerDigits
2749             */
2750            public void setMaximumIntegerDigits(int newValue) {
2751                maximumIntegerDigits = Math.min(Math.max(0, newValue),
2752                        MAXIMUM_INTEGER_DIGITS);
2753                super 
2754                        .setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? DOUBLE_INTEGER_DIGITS
2755                                : maximumIntegerDigits);
2756                if (minimumIntegerDigits > maximumIntegerDigits) {
2757                    minimumIntegerDigits = maximumIntegerDigits;
2758                    super 
2759                            .setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? DOUBLE_INTEGER_DIGITS
2760                                    : minimumIntegerDigits);
2761                }
2762            }
2763
2764            /**
2765             * Sets the minimum number of digits allowed in the integer portion of a
2766             * number.
2767             * For formatting numbers other than <code>BigInteger</code> and
2768             * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2769             * 309 is used. Negative input values are replaced with 0.
2770             * @see NumberFormat#setMinimumIntegerDigits
2771             */
2772            public void setMinimumIntegerDigits(int newValue) {
2773                minimumIntegerDigits = Math.min(Math.max(0, newValue),
2774                        MAXIMUM_INTEGER_DIGITS);
2775                super 
2776                        .setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? DOUBLE_INTEGER_DIGITS
2777                                : minimumIntegerDigits);
2778                if (minimumIntegerDigits > maximumIntegerDigits) {
2779                    maximumIntegerDigits = minimumIntegerDigits;
2780                    super 
2781                            .setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? DOUBLE_INTEGER_DIGITS
2782                                    : maximumIntegerDigits);
2783                }
2784            }
2785
2786            /**
2787             * Sets the maximum number of digits allowed in the fraction portion of a
2788             * number.
2789             * For formatting numbers other than <code>BigInteger</code> and
2790             * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2791             * 340 is used. Negative input values are replaced with 0.
2792             * @see NumberFormat#setMaximumFractionDigits
2793             */
2794            public void setMaximumFractionDigits(int newValue) {
2795                maximumFractionDigits = Math.min(Math.max(0, newValue),
2796                        MAXIMUM_FRACTION_DIGITS);
2797                super 
2798                        .setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ? DOUBLE_FRACTION_DIGITS
2799                                : maximumFractionDigits);
2800                if (minimumFractionDigits > maximumFractionDigits) {
2801                    minimumFractionDigits = maximumFractionDigits;
2802                    super 
2803                            .setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ? DOUBLE_FRACTION_DIGITS
2804                                    : minimumFractionDigits);
2805                }
2806            }
2807
2808            /**
2809             * Sets the minimum number of digits allowed in the fraction portion of a
2810             * number.
2811             * For formatting numbers other than <code>BigInteger</code> and
2812             * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2813             * 340 is used. Negative input values are replaced with 0.
2814             * @see NumberFormat#setMinimumFractionDigits
2815             */
2816            public void setMinimumFractionDigits(int newValue) {
2817                minimumFractionDigits = Math.min(Math.max(0, newValue),
2818                        MAXIMUM_FRACTION_DIGITS);
2819                super 
2820                        .setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ? DOUBLE_FRACTION_DIGITS
2821                                : minimumFractionDigits);
2822                if (minimumFractionDigits > maximumFractionDigits) {
2823                    maximumFractionDigits = minimumFractionDigits;
2824                    super 
2825                            .setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ? DOUBLE_FRACTION_DIGITS
2826                                    : maximumFractionDigits);
2827                }
2828            }
2829
2830            /**
2831             * Gets the maximum number of digits allowed in the integer portion of a
2832             * number.
2833             * For formatting numbers other than <code>BigInteger</code> and
2834             * <code>BigDecimal</code> objects, the lower of the return value and
2835             * 309 is used.
2836             * @see #setMaximumIntegerDigits
2837             */
2838            public int getMaximumIntegerDigits() {
2839                return maximumIntegerDigits;
2840            }
2841
2842            /**
2843             * Gets the minimum number of digits allowed in the integer portion of a
2844             * number.
2845             * For formatting numbers other than <code>BigInteger</code> and
2846             * <code>BigDecimal</code> objects, the lower of the return value and
2847             * 309 is used.
2848             * @see #setMinimumIntegerDigits
2849             */
2850            public int getMinimumIntegerDigits() {
2851                return minimumIntegerDigits;
2852            }
2853
2854            /**
2855             * Gets the maximum number of digits allowed in the fraction portion of a
2856             * number.
2857             * For formatting numbers other than <code>BigInteger</code> and
2858             * <code>BigDecimal</code> objects, the lower of the return value and
2859             * 340 is used.
2860             * @see #setMaximumFractionDigits
2861             */
2862            public int getMaximumFractionDigits() {
2863                return maximumFractionDigits;
2864            }
2865
2866            /**
2867             * Gets the minimum number of digits allowed in the fraction portion of a
2868             * number.
2869             * For formatting numbers other than <code>BigInteger</code> and
2870             * <code>BigDecimal</code> objects, the lower of the return value and
2871             * 340 is used.
2872             * @see #setMinimumFractionDigits
2873             */
2874            public int getMinimumFractionDigits() {
2875                return minimumFractionDigits;
2876            }
2877
2878            /**
2879             * Gets the currency used by this decimal format when formatting
2880             * currency values.
2881             * The currency is obtained by calling
2882             * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency}
2883             * on this number format's symbols.
2884             *
2885             * @return the currency used by this decimal format, or <code>null</code>
2886             * @since 1.4
2887             */
2888            public Currency getCurrency() {
2889                return symbols.getCurrency();
2890            }
2891
2892            /**
2893             * Sets the currency used by this number format when formatting
2894             * currency values. This does not update the minimum or maximum
2895             * number of fraction digits used by the number format.
2896             * The currency is set by calling
2897             * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency}
2898             * on this number format's symbols.
2899             *
2900             * @param currency the new currency to be used by this decimal format
2901             * @exception NullPointerException if <code>currency</code> is null
2902             * @since 1.4
2903             */
2904            public void setCurrency(Currency currency) {
2905                if (currency != symbols.getCurrency()) {
2906                    symbols.setCurrency(currency);
2907                    if (isCurrencyFormat) {
2908                        expandAffixes();
2909                    }
2910                }
2911            }
2912
2913            /**
2914             * Gets the {@link java.math.RoundingMode} used in this DecimalFormat.
2915             *
2916             * @return The <code>RoundingMode</code> used for this DecimalFormat.
2917             * @see #setRoundingMode(RoundingMode)
2918             * @since 1.6
2919             */
2920            public RoundingMode getRoundingMode() {
2921                return roundingMode;
2922            }
2923
2924            /**
2925             * Sets the {@link java.math.RoundingMode} used in this DecimalFormat.
2926             *
2927             * @param roundingMode The <code>RoundingMode</code> to be used
2928             * @see #getRoundingMode()
2929             * @exception NullPointerException if <code>roundingMode</code> is null.
2930             * @since 1.6
2931             */
2932            public void setRoundingMode(RoundingMode roundingMode) {
2933                if (roundingMode == null) {
2934                    throw new NullPointerException();
2935                }
2936
2937                this .roundingMode = roundingMode;
2938                digitList.setRoundingMode(roundingMode);
2939            }
2940
2941            /**
2942             * Adjusts the minimum and maximum fraction digits to values that
2943             * are reasonable for the currency's default fraction digits.
2944             */
2945            void adjustForCurrencyDefaultFractionDigits() {
2946                Currency currency = symbols.getCurrency();
2947                if (currency == null) {
2948                    try {
2949                        currency = Currency.getInstance(symbols
2950                                .getInternationalCurrencySymbol());
2951                    } catch (IllegalArgumentException e) {
2952                    }
2953                }
2954                if (currency != null) {
2955                    int digits = currency.getDefaultFractionDigits();
2956                    if (digits != -1) {
2957                        int oldMinDigits = getMinimumFractionDigits();
2958                        // Common patterns are "#.##", "#.00", "#".
2959                        // Try to adjust all of them in a reasonable way.
2960                        if (oldMinDigits == getMaximumFractionDigits()) {
2961                            setMinimumFractionDigits(digits);
2962                            setMaximumFractionDigits(digits);
2963                        } else {
2964                            setMinimumFractionDigits(Math.min(digits,
2965                                    oldMinDigits));
2966                            setMaximumFractionDigits(digits);
2967                        }
2968                    }
2969                }
2970            }
2971
2972            /**
2973             * Reads the default serializable fields from the stream and performs
2974             * validations and adjustments for older serialized versions. The
2975             * validations and adjustments are:
2976             * <ol>
2977             * <li>
2978             * Verify that the superclass's digit count fields correctly reflect
2979             * the limits imposed on formatting numbers other than
2980             * <code>BigInteger</code> and <code>BigDecimal</code> objects. These
2981             * limits are stored in the superclass for serialization compatibility
2982             * with older versions, while the limits for <code>BigInteger</code> and
2983             * <code>BigDecimal</code> objects are kept in this class.
2984             * If, in the superclass, the minimum or maximum integer digit count is
2985             * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or
2986             * maximum fraction digit count is larger than
2987             * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid
2988             * and this method throws an <code>InvalidObjectException</code>.
2989             * <li>
2990             * If <code>serialVersionOnStream</code> is less than 4, initialize
2991             * <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN
2992             * RoundingMode.HALF_EVEN}.  This field is new with version 4.
2993             * <li>
2994             * If <code>serialVersionOnStream</code> is less than 3, then call
2995             * the setters for the minimum and maximum integer and fraction digits with
2996             * the values of the corresponding superclass getters to initialize the
2997             * fields in this class. The fields in this class are new with version 3.
2998             * <li>
2999             * If <code>serialVersionOnStream</code> is less than 1, indicating that
3000             * the stream was written by JDK 1.1, initialize
3001             * <code>useExponentialNotation</code>
3002             * to false, since it was not present in JDK 1.1.
3003             * <li>
3004             * Set <code>serialVersionOnStream</code> to the maximum allowed value so
3005             * that default serialization will work properly if this object is streamed
3006             * out again.
3007             * </ol>
3008             *
3009             * <p>Stream versions older than 2 will not have the affix pattern variables
3010             * <code>posPrefixPattern</code> etc.  As a result, they will be initialized
3011             * to <code>null</code>, which means the affix strings will be taken as
3012             * literal values.  This is exactly what we want, since that corresponds to
3013             * the pre-version-2 behavior.
3014             */
3015            private void readObject(ObjectInputStream stream)
3016                    throws IOException, ClassNotFoundException {
3017                stream.defaultReadObject();
3018                digitList = new DigitList();
3019
3020                if (serialVersionOnStream < 4) {
3021                    setRoundingMode(RoundingMode.HALF_EVEN);
3022                }
3023                // We only need to check the maximum counts because NumberFormat
3024                // .readObject has already ensured that the maximum is greater than the
3025                // minimum count.
3026                if (super .getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS
3027                        || super .getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {
3028                    throw new InvalidObjectException("Digit count out of range");
3029                }
3030                if (serialVersionOnStream < 3) {
3031                    setMaximumIntegerDigits(super .getMaximumIntegerDigits());
3032                    setMinimumIntegerDigits(super .getMinimumIntegerDigits());
3033                    setMaximumFractionDigits(super .getMaximumFractionDigits());
3034                    setMinimumFractionDigits(super .getMinimumFractionDigits());
3035                }
3036                if (serialVersionOnStream < 1) {
3037                    // Didn't have exponential fields
3038                    useExponentialNotation = false;
3039                }
3040                serialVersionOnStream = currentSerialVersion;
3041            }
3042
3043            //----------------------------------------------------------------------
3044            // INSTANCE VARIABLES
3045            //----------------------------------------------------------------------
3046
3047            private transient DigitList digitList = new DigitList();
3048
3049            /**
3050             * The symbol used as a prefix when formatting positive numbers, e.g. "+".
3051             *
3052             * @serial
3053             * @see #getPositivePrefix
3054             */
3055            private String positivePrefix = "";
3056
3057            /**
3058             * The symbol used as a suffix when formatting positive numbers.
3059             * This is often an empty string.
3060             *
3061             * @serial
3062             * @see #getPositiveSuffix
3063             */
3064            private String positiveSuffix = "";
3065
3066            /**
3067             * The symbol used as a prefix when formatting negative numbers, e.g. "-".
3068             *
3069             * @serial
3070             * @see #getNegativePrefix
3071             */
3072            private String negativePrefix = "-";
3073
3074            /**
3075             * The symbol used as a suffix when formatting negative numbers.
3076             * This is often an empty string.
3077             *
3078             * @serial
3079             * @see #getNegativeSuffix
3080             */
3081            private String negativeSuffix = "";
3082
3083            /**
3084             * The prefix pattern for non-negative numbers.  This variable corresponds
3085             * to <code>positivePrefix</code>.
3086             *
3087             * <p>This pattern is expanded by the method <code>expandAffix()</code> to
3088             * <code>positivePrefix</code> to update the latter to reflect changes in
3089             * <code>symbols</code>.  If this variable is <code>null</code> then
3090             * <code>positivePrefix</code> is taken as a literal value that does not
3091             * change when <code>symbols</code> changes.  This variable is always
3092             * <code>null</code> for <code>DecimalFormat</code> objects older than
3093             * stream version 2 restored from stream.
3094             *
3095             * @serial
3096             * @since 1.3
3097             */
3098            private String posPrefixPattern;
3099
3100            /**
3101             * The suffix pattern for non-negative numbers.  This variable corresponds
3102             * to <code>positiveSuffix</code>.  This variable is analogous to
3103             * <code>posPrefixPattern</code>; see that variable for further
3104             * documentation.
3105             *
3106             * @serial
3107             * @since 1.3
3108             */
3109            private String posSuffixPattern;
3110
3111            /**
3112             * The prefix pattern for negative numbers.  This variable corresponds
3113             * to <code>negativePrefix</code>.  This variable is analogous to
3114             * <code>posPrefixPattern</code>; see that variable for further
3115             * documentation.
3116             *
3117             * @serial
3118             * @since 1.3
3119             */
3120            private String negPrefixPattern;
3121
3122            /**
3123             * The suffix pattern for negative numbers.  This variable corresponds
3124             * to <code>negativeSuffix</code>.  This variable is analogous to
3125             * <code>posPrefixPattern</code>; see that variable for further
3126             * documentation.
3127             *
3128             * @serial
3129             * @since 1.3
3130             */
3131            private String negSuffixPattern;
3132
3133            /**
3134             * The multiplier for use in percent, per mille, etc.
3135             *
3136             * @serial
3137             * @see #getMultiplier
3138             */
3139            private int multiplier = 1;
3140
3141            /**
3142             * The number of digits between grouping separators in the integer
3143             * portion of a number.  Must be greater than 0 if
3144             * <code>NumberFormat.groupingUsed</code> is true.
3145             *
3146             * @serial
3147             * @see #getGroupingSize
3148             * @see java.text.NumberFormat#isGroupingUsed
3149             */
3150            private byte groupingSize = 3; // invariant, > 0 if useThousands
3151
3152            /**
3153             * If true, forces the decimal separator to always appear in a formatted
3154             * number, even if the fractional part of the number is zero.
3155             *
3156             * @serial
3157             * @see #isDecimalSeparatorAlwaysShown
3158             */
3159            private boolean decimalSeparatorAlwaysShown = false;
3160
3161            /**
3162             * If true, parse returns BigDecimal wherever possible.
3163             *
3164             * @serial
3165             * @see #isParseBigDecimal
3166             * @since 1.5
3167             */
3168            private boolean parseBigDecimal = false;
3169
3170            /**
3171             * True if this object represents a currency format.  This determines
3172             * whether the monetary decimal separator is used instead of the normal one.
3173             */
3174            private transient boolean isCurrencyFormat = false;
3175
3176            /**
3177             * The <code>DecimalFormatSymbols</code> object used by this format.
3178             * It contains the symbols used to format numbers, e.g. the grouping separator,
3179             * decimal separator, and so on.
3180             *
3181             * @serial
3182             * @see #setDecimalFormatSymbols
3183             * @see java.text.DecimalFormatSymbols
3184             */
3185            private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols();
3186
3187            /**
3188             * True to force the use of exponential (i.e. scientific) notation when formatting
3189             * numbers.
3190             *
3191             * @serial
3192             * @since 1.2
3193             */
3194            private boolean useExponentialNotation; // Newly persistent in the Java 2 platform v.1.2
3195
3196            /**
3197             * FieldPositions describing the positive prefix String. This is
3198             * lazily created. Use <code>getPositivePrefixFieldPositions</code>
3199             * when needed.
3200             */
3201            private transient FieldPosition[] positivePrefixFieldPositions;
3202
3203            /**
3204             * FieldPositions describing the positive suffix String. This is
3205             * lazily created. Use <code>getPositiveSuffixFieldPositions</code>
3206             * when needed.
3207             */
3208            private transient FieldPosition[] positiveSuffixFieldPositions;
3209
3210            /**
3211             * FieldPositions describing the negative prefix String. This is
3212             * lazily created. Use <code>getNegativePrefixFieldPositions</code>
3213             * when needed.
3214             */
3215            private transient FieldPosition[] negativePrefixFieldPositions;
3216
3217            /**
3218             * FieldPositions describing the negative suffix String. This is
3219             * lazily created. Use <code>getNegativeSuffixFieldPositions</code>
3220             * when needed.
3221             */
3222            private transient FieldPosition[] negativeSuffixFieldPositions;
3223
3224            /**
3225             * The minimum number of digits used to display the exponent when a number is
3226             * formatted in exponential notation.  This field is ignored if
3227             * <code>useExponentialNotation</code> is not true.
3228             *
3229             * @serial
3230             * @since 1.2
3231             */
3232            private byte minExponentDigits; // Newly persistent in the Java 2 platform v.1.2
3233
3234            /**
3235             * The maximum number of digits allowed in the integer portion of a
3236             * <code>BigInteger</code> or <code>BigDecimal</code> number.
3237             * <code>maximumIntegerDigits</code> must be greater than or equal to
3238             * <code>minimumIntegerDigits</code>.
3239             *
3240             * @serial
3241             * @see #getMaximumIntegerDigits
3242             * @since 1.5
3243             */
3244            private int maximumIntegerDigits = super .getMaximumIntegerDigits();
3245
3246            /**
3247             * The minimum number of digits allowed in the integer portion of a
3248             * <code>BigInteger</code> or <code>BigDecimal</code> number.
3249             * <code>minimumIntegerDigits</code> must be less than or equal to
3250             * <code>maximumIntegerDigits</code>.
3251             *
3252             * @serial
3253             * @see #getMinimumIntegerDigits
3254             * @since 1.5
3255             */
3256            private int minimumIntegerDigits = super .getMinimumIntegerDigits();
3257
3258            /**
3259             * The maximum number of digits allowed in the fractional portion of a
3260             * <code>BigInteger</code> or <code>BigDecimal</code> number.
3261             * <code>maximumFractionDigits</code> must be greater than or equal to
3262             * <code>minimumFractionDigits</code>.
3263             *
3264             * @serial
3265             * @see #getMaximumFractionDigits
3266             * @since 1.5
3267             */
3268            private int maximumFractionDigits = super 
3269                    .getMaximumFractionDigits();
3270
3271            /**
3272             * The minimum number of digits allowed in the fractional portion of a
3273             * <code>BigInteger</code> or <code>BigDecimal</code> number.
3274             * <code>minimumFractionDigits</code> must be less than or equal to
3275             * <code>maximumFractionDigits</code>.
3276             *
3277             * @serial
3278             * @see #getMinimumFractionDigits
3279             * @since 1.5
3280             */
3281            private int minimumFractionDigits = super 
3282                    .getMinimumFractionDigits();
3283
3284            /**
3285             * The {@link java.math.RoundingMode} used in this DecimalFormat.
3286             *
3287             * @serial
3288             * @since 1.6
3289             */
3290            private RoundingMode roundingMode = RoundingMode.HALF_EVEN;
3291
3292            //----------------------------------------------------------------------
3293
3294            static final int currentSerialVersion = 4;
3295
3296            /**
3297             * The internal serial version which says which version was written.
3298             * Possible values are:
3299             * <ul>
3300             * <li><b>0</b> (default): versions before the Java 2 platform v1.2
3301             * <li><b>1</b>: version for 1.2, which includes the two new fields
3302             *      <code>useExponentialNotation</code> and
3303             *      <code>minExponentDigits</code>.
3304             * <li><b>2</b>: version for 1.3 and later, which adds four new fields:
3305             *      <code>posPrefixPattern</code>, <code>posSuffixPattern</code>,
3306             *      <code>negPrefixPattern</code>, and <code>negSuffixPattern</code>.
3307             * <li><b>3</b>: version for 1.5 and later, which adds five new fields:
3308             *      <code>maximumIntegerDigits</code>,
3309             *      <code>minimumIntegerDigits</code>,
3310             *      <code>maximumFractionDigits</code>,
3311             *      <code>minimumFractionDigits</code>, and
3312             *      <code>parseBigDecimal</code>.
3313             * <li><b>4</b>: version for 1.6 and later, which adds one new field:
3314             *      <code>roundingMode</code>.
3315             * </ul>
3316             * @since 1.2
3317             * @serial
3318             */
3319            private int serialVersionOnStream = currentSerialVersion;
3320
3321            //----------------------------------------------------------------------
3322            // CONSTANTS
3323            //----------------------------------------------------------------------
3324
3325            // Constants for characters used in programmatic (unlocalized) patterns.
3326            private static final char PATTERN_ZERO_DIGIT = '0';
3327            private static final char PATTERN_GROUPING_SEPARATOR = ',';
3328            private static final char PATTERN_DECIMAL_SEPARATOR = '.';
3329            private static final char PATTERN_PER_MILLE = '\u2030';
3330            private static final char PATTERN_PERCENT = '%';
3331            private static final char PATTERN_DIGIT = '#';
3332            private static final char PATTERN_SEPARATOR = ';';
3333            private static final String PATTERN_EXPONENT = "E";
3334            private static final char PATTERN_MINUS = '-';
3335
3336            /**
3337             * The CURRENCY_SIGN is the standard Unicode symbol for currency.  It
3338             * is used in patterns and substituted with either the currency symbol,
3339             * or if it is doubled, with the international currency symbol.  If the
3340             * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
3341             * replaced with the monetary decimal separator.
3342             *
3343             * The CURRENCY_SIGN is not localized.
3344             */
3345            private static final char CURRENCY_SIGN = '\u00A4';
3346
3347            private static final char QUOTE = '\'';
3348
3349            private static FieldPosition[] EmptyFieldPositionArray = new FieldPosition[0];
3350
3351            // Upper limit on integer and fraction digits for a Java double
3352            static final int DOUBLE_INTEGER_DIGITS = 309;
3353            static final int DOUBLE_FRACTION_DIGITS = 340;
3354
3355            // Upper limit on integer and fraction digits for BigDecimal and BigInteger
3356            static final int MAXIMUM_INTEGER_DIGITS = Integer.MAX_VALUE;
3357            static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE;
3358
3359            // Proclaim JDK 1.1 serial compatibility.
3360            static final long serialVersionUID = 864413376551465018L;
3361
3362            /**
3363             * Cache to hold the NumberPattern of a Locale.
3364             */
3365            private static Hashtable cachedLocaleData = new Hashtable(3);
3366        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.