KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > text > DecimalFormat


1 /*
2  * @(#)DecimalFormat.java 1.79 04/06/28
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 /*
9  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
10  * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
11  *
12  * The original version of this source code and documentation is copyrighted
13  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
14  * materials are provided under terms of a License Agreement between Taligent
15  * and Sun. This technology is protected by multiple US and International
16  * patents. This notice and attribution to Taligent may not be removed.
17  * Taligent is a registered trademark of Taligent, Inc.
18  *
19  */

20
21 package java.text;
22
23 import java.io.InvalidObjectException JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.ObjectInputStream JavaDoc;
26 import java.math.BigDecimal JavaDoc;
27 import java.math.BigInteger JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Currency JavaDoc;
30 import java.util.Hashtable JavaDoc;
31 import java.util.Locale JavaDoc;
32 import java.util.ResourceBundle JavaDoc;
33 import sun.text.resources.LocaleData;
34
35 /**
36  * <code>DecimalFormat</code> is a concrete subclass of
37  * <code>NumberFormat</code> that formats decimal numbers. It has a variety of
38  * features designed to make it possible to parse and format numbers in any
39  * locale, including support for Western, Arabic, and Indic digits. It also
40  * supports different kinds of numbers, including integers (123), fixed-point
41  * numbers (123.4), scientific notation (1.23E4), percentages (12%), and
42  * currency amounts ($123). All of these can be localized.
43  *
44  * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the
45  * default locale, call one of <code>NumberFormat</code>'s factory methods, such
46  * as <code>getInstance()</code>. In general, do not call the
47  * <code>DecimalFormat</code> constructors directly, since the
48  * <code>NumberFormat</code> factory methods may return subclasses other than
49  * <code>DecimalFormat</code>. If you need to customize the format object, do
50  * something like this:
51  *
52  * <blockquote><pre>
53  * NumberFormat f = NumberFormat.getInstance(loc);
54  * if (f instanceof DecimalFormat) {
55  * ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
56  * }
57  * </pre></blockquote>
58  *
59  * <p>A <code>DecimalFormat</code> comprises a <em>pattern</em> and a set of
60  * <em>symbols</em>. The pattern may be set directly using
61  * <code>applyPattern()</code>, or indirectly using the API methods. The
62  * symbols are stored in a <code>DecimalFormatSymbols</code> object. When using
63  * the <code>NumberFormat</code> factory methods, the pattern and symbols are
64  * read from localized <code>ResourceBundle</code>s.
65  *
66  * <h4>Patterns</h4>
67  *
68  * <code>DecimalFormat</code> patterns have the following syntax:
69  * <blockquote><pre>
70  * <i>Pattern:</i>
71  * <i>PositivePattern</i>
72  * <i>PositivePattern</i> ; <i>NegativePattern</i>
73  * <i>PositivePattern:</i>
74  * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
75  * <i>NegativePattern:</i>
76  * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
77  * <i>Prefix:</i>
78  * any Unicode characters except &#92;uFFFE, &#92;uFFFF, and special characters
79  * <i>Suffix:</i>
80  * any Unicode characters except &#92;uFFFE, &#92;uFFFF, and special characters
81  * <i>Number:</i>
82  * <i>Integer</i> <i>Exponent<sub>opt</sub></i>
83  * <i>Integer</i> . <i>Fraction</i> <i>Exponent<sub>opt</sub></i>
84  * <i>Integer:</i>
85  * <i>MinimumInteger</i>
86  * #
87  * # <i>Integer</i>
88  * # , <i>Integer</i>
89  * <i>MinimumInteger:</i>
90  * 0
91  * 0 <i>MinimumInteger</i>
92  * 0 , <i>MinimumInteger</i>
93  * <i>Fraction:</i>
94  * <i>MinimumFraction<sub>opt</sub></i> <i>OptionalFraction<sub>opt</sub></i>
95  * <i>MinimumFraction:</i>
96  * 0 <i>MinimumFraction<sub>opt</sub></i>
97  * <i>OptionalFraction:</i>
98  * # <i>OptionalFraction<sub>opt</sub></i>
99  * <i>Exponent:</i>
100  * E <i>MinimumExponent</i>
101  * <i>MinimumExponent:</i>
102  * 0 <i>MinimumExponent<sub>opt</sub></i>
103  * </pre></blockquote>
104  *
105  * <p>A <code>DecimalFormat</code> pattern contains a positive and negative
106  * subpattern, for example, <code>"#,##0.00;(#,##0.00)"</code>. Each
107  * subpattern has a prefix, numeric part, and suffix. The negative subpattern
108  * is optional; if absent, then the positive subpattern prefixed with the
109  * localized minus sign (<code>'-'</code> in most locales) is used as the
110  * negative subpattern. That is, <code>"0.00"</code> alone is equivalent to
111  * <code>"0.00;-0.00"</code>. If there is an explicit negative subpattern, it
112  * serves only to specify the negative prefix and suffix; the number of digits,
113  * minimal digits, and other characteristics are all the same as the positive
114  * pattern. That means that <code>"#,##0.0#;(#)"</code> produces precisely
115  * the same behavior as <code>"#,##0.0#;(#,##0.0#)"</code>.
116  *
117  * <p>The prefixes, suffixes, and various symbols used for infinity, digits,
118  * thousands separators, decimal separators, etc. may be set to arbitrary
119  * values, and they will appear properly during formatting. However, care must
120  * be taken that the symbols and strings do not conflict, or parsing will be
121  * unreliable. For example, either the positive and negative prefixes or the
122  * suffixes must be distinct for <code>DecimalFormat.parse()</code> to be able
123  * to distinguish positive from negative values. (If they are identical, then
124  * <code>DecimalFormat</code> will behave as if no negative subpattern was
125  * specified.) Another example is that the decimal separator and thousands
126  * separator should be distinct characters, or parsing will be impossible.
127  *
128  * <p>The grouping separator is commonly used for thousands, but in some
129  * countries it separates ten-thousands. The grouping size is a constant number
130  * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for
131  * 1,0000,0000. If you supply a pattern with multiple grouping characters, the
132  * interval between the last one and the end of the integer is the one that is
133  * used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> ==
134  * <code>"##,####,####"</code>.
135  *
136  * <h4>Special Pattern Characters</h4>
137  *
138  * <p>Many characters in a pattern are taken literally; they are matched during
139  * parsing and output unchanged during formatting. Special characters, on the
140  * other hand, stand for other characters, strings, or classes of characters.
141  * They must be quoted, unless noted otherwise, if they are to appear in the
142  * prefix or suffix as literals.
143  *
144  * <p>The characters listed here are used in non-localized patterns. Localized
145  * patterns use the corresponding characters taken from this formatter's
146  * <code>DecimalFormatSymbols</code> object instead, and these characters lose
147  * their special status. Two exceptions are the currency sign and quote, which
148  * are not localized.
149  *
150  * <blockquote>
151  * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol,
152  * location, localized, and meaning.">
153  * <tr bgcolor="#ccccff">
154  * <th align=left>Symbol
155  * <th align=left>Location
156  * <th align=left>Localized?
157  * <th align=left>Meaning
158  * <tr valign=top>
159  * <td><code>0</code>
160  * <td>Number
161  * <td>Yes
162  * <td>Digit
163  * <tr valign=top bgcolor="#eeeeff">
164  * <td><code>#</code>
165  * <td>Number
166  * <td>Yes
167  * <td>Digit, zero shows as absent
168  * <tr valign=top>
169  * <td><code>.</code>
170  * <td>Number
171  * <td>Yes
172  * <td>Decimal separator or monetary decimal separator
173  * <tr valign=top bgcolor="#eeeeff">
174  * <td><code>-</code>
175  * <td>Number
176  * <td>Yes
177  * <td>Minus sign
178  * <tr valign=top>
179  * <td><code>,</code>
180  * <td>Number
181  * <td>Yes
182  * <td>Grouping separator
183  * <tr valign=top bgcolor="#eeeeff">
184  * <td><code>E</code>
185  * <td>Number
186  * <td>Yes
187  * <td>Separates mantissa and exponent in scientific notation.
188  * <em>Need not be quoted in prefix or suffix.</em>
189  * <tr valign=top>
190  * <td><code>;</code>
191  * <td>Subpattern boundary
192  * <td>Yes
193  * <td>Separates positive and negative subpatterns
194  * <tr valign=top bgcolor="#eeeeff">
195  * <td><code>%</code>
196  * <td>Prefix or suffix
197  * <td>Yes
198  * <td>Multiply by 100 and show as percentage
199  * <tr valign=top>
200  * <td><code>&#92;u2030</code>
201  * <td>Prefix or suffix
202  * <td>Yes
203  * <td>Multiply by 1000 and show as per mille value
204  * <tr valign=top bgcolor="#eeeeff">
205  * <td><code>&#164;</code> (<code>&#92;u00A4</code>)
206  * <td>Prefix or suffix
207  * <td>No
208  * <td>Currency sign, replaced by currency symbol. If
209  * doubled, replaced by international currency symbol.
210  * If present in a pattern, the monetary decimal separator
211  * is used instead of the decimal separator.
212  * <tr valign=top>
213  * <td><code>'</code>
214  * <td>Prefix or suffix
215  * <td>No
216  * <td>Used to quote special characters in a prefix or suffix,
217  * for example, <code>"'#'#"</code> formats 123 to
218  * <code>"#123"</code>. To create a single quote
219  * itself, use two in a row: <code>"# o''clock"</code>.
220  * </table>
221  * </blockquote>
222  *
223  * <h4>Scientific Notation</h4>
224  *
225  * <p>Numbers in scientific notation are expressed as the product of a mantissa
226  * and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3. The
227  * mantissa is often in the range 1.0 <= x < 10.0, but it need not be.
228  * <code>DecimalFormat</code> can be instructed to format and parse scientific
229  * notation <em>only via a pattern</em>; there is currently no factory method
230  * that creates a scientific notation format. In a pattern, the exponent
231  * character immediately followed by one or more digit characters indicates
232  * scientific notation. Example: <code>"0.###E0"</code> formats the number
233  * 1234 as <code>"1.234E3"</code>.
234  *
235  * <ul>
236  * <li>The number of digit characters after the exponent character gives the
237  * minimum exponent digit count. There is no maximum. Negative exponents are
238  * formatted using the localized minus sign, <em>not</em> the prefix and suffix
239  * from the pattern. This allows patterns such as <code>"0.###E0 m/s"</code>.
240  *
241  * <li>The minimum and maximum number of integer digits are interpreted
242  * together:
243  *
244  * <ul>
245  * <li>If the maximum number of integer digits is greater than their minimum number
246  * and greater than 1, it forces the exponent to be a multiple of the maximum
247  * number of integer digits, and the minimum number of integer digits to be
248  * interpreted as 1. The most common use of this is to generate
249  * <em>engineering notation</em>, in which the exponent is a multiple of three,
250  * e.g., <code>"##0.#####E0"</code>. Using this pattern, the number 12345
251  * formats to <code>"12.345E3"</code>, and 123456 formats to
252  * <code>"123.456E3"</code>.
253  *
254  * <li>Otherwise, the minimum number of integer digits is achieved by adjusting the
255  * exponent. Example: 0.00123 formatted with <code>"00.###E0"</code> yields
256  * <code>"12.3E-4"</code>.
257  * </ul>
258  *
259  * <li>The number of significant digits in the mantissa is the sum of the
260  * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is
261  * unaffected by the maximum integer digits. For example, 12345 formatted with
262  * <code>"##0.##E0"</code> is <code>"12.3E3"</code>. To show all digits, set
263  * the significant digits count to zero. The number of significant digits
264  * does not affect parsing.
265  *
266  * <li>Exponential patterns may not contain grouping separators.
267  * </ul>
268  *
269  * <h4>Rounding</h4>
270  *
271  * <code>DecimalFormat</code> uses half-even rounding (see
272  * {@link java.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for
273  * formatting.
274  *
275  * <h4>Digits</h4>
276  *
277  * For formatting, <code>DecimalFormat</code> uses the ten consecutive
278  * characters starting with the localized zero digit defined in the
279  * <code>DecimalFormatSymbols</code> object as digits. For parsing, these
280  * digits as well as all Unicode decimal digits, as defined by
281  * {@link Character#digit Character.digit}, are recognized.
282  *
283  * <h4>Special Values</h4>
284  *
285  * <p><code>NaN</code> is formatted as a single character, typically
286  * <code>&#92;uFFFD</code>. This character is determined by the
287  * <code>DecimalFormatSymbols</code> object. This is the only value for which
288  * the prefixes and suffixes are not used.
289  *
290  * <p>Infinity is formatted as a single character, typically
291  * <code>&#92;u221E</code>, with the positive or negative prefixes and suffixes
292  * applied. The infinity character is determined by the
293  * <code>DecimalFormatSymbols</code> object.
294  *
295  * <p>Negative zero (<code>"-0"</code>) parses to
296  * <ul>
297  * <li><code>BigDecimal(0)</code> if <code>isParseBigDecimal()</code> is
298  * true,
299  * <li><code>Long(0)</code> if <code>isParseBigDecimal()</code> is false
300  * and <code>isParseIntegerOnly()</code> is true,
301  * <li><code>Double(-0.0)</code> if both <code>isParseBigDecimal()</code>
302  * and <code>isParseIntegerOnly()</code> are false.
303  * </ul>
304  *
305  * <h4><a name="synchronization">Synchronization</a></h4>
306  *
307  * <p>
308  * Decimal formats are generally not synchronized.
309  * It is recommended to create separate format instances for each thread.
310  * If multiple threads access a format concurrently, it must be synchronized
311  * externally.
312  *
313  * <h4>Example</h4>
314  *
315  * <blockquote><pre>
316  * <strong>// Print out a number using the localized number, integer, currency,
317  * // and percent format for each locale</strong>
318  * Locale[] locales = NumberFormat.getAvailableLocales();
319  * double myNumber = -1234.56;
320  * NumberFormat form;
321  * for (int j=0; j<4; ++j) {
322  * System.out.println("FORMAT");
323  * for (int i = 0; i < locales.length; ++i) {
324  * if (locales[i].getCountry().length() == 0) {
325  * continue; // Skip language-only locales
326  * }
327  * System.out.print(locales[i].getDisplayName());
328  * switch (j) {
329  * case 0:
330  * form = NumberFormat.getInstance(locales[i]); break;
331  * case 1:
332  * form = NumberFormat.getIntegerInstance(locales[i]); break;
333  * case 2:
334  * form = NumberFormat.getCurrencyInstance(locales[i]); break;
335  * default:
336  * form = NumberFormat.getPercentInstance(locales[i]); break;
337  * }
338  * if (form instanceof DecimalFormat) {
339  * System.out.print(": " + ((DecimalFormat) form).toPattern());
340  * }
341  * System.out.print(" -> " + form.format(myNumber));
342  * try {
343  * System.out.println(" -> " + form.parse(form.format(myNumber)));
344  * } catch (ParseException e) {}
345  * }
346  * }
347  * </pre></blockquote>
348  *
349  * @see <a HREF="http://java.sun.com/docs/books/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a>
350  * @see NumberFormat
351  * @see DecimalFormatSymbols
352  * @see ParsePosition
353  * @version 1.79 06/28/04
354  * @author Mark Davis
355  * @author Alan Liu
356  */

357 public class DecimalFormat extends NumberFormat JavaDoc {
358
359     /**
360      * Creates a DecimalFormat using the default pattern and symbols
361      * for the default locale. This is a convenient way to obtain a
362      * DecimalFormat when internationalization is not the main concern.
363      * <p>
364      * To obtain standard formats for a given locale, use the factory methods
365      * on NumberFormat such as getNumberInstance. These factories will
366      * return the most appropriate sub-class of NumberFormat for a given
367      * locale.
368      *
369      * @see java.text.NumberFormat#getInstance
370      * @see java.text.NumberFormat#getNumberInstance
371      * @see java.text.NumberFormat#getCurrencyInstance
372      * @see java.text.NumberFormat#getPercentInstance
373      */

374     public DecimalFormat() {
375         Locale JavaDoc def = Locale.getDefault();
376         // try to get the pattern from the cache
377
String JavaDoc pattern = (String JavaDoc) cachedLocaleData.get(def);
378         if (pattern == null) { /* cache miss */
379             // Get the pattern for the default locale.
380
ResourceBundle JavaDoc rb = LocaleData.getLocaleElements(def);
381             String JavaDoc[] all = rb.getStringArray("NumberPatterns");
382             pattern = all[0];
383             /* update cache */
384             cachedLocaleData.put(def, pattern);
385         }
386
387         // Always applyPattern after the symbols are set
388
this.symbols = new DecimalFormatSymbols JavaDoc(def);
389         applyPattern(pattern, false);
390     }
391
392
393     /**
394      * Creates a DecimalFormat using the given pattern and the symbols
395      * for the default locale. This is a convenient way to obtain a
396      * DecimalFormat when internationalization is not the main concern.
397      * <p>
398      * To obtain standard formats for a given locale, use the factory methods
399      * on NumberFormat such as getNumberInstance. These factories will
400      * return the most appropriate sub-class of NumberFormat for a given
401      * locale.
402      *
403      * @param pattern A non-localized pattern string.
404      * @exception NullPointerException if <code>pattern</code> is null
405      * @exception IllegalArgumentException if the given pattern is invalid.
406      * @see java.text.NumberFormat#getInstance
407      * @see java.text.NumberFormat#getNumberInstance
408      * @see java.text.NumberFormat#getCurrencyInstance
409      * @see java.text.NumberFormat#getPercentInstance
410      */

411     public DecimalFormat(String JavaDoc pattern) {
412         // Always applyPattern after the symbols are set
413
this.symbols = new DecimalFormatSymbols JavaDoc(Locale.getDefault());
414         applyPattern(pattern, false);
415     }
416
417
418     /**
419      * Creates a DecimalFormat using the given pattern and symbols.
420      * Use this constructor when you need to completely customize the
421      * behavior of the format.
422      * <p>
423      * To obtain standard formats for a given
424      * locale, use the factory methods on NumberFormat such as
425      * getInstance or getCurrencyInstance. If you need only minor adjustments
426      * to a standard format, you can modify the format returned by
427      * a NumberFormat factory method.
428      *
429      * @param pattern a non-localized pattern string
430      * @param symbols the set of symbols to be used
431      * @exception NullPointerException if any of the given arguments is null
432      * @exception IllegalArgumentException if the given pattern is invalid
433      * @see java.text.NumberFormat#getInstance
434      * @see java.text.NumberFormat#getNumberInstance
435      * @see java.text.NumberFormat#getCurrencyInstance
436      * @see java.text.NumberFormat#getPercentInstance
437      * @see java.text.DecimalFormatSymbols
438      */

439     public DecimalFormat (String JavaDoc pattern, DecimalFormatSymbols JavaDoc symbols) {
440         // Always applyPattern after the symbols are set
441
this.symbols = (DecimalFormatSymbols JavaDoc)symbols.clone();
442         applyPattern(pattern, false);
443     }
444
445
446     // Overrides
447
/**
448      * Formats a number and appends the resulting text to the given string
449      * buffer.
450      * The number can be of any subclass of {@link java.lang.Number}.
451      * <p>
452      * This implementation uses the maximum precision permitted.
453      * @param number the number to format
454      * @param toAppendTo the <code>StringBuffer</code> to which the formatted
455      * text is to be appended
456      * @param pos On input: an alignment field, if desired.
457      * On output: the offsets of the alignment field.
458      * @return the value passed in as <code>toAppendTo</code>
459      * @exception IllegalArgumentException if <code>number</code> is
460      * null or not an instance of <code>Number</code>.
461      * @exception NullPointerException if <code>toAppendTo</code> or
462      * <code>pos</code> is null
463      * @see java.text.FieldPosition
464      */

465     public final StringBuffer JavaDoc format(Object JavaDoc number,
466                                      StringBuffer JavaDoc toAppendTo,
467                                      FieldPosition JavaDoc pos) {
468         if (number instanceof Long JavaDoc || number instanceof Integer JavaDoc ||
469                    number instanceof Short JavaDoc || number instanceof Byte JavaDoc ||
470                    (number instanceof BigInteger JavaDoc &&
471                     ((BigInteger JavaDoc)number).bitLength () < 64)) {
472             return format(((Number JavaDoc)number).longValue(), toAppendTo, pos);
473         } else if (number instanceof BigDecimal JavaDoc) {
474             return format((BigDecimal JavaDoc)number, toAppendTo, pos);
475         } else if (number instanceof BigInteger JavaDoc) {
476             return format((BigInteger JavaDoc)number, toAppendTo, pos);
477         } else if (number instanceof Number JavaDoc) {
478             return format(((Number JavaDoc)number).doubleValue(), toAppendTo, pos);
479         } else {
480             throw new IllegalArgumentException JavaDoc("Cannot format given Object as a Number");
481         }
482     }
483
484     /**
485      * Formats a double to produce a string.
486      * @param number The double to format
487      * @param result where the text is to be appended
488      * @param fieldPosition On input: an alignment field, if desired.
489      * On output: the offsets of the alignment field.
490      * @return The formatted number string
491      * @see java.text.FieldPosition
492      */

493     public StringBuffer JavaDoc format(double number, StringBuffer JavaDoc result,
494                                FieldPosition JavaDoc fieldPosition) {
495         fieldPosition.setBeginIndex(0);
496         fieldPosition.setEndIndex(0);
497
498         return format(number, result, fieldPosition.getFieldDelegate());
499     }
500
501     /**
502      * Formats a double to produce a string.
503      * @param number The double to format
504      * @param result where the text is to be appended
505      * @param delegate notified of locations of sub fields
506      * @return The formatted number string
507      */

508     private StringBuffer JavaDoc format(double number, StringBuffer JavaDoc result,
509                                 FieldDelegate delegate) {
510         if (Double.isNaN(number) ||
511            (Double.isInfinite(number) && multiplier == 0)) {
512             int iFieldStart = result.length();
513             result.append(symbols.getNaN());
514             delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
515                                iFieldStart, result.length(), result);
516             return result;
517         }
518
519         /* Detecting whether a double is negative is easy with the exception of
520          * the value -0.0. This is a double which has a zero mantissa (and
521          * exponent), but a negative sign bit. It is semantically distinct from
522          * a zero with a positive sign bit, and this distinction is important
523          * to certain kinds of computations. However, it's a little tricky to
524          * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0). How then, you may
525          * ask, does it behave distinctly from +0.0? Well, 1/(-0.0) ==
526          * -Infinity. Proper detection of -0.0 is needed to deal with the
527          * issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98.
528          */

529         boolean isNegative = ((number < 0.0) || (number == 0.0 && 1/number < 0.0)) ^ (multiplier < 0);
530
531         if (multiplier != 1) {
532             number *= multiplier;
533         }
534
535         if (Double.isInfinite(number)) {
536             if (isNegative) {
537                 append(result, negativePrefix, delegate,
538                        getNegativePrefixFieldPositions(), Field.SIGN);
539             } else {
540                 append(result, positivePrefix, delegate,
541                        getPositivePrefixFieldPositions(), Field.SIGN);
542             }
543
544             int iFieldStart = result.length();
545             result.append(symbols.getInfinity());
546             delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
547                                iFieldStart, result.length(), result);
548
549             if (isNegative) {
550                 append(result, negativeSuffix, delegate,
551                        getNegativeSuffixFieldPositions(), Field.SIGN);
552             } else {
553                 append(result, positiveSuffix, delegate,
554                        getPositiveSuffixFieldPositions(), Field.SIGN);
555             }
556
557             return result;
558         }
559
560         if (isNegative) {
561             number = -number;
562         }
563
564         // at this point we are guaranteed a nonnegative finite number.
565
assert(number >= 0 && !Double.isInfinite(number));
566
567         synchronized(digitList) {
568             int maxIntDigits = super.getMaximumIntegerDigits();
569             int minIntDigits = super.getMinimumIntegerDigits();
570             int maxFraDigits = super.getMaximumFractionDigits();
571             int minFraDigits = super.getMinimumFractionDigits();
572
573             digitList.set(number, useExponentialNotation ?
574                           maxIntDigits + maxFraDigits : maxFraDigits,
575                           !useExponentialNotation);
576             return subformat(result, delegate, isNegative, false,
577                        maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
578         }
579     }
580
581     /**
582      * Format a long to produce a string.
583      * @param number The long to format
584      * @param result where the text is to be appended
585      * @param fieldPosition On input: an alignment field, if desired.
586      * On output: the offsets of the alignment field.
587      * @return The formatted number string
588      * @see java.text.FieldPosition
589      */

590     public StringBuffer JavaDoc format(long number, StringBuffer JavaDoc result,
591                                FieldPosition JavaDoc fieldPosition) {
592         fieldPosition.setBeginIndex(0);
593         fieldPosition.setEndIndex(0);
594
595         return format(number, result, fieldPosition.getFieldDelegate());
596     }
597
598     /**
599      * Format a long to produce a string.
600      * @param number The long to format
601      * @param result where the text is to be appended
602      * @param delegate notified of locations of sub fields
603      * @return The formatted number string
604      * @see java.text.FieldPosition
605      */

606     private StringBuffer JavaDoc format(long number, StringBuffer JavaDoc result,
607                                FieldDelegate delegate) {
608         boolean isNegative = (number < 0);
609         if (isNegative) {
610             number = -number;
611         }
612
613         // In general, long values always represent real finite numbers, so
614
// we don't have to check for +/- Infinity or NaN. However, there
615
// is one case we have to be careful of: The multiplier can push
616
// a number near MIN_VALUE or MAX_VALUE outside the legal range. We
617
// check for this before multiplying, and if it happens we use
618
// BigInteger instead.
619
boolean useBigInteger = false;
620         if (number < 0) { // This can only happen if number == Long.MIN_VALUE.
621
if (multiplier != 0) {
622                 useBigInteger = true;
623             }
624         } else if (multiplier != 1 && multiplier != 0) {
625             long cutoff = Long.MAX_VALUE / multiplier;
626             if (cutoff < 0) {
627                 cutoff = -cutoff;
628             }
629             useBigInteger = (number > cutoff);
630         }
631
632         if (useBigInteger) {
633             if (isNegative) {
634                 number = -number;
635             }
636             BigInteger JavaDoc bigIntegerValue = BigInteger.valueOf(number);
637             return format(bigIntegerValue, result, delegate, true);
638         }
639
640         number *= multiplier;
641         if (number == 0) {
642             isNegative = false;
643         } else {
644             if (multiplier < 0) {
645                 number = -number;
646                 isNegative = !isNegative;
647             }
648         }
649
650         synchronized(digitList) {
651             int maxIntDigits = super.getMaximumIntegerDigits();
652             int minIntDigits = super.getMinimumIntegerDigits();
653             int maxFraDigits = super.getMaximumFractionDigits();
654             int minFraDigits = super.getMinimumFractionDigits();
655
656             digitList.set(number,
657                      useExponentialNotation ? maxIntDigits + maxFraDigits : 0);
658
659             return subformat(result, delegate, isNegative, true,
660                        maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
661         }
662     }
663
664     /**
665      * Formats a BigDecimal to produce a string.
666      * @param number The BigDecimal to format
667      * @param result where the text is to be appended
668      * @param fieldPosition On input: an alignment field, if desired.
669      * On output: the offsets of the alignment field.
670      * @return The formatted number string
671      * @see java.text.FieldPosition
672      */

673     private StringBuffer JavaDoc format(BigDecimal JavaDoc number, StringBuffer JavaDoc result,
674                                 FieldPosition JavaDoc fieldPosition) {
675         fieldPosition.setBeginIndex(0);
676         fieldPosition.setEndIndex(0);
677         return format(number, result, fieldPosition.getFieldDelegate());
678     }
679
680     /**
681      * Formats a BigDecimal to produce a string.
682      * @param number The BigDecimal to format
683      * @param result where the text is to be appended
684      * @param delegate notified of locations of sub fields
685      * @return The formatted number string
686      */

687     private StringBuffer JavaDoc format(BigDecimal JavaDoc number, StringBuffer JavaDoc result,
688                                 FieldDelegate delegate) {
689         if (multiplier != 1) {
690             number = number.multiply(getBigDecimalMultiplier());
691         }
692         boolean isNegative = number.signum() == -1;
693         if (isNegative) {
694             number = number.negate();
695         }
696
697         synchronized(digitList) {
698             int maxIntDigits = getMaximumIntegerDigits();
699             int minIntDigits = getMinimumIntegerDigits();
700             int maxFraDigits = getMaximumFractionDigits();
701             int minFraDigits = getMinimumFractionDigits();
702             int maximumDigits = maxIntDigits + maxFraDigits;
703
704             digitList.set(number, useExponentialNotation ?
705                 ((maximumDigits < 0) ? Integer.MAX_VALUE : maximumDigits) :
706                 maxFraDigits, !useExponentialNotation);
707
708             return subformat(result, delegate, isNegative, false,
709                 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
710         }
711     }
712
713     /**
714      * Format a BigInteger to produce a string.
715      * @param number The BigInteger to format
716      * @param result where the text is to be appended
717      * @param fieldPosition On input: an alignment field, if desired.
718      * On output: the offsets of the alignment field.
719      * @return The formatted number string
720      * @see java.text.FieldPosition
721      */

722     private StringBuffer JavaDoc format(BigInteger JavaDoc number, StringBuffer JavaDoc result,
723                                FieldPosition JavaDoc fieldPosition) {
724         fieldPosition.setBeginIndex(0);
725         fieldPosition.setEndIndex(0);
726
727         return format(number, result, fieldPosition.getFieldDelegate(), false);
728     }
729
730     /**
731      * Format a BigInteger to produce a string.
732      * @param number The BigInteger to format
733      * @param result where the text is to be appended
734      * @param delegate notified of locations of sub fields
735      * @return The formatted number string
736      * @see java.text.FieldPosition
737      */

738     private StringBuffer JavaDoc format(BigInteger JavaDoc number, StringBuffer JavaDoc result,
739                                FieldDelegate delegate, boolean formatLong) {
740         if (multiplier != 1) {
741             number = number.multiply(getBigIntegerMultiplier());
742         }
743         boolean isNegative = number.signum() == -1;
744         if (isNegative) {
745             number = number.negate();
746         }
747
748         synchronized(digitList) {
749             int maxIntDigits, minIntDigits, maxFraDigits, minFraDigits, maximumDigits;
750             if (formatLong) {
751                 maxIntDigits = super.getMaximumIntegerDigits();
752                 minIntDigits = super.getMinimumIntegerDigits();
753                 maxFraDigits = super.getMaximumFractionDigits();
754                 minFraDigits = super.getMinimumFractionDigits();
755                 maximumDigits = maxIntDigits + maxFraDigits;
756             } else {
757                 maxIntDigits = getMaximumIntegerDigits();
758                 minIntDigits = getMinimumIntegerDigits();
759                 maxFraDigits = getMaximumFractionDigits();
760                 minFraDigits = getMinimumFractionDigits();
761                 maximumDigits = maxIntDigits + maxFraDigits;
762                 if (maximumDigits < 0) {
763                     maximumDigits = Integer.MAX_VALUE;
764                 }
765             }
766
767             digitList.set(number, useExponentialNotation ? maximumDigits : 0);
768
769             return subformat(result, delegate, isNegative, true,
770                 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
771         }
772     }
773
774     /**
775      * Formats an Object producing an <code>AttributedCharacterIterator</code>.
776      * You can use the returned <code>AttributedCharacterIterator</code>
777      * to build the resulting String, as well as to determine information
778      * about the resulting String.
779      * <p>
780      * Each attribute key of the AttributedCharacterIterator will be of type
781      * <code>NumberFormat.Field</code>, with the attribute value being the
782      * same as the attribute key.
783      *
784      * @exception NullPointerException if obj is null.
785      * @exception IllegalArgumentException when the Format cannot format the
786      * given object.
787      * @param obj The object to format
788      * @return AttributedCharacterIterator describing the formatted value.
789      * @since 1.4
790      */

791     public AttributedCharacterIterator JavaDoc formatToCharacterIterator(Object JavaDoc obj) {
792         CharacterIteratorFieldDelegate JavaDoc delegate =
793                          new CharacterIteratorFieldDelegate JavaDoc();
794         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
795
796         if (obj instanceof Double JavaDoc || obj instanceof Float JavaDoc) {
797             format(((Number JavaDoc)obj).doubleValue(), sb, delegate);
798         } else if (obj instanceof Long JavaDoc || obj instanceof Integer JavaDoc ||
799                    obj instanceof Short JavaDoc || obj instanceof Byte JavaDoc) {
800             format(((Number JavaDoc)obj).longValue(), sb, delegate);
801         } else if (obj instanceof BigDecimal JavaDoc) {
802             format((BigDecimal JavaDoc)obj, sb, delegate);
803         } else if (obj instanceof BigInteger JavaDoc) {
804             format((BigInteger JavaDoc)obj, sb, delegate, false);
805         } else if (obj == null) {
806             throw new NullPointerException JavaDoc(
807                 "formatToCharacterIterator must be passed non-null object");
808         } else {
809             throw new IllegalArgumentException JavaDoc(
810                 "Cannot format given Object as a Number");
811         }
812         return delegate.getIterator(sb.toString());
813     }
814
815     /**
816      * Complete the formatting of a finite number. On entry, the digitList must
817      * be filled in with the correct digits.
818      */

819     private StringBuffer JavaDoc subformat(StringBuffer JavaDoc result, FieldDelegate delegate,
820                                    boolean isNegative, boolean isInteger,
821                                    int maxIntDigits, int minIntDigits,
822                                    int maxFraDigits, int minFraDigits) {
823         // NOTE: This isn't required anymore because DigitList takes care of this.
824
//
825
// // The negative of the exponent represents the number of leading
826
// // zeros between the decimal and the first non-zero digit, for
827
// // a value < 0.1 (e.g., for 0.00123, -fExponent == 2). If this
828
// // is more than the maximum fraction digits, then we have an underflow
829
// // for the printed representation. We recognize this here and set
830
// // the DigitList representation to zero in this situation.
831
//
832
// if (-digitList.decimalAt >= getMaximumFractionDigits())
833
// {
834
// digitList.count = 0;
835
// }
836

837         char zero = symbols.getZeroDigit();
838         int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
839
char grouping = symbols.getGroupingSeparator();
840         char decimal = isCurrencyFormat ?
841             symbols.getMonetaryDecimalSeparator() :
842             symbols.getDecimalSeparator();
843
844         /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
845          * format as zero. This allows sensible computations and preserves
846          * relations such as signum(1/x) = signum(x), where x is +Infinity or
847          * -Infinity. Prior to this fix, we always formatted zero values as if
848          * they were positive. Liu 7/6/98.
849          */

850         if (digitList.isZero()) {
851             digitList.decimalAt = 0; // Normalize
852
}
853
854         if (isNegative) {
855             append(result, negativePrefix, delegate,
856                    getNegativePrefixFieldPositions(), Field.SIGN);
857         } else {
858             append(result, positivePrefix, delegate,
859                    getPositivePrefixFieldPositions(), Field.SIGN);
860         }
861
862         if (useExponentialNotation) {
863             int iFieldStart = result.length();
864             int iFieldEnd = -1;
865             int fFieldStart = -1;
866
867             // Minimum integer digits are handled in exponential format by
868
// adjusting the exponent. For example, 0.01234 with 3 minimum
869
// integer digits is "123.4E-4".
870

871             // Maximum integer digits are interpreted as indicating the
872
// repeating range. This is useful for engineering notation, in
873
// which the exponent is restricted to a multiple of 3. For
874
// example, 0.01234 with 3 maximum integer digits is "12.34e-3".
875
// If maximum integer digits are > 1 and are larger than
876
// minimum integer digits, then minimum integer digits are
877
// ignored.
878
int exponent = digitList.decimalAt;
879             int repeat = maxIntDigits;
880             int minimumIntegerDigits = minIntDigits;
881             if (repeat > 1 && repeat > minIntDigits) {
882                 // A repeating range is defined; adjust to it as follows.
883
// If repeat == 3, we have 6,5,4=>3; 3,2,1=>0; 0,-1,-2=>-3;
884
// -3,-4,-5=>-6, etc. This takes into account that the
885
// exponent we have here is off by one from what we expect;
886
// it is for the format 0.MMMMMx10^n.
887
if (exponent >= 1) {
888                     exponent = ((exponent - 1) / repeat) * repeat;
889                 } else {
890                     // integer division rounds towards 0
891
exponent = ((exponent - repeat) / repeat) * repeat;
892                 }
893                 minimumIntegerDigits = 1;
894             } else {
895                 // No repeating range is defined; use minimum integer digits.
896
exponent -= minimumIntegerDigits;
897             }
898
899             // We now output a minimum number of digits, and more if there
900
// are more digits, up to the maximum number of digits. We
901
// place the decimal point after the "integer" digits, which
902
// are the first (decimalAt - exponent) digits.
903
int minimumDigits = minIntDigits + minFraDigits;
904             if (minimumDigits < 0) { // overflow?
905
minimumDigits = Integer.MAX_VALUE;
906             }
907
908             // The number of integer digits is handled specially if the number
909
// is zero, since then there may be no digits.
910
int integerDigits = digitList.isZero() ? minimumIntegerDigits :
911                     digitList.decimalAt - exponent;
912             if (minimumDigits < integerDigits) {
913                 minimumDigits = integerDigits;
914             }
915             int totalDigits = digitList.count;
916             if (minimumDigits > totalDigits) {
917                 totalDigits = minimumDigits;
918             }
919             boolean addedDecimalSeparator = false;
920
921             for (int i=0; i<totalDigits; ++i) {
922                 if (i == integerDigits) {
923                     // Record field information for caller.
924
iFieldEnd = result.length();
925
926                     result.append(decimal);
927                     addedDecimalSeparator = true;
928
929                     // Record field information for caller.
930
fFieldStart = result.length();
931                 }
932                 result.append((i < digitList.count) ?
933                               (char)(digitList.digits[i] + zeroDelta) :
934                               zero);
935             }
936
937             if (decimalSeparatorAlwaysShown && totalDigits == integerDigits) {
938                 // Record field information for caller.
939
iFieldEnd = result.length();
940
941                 result.append(decimal);
942                 addedDecimalSeparator = true;
943
944                 // Record field information for caller.
945
fFieldStart = result.length();
946             }
947
948             // Record field information
949
if (iFieldEnd == -1) {
950                 iFieldEnd = result.length();
951             }
952             delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
953                                iFieldStart, iFieldEnd, result);
954             if (addedDecimalSeparator) {
955                 delegate.formatted(Field.DECIMAL_SEPARATOR,
956                                    Field.DECIMAL_SEPARATOR,
957                                    iFieldEnd, fFieldStart, result);
958             }
959             if (fFieldStart == -1) {
960                 fFieldStart = result.length();
961             }
962             delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
963                                fFieldStart, result.length(), result);
964
965             // The exponent is output using the pattern-specified minimum
966
// exponent digits. There is no maximum limit to the exponent
967
// digits, since truncating the exponent would result in an
968
// unacceptable inaccuracy.
969
int fieldStart = result.length();
970
971             result.append(symbols.getExponentialSymbol());
972
973             delegate.formatted(Field.EXPONENT_SYMBOL, Field.EXPONENT_SYMBOL,
974                                fieldStart, result.length(), result);
975
976             // For zero values, we force the exponent to zero. We
977
// must do this here, and not earlier, because the value
978
// is used to determine integer digit count above.
979
if (digitList.isZero()) {
980                 exponent = 0;
981             }
982
983             boolean negativeExponent = exponent < 0;
984             if (negativeExponent) {
985                 exponent = -exponent;
986                 fieldStart = result.length();
987                 result.append(symbols.getMinusSign());
988                 delegate.formatted(Field.EXPONENT_SIGN, Field.EXPONENT_SIGN,
989                                    fieldStart, result.length(), result);
990             }
991             digitList.set(exponent);
992
993             int eFieldStart = result.length();
994
995             for (int i=digitList.decimalAt; i<minExponentDigits; ++i) {
996                 result.append(zero);
997             }
998             for (int i=0; i<digitList.decimalAt; ++i) {
999                 result.append((i < digitList.count) ?
1000                          (char)(digitList.digits[i] + zeroDelta) : zero);
1001            }
1002            delegate.formatted(Field.EXPONENT, Field.EXPONENT, eFieldStart,
1003                               result.length(), result);
1004        } else {
1005            int iFieldStart = result.length();
1006
1007            // Output the integer portion. Here 'count' is the total
1008
// number of integer digits we will display, including both
1009
// leading zeros required to satisfy getMinimumIntegerDigits,
1010
// and actual digits present in the number.
1011
int count = minIntDigits;
1012            int digitIndex = 0; // Index into digitList.fDigits[]
1013
if (digitList.decimalAt > 0 && count < digitList.decimalAt) {
1014                count = digitList.decimalAt;
1015            }
1016
1017            // Handle the case where getMaximumIntegerDigits() is smaller
1018
// than the real number of integer digits. If this is so, we
1019
// output the least significant max integer digits. For example,
1020
// the value 1997 printed with 2 max integer digits is just "97".
1021
if (count > maxIntDigits) {
1022                count = maxIntDigits;
1023                digitIndex = digitList.decimalAt - count;
1024            }
1025
1026            int sizeBeforeIntegerPart = result.length();
1027            for (int i=count-1; i>=0; --i) {
1028                if (i < digitList.decimalAt && digitIndex < digitList.count) {
1029                    // Output a real digit
1030
result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
1031                } else {
1032                    // Output a leading zero
1033
result.append(zero);
1034                }
1035
1036                // Output grouping separator if necessary. Don't output a
1037
// grouping separator if i==0 though; that's at the end of
1038
// the integer part.
1039
if (isGroupingUsed() && i>0 && (groupingSize != 0) &&
1040                    (i % groupingSize == 0)) {
1041                    int gStart = result.length();
1042                    result.append(grouping);
1043                    delegate.formatted(Field.GROUPING_SEPARATOR,
1044                                       Field.GROUPING_SEPARATOR, gStart,
1045                                       result.length(), result);
1046                }
1047            }
1048
1049            // Determine whether or not there are any printable fractional
1050
// digits. If we've used up the digits we know there aren't.
1051
boolean fractionPresent = (minFraDigits > 0) ||
1052                (!isInteger && digitIndex < digitList.count);
1053
1054            // If there is no fraction present, and we haven't printed any
1055
// integer digits, then print a zero. Otherwise we won't print
1056
// _any_ digits, and we won't be able to parse this string.
1057
if (!fractionPresent && result.length() == sizeBeforeIntegerPart) {
1058                result.append(zero);
1059            }
1060
1061            delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
1062                               iFieldStart, result.length(), result);
1063
1064            // Output the decimal separator if we always do so.
1065
int sStart = result.length();
1066            if (decimalSeparatorAlwaysShown || fractionPresent) {
1067                result.append(decimal);
1068            }
1069
1070            if (sStart != result.length()) {
1071                delegate.formatted(Field.DECIMAL_SEPARATOR,
1072                                   Field.DECIMAL_SEPARATOR,
1073                                   sStart, result.length(), result);
1074            }
1075            int fFieldStart = result.length();
1076
1077            for (int i=0; i < maxFraDigits; ++i) {
1078                // Here is where we escape from the loop. We escape if we've
1079
// output the maximum fraction digits (specified in the for
1080
// expression above).
1081
// We also stop when we've output the minimum digits and either:
1082
// we have an integer, so there is no fractional stuff to
1083
// display, or we're out of significant digits.
1084
if (i >= minFraDigits &&
1085                    (isInteger || digitIndex >= digitList.count)) {
1086                    break;
1087                }
1088
1089                // Output leading fractional zeros. These are zeros that come
1090
// after the decimal but before any significant digits. These
1091
// are only output if abs(number being formatted) < 1.0.
1092
if (-1-i > (digitList.decimalAt-1)) {
1093                    result.append(zero);
1094                    continue;
1095                }
1096
1097                // Output a digit, if we have any precision left, or a
1098
// zero if we don't. We don't want to output noise digits.
1099
if (!isInteger && digitIndex < digitList.count) {
1100                    result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
1101                } else {
1102                    result.append(zero);
1103                }
1104            }
1105
1106            // Record field information for caller.
1107
delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
1108                               fFieldStart, result.length(), result);
1109        }
1110
1111        if (isNegative) {
1112            append(result, negativeSuffix, delegate,
1113                   getNegativeSuffixFieldPositions(), Field.SIGN);
1114        }
1115        else {
1116            append(result, positiveSuffix, delegate,
1117                   getPositiveSuffixFieldPositions(), Field.SIGN);
1118        }
1119
1120        return result;
1121    }
1122
1123    /**
1124     * Appends the String <code>string</code> to <code>result</code>.
1125     * <code>delegate</code> is notified of all the
1126     * <code>FieldPosition</code>s in <code>positions</code>.
1127     * <p>
1128     * If one of the <code>FieldPosition</code>s in <code>positions</code>
1129     * identifies a <code>SIGN</code> attribute, it is mapped to
1130     * <code>signAttribute</code>. This is used
1131     * to map the <code>SIGN</code> attribute to the <code>EXPONENT</code>
1132     * attribute as necessary.
1133     * <p>
1134     * This is used by <code>subformat</code> to add the prefix/suffix.
1135     */

1136    private void append(StringBuffer JavaDoc result, String JavaDoc string,
1137                        FieldDelegate delegate,
1138                        FieldPosition JavaDoc[] positions,
1139                        Format.Field JavaDoc signAttribute) {
1140        int start = result.length();
1141
1142        if (string.length() > 0) {
1143            result.append(string);
1144            for (int counter = 0, max = positions.length; counter < max;
1145                 counter++) {
1146                FieldPosition JavaDoc fp = positions[counter];
1147                Format.Field JavaDoc attribute = fp.getFieldAttribute();
1148
1149                if (attribute == Field.SIGN) {
1150                    attribute = signAttribute;
1151                }
1152                delegate.formatted(attribute, attribute,
1153                                   start + fp.getBeginIndex(),
1154                                   start + fp.getEndIndex(), result);
1155            }
1156        }
1157    }
1158
1159    /**
1160     * Parses text from a string to produce a <code>Number</code>.
1161     * <p>
1162     * The method attempts to parse text starting at the index given by
1163     * <code>pos</code>.
1164     * If parsing succeeds, then the index of <code>pos</code> is updated
1165     * to the index after the last character used (parsing does not necessarily
1166     * use all characters up to the end of the string), and the parsed
1167     * number is returned. The updated <code>pos</code> can be used to
1168     * indicate the starting point for the next call to this method.
1169     * If an error occurs, then the index of <code>pos</code> is not
1170     * changed, the error index of <code>pos</code> is set to the index of
1171     * the character where the error occurred, and null is returned.
1172     * <p>
1173     * The subclass returned depends on the value of {@link #isParseBigDecimal}
1174     * as well as on the string being parsed.
1175     * <ul>
1176     * <li>If <code>isParseBigDecimal()</code> is false (the default),
1177     * most integer values are returned as <code>Long</code>
1178     * objects, no matter how they are written: <code>"17"</code> and
1179     * <code>"17.000"</code> both parse to <code>Long(17)</code>.
1180     * Values that cannot fit into a <code>Long</code> are returned as
1181     * <code>Double</code>s. This includes values with a fractional part,
1182     * infinite values, <code>NaN</code>, and the value -0.0.
1183     * <code>DecimalFormat</code> does <em>not</em> decide whether to
1184     * return a <code>Double</code> or a <code>Long</code> based on the
1185     * presence of a decimal separator in the source string. Doing so
1186     * would prevent integers that overflow the mantissa of a double,
1187     * such as <code>"-9,223,372,036,854,775,808.00"</code>, from being
1188     * parsed accurately.
1189     * <p>
1190     * Callers may use the <code>Number</code> methods
1191     * <code>doubleValue</code>, <code>longValue</code>, etc., to obtain
1192     * the type they want.
1193     * <li>If <code>isParseBigDecimal()</code> is true, values are returned
1194     * as <code>BigDecimal</code> objects. The values are the ones
1195     * constructed by {@link java.math.BigDecimal#BigDecimal(String)}
1196     * for corresponding strings in locale-independent format. The
1197     * special cases negative and positive infinity and NaN are returned
1198     * as <code>Double</code> instances holding the values of the
1199     * corresponding <code>Double</code> constants.
1200     * </ul>
1201     * <p>
1202     * <code>DecimalFormat</code> parses all Unicode characters that represent
1203     * decimal digits, as defined by <code>Character.digit()</code>. In
1204     * addition, <code>DecimalFormat</code> also recognizes as digits the ten
1205     * consecutive characters starting with the localized zero digit defined in
1206     * the <code>DecimalFormatSymbols</code> object.
1207     *
1208     * @param text the string to be parsed
1209     * @param pos A <code>ParsePosition</code> object with index and error
1210     * index information as described above.
1211     * @return the parsed value, or <code>null</code> if the parse fails
1212     * @exception NullPointerException if <code>text</code> or
1213     * <code>pos</code> is null.
1214     */

1215    public Number JavaDoc parse(String JavaDoc text, ParsePosition JavaDoc pos) {
1216        // special case NaN
1217
if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) {
1218            pos.index = pos.index + symbols.getNaN().length();
1219            return new Double JavaDoc(Double.NaN);
1220        }
1221
1222        boolean[] status = new boolean[STATUS_LENGTH];
1223        if (!subparse(text, pos, positivePrefix, negativePrefix, digitList, false, status)) {
1224            return null;
1225        }
1226
1227        // special case INFINITY
1228
if (status[STATUS_INFINITE]) {
1229            if (status[STATUS_POSITIVE] == (multiplier >= 0)) {
1230                return new Double JavaDoc(Double.POSITIVE_INFINITY);
1231            } else {
1232                return new Double JavaDoc(Double.NEGATIVE_INFINITY);
1233            }
1234        }
1235
1236        if (multiplier == 0) {
1237            if (digitList.isZero()) {
1238                return new Double JavaDoc(Double.NaN);
1239            } else if (status[STATUS_POSITIVE]) {
1240                return new Double JavaDoc(Double.POSITIVE_INFINITY);
1241            } else {
1242                return new Double JavaDoc(Double.NEGATIVE_INFINITY);
1243            }
1244        }
1245
1246        if (isParseBigDecimal()) {
1247            BigDecimal JavaDoc bigDecimalResult = digitList.getBigDecimal();
1248
1249            if (multiplier != 1) {
1250                try {
1251                    bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier());
1252                }
1253                catch (ArithmeticException JavaDoc e) { // non-terminating decimal expansion
1254
bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier(), BigDecimal.ROUND_HALF_EVEN);
1255                }
1256            }
1257
1258            if (!status[STATUS_POSITIVE]) {
1259                bigDecimalResult = bigDecimalResult.negate();
1260            }
1261            return bigDecimalResult;
1262        } else {
1263            boolean gotDouble = true;
1264            boolean gotLongMinimum = false;
1265            double doubleResult = 0.0;
1266            long longResult = 0;
1267
1268            // Finally, have DigitList parse the digits into a value.
1269
if (digitList.fitsIntoLong(status[STATUS_POSITIVE], isParseIntegerOnly())) {
1270                gotDouble = false;
1271                longResult = digitList.getLong();
1272                if (longResult < 0) { // got Long.MIN_VALUE
1273
gotLongMinimum = true;
1274                }
1275            } else {
1276                doubleResult = digitList.getDouble();
1277            }
1278
1279            // Divide by multiplier. We have to be careful here not to do
1280
// unneeded conversions between double and long.
1281
if (multiplier != 1) {
1282                if (gotDouble) {
1283                    doubleResult /= multiplier;
1284                } else {
1285                    // Avoid converting to double if we can
1286
if (longResult % multiplier == 0) {
1287                        longResult /= multiplier;
1288                    } else {
1289                        doubleResult = ((double)longResult) / multiplier;
1290                        gotDouble = true;
1291                    }
1292                }
1293            }
1294
1295            if (!status[STATUS_POSITIVE] && !gotLongMinimum) {
1296                doubleResult = -doubleResult;
1297                longResult = -longResult;
1298            }
1299
1300            // At this point, if we divided the result by the multiplier, the
1301
// result may fit into a long. We check for this case and return
1302
// a long if possible.
1303
// We must do this AFTER applying the negative (if appropriate)
1304
// in order to handle the case of LONG_MIN; otherwise, if we do
1305
// this with a positive value -LONG_MIN, the double is > 0, but
1306
// the long is < 0. We also must retain a double in the case of
1307
// -0.0, which will compare as == to a long 0 cast to a double
1308
// (bug 4162852).
1309
if (multiplier != 1 && gotDouble) {
1310                longResult = (long)doubleResult;
1311                gotDouble = ((doubleResult != (double)longResult) ||
1312                            (doubleResult == 0.0 && 1/doubleResult < 0.0)) &&
1313                            !isParseIntegerOnly();
1314            }
1315
1316            return gotDouble ?
1317                (Number JavaDoc)new Double JavaDoc(doubleResult) : (Number JavaDoc)new Long JavaDoc(longResult);
1318        }
1319    }
1320
1321    /**
1322     * Return a BigInteger multiplier.
1323     */

1324    private BigInteger JavaDoc getBigIntegerMultiplier() {
1325        if (bigIntegerMultiplier == null) {
1326            bigIntegerMultiplier = BigInteger.valueOf(multiplier);
1327        }
1328        return bigIntegerMultiplier;
1329    }
1330    private transient BigInteger JavaDoc bigIntegerMultiplier;
1331
1332    /**
1333     * Return a BigDecimal multiplier.
1334     */

1335    private BigDecimal JavaDoc getBigDecimalMultiplier() {
1336        if (bigDecimalMultiplier == null) {
1337            bigDecimalMultiplier = new BigDecimal JavaDoc(multiplier);
1338        }
1339        return bigDecimalMultiplier;
1340    }
1341    private transient BigDecimal JavaDoc bigDecimalMultiplier;
1342
1343    private static final int STATUS_INFINITE = 0;
1344    private static final int STATUS_POSITIVE = 1;
1345    private static final int STATUS_LENGTH = 2;
1346
1347    /**
1348     * Parse the given text into a number. The text is parsed beginning at
1349     * parsePosition, until an unparseable character is seen.
1350     * @param text The string to parse.
1351     * @param parsePosition The position at which to being parsing. Upon
1352     * return, the first unparseable character.
1353     * @param digits The DigitList to set to the parsed value.
1354     * @param isExponent If true, parse an exponent. This means no
1355     * infinite values and integer only.
1356     * @param status Upon return contains boolean status flags indicating
1357     * whether the value was infinite and whether it was positive.
1358     */

1359    private final boolean subparse(String JavaDoc text, ParsePosition JavaDoc parsePosition,
1360                   String JavaDoc positivePrefix, String JavaDoc negativePrefix,
1361                   DigitList JavaDoc digits, boolean isExponent,
1362                   boolean status[]) {
1363        int position = parsePosition.index;
1364        int oldStart = parsePosition.index;
1365        int backup;
1366        boolean gotPositive, gotNegative;
1367
1368        // check for positivePrefix; take longest
1369
gotPositive = text.regionMatches(position, positivePrefix, 0,
1370                                         positivePrefix.length());
1371        gotNegative = text.regionMatches(position, negativePrefix, 0,
1372                                         negativePrefix.length());
1373
1374        if (gotPositive && gotNegative) {
1375            if (positivePrefix.length() > negativePrefix.length()) {
1376                gotNegative = false;
1377            } else if (positivePrefix.length() < negativePrefix.length()) {
1378                gotPositive = false;
1379            }
1380        }
1381
1382        if (gotPositive) {
1383            position += positivePrefix.length();
1384        } else if (gotNegative) {
1385            position += negativePrefix.length();
1386        } else {
1387            parsePosition.errorIndex = position;
1388            return false;
1389        }
1390
1391        // process digits or Inf, find decimal position
1392
status[STATUS_INFINITE] = false;
1393        if (!isExponent && text.regionMatches(position,symbols.getInfinity(),0,
1394                          symbols.getInfinity().length())) {
1395            position += symbols.getInfinity().length();
1396            status[STATUS_INFINITE] = true;
1397        } else {
1398            // We now have a string of digits, possibly with grouping symbols,
1399
// and decimal points. We want to process these into a DigitList.
1400
// We don't want to put a bunch of leading zeros into the DigitList
1401
// though, so we keep track of the location of the decimal point,
1402
// put only significant digits into the DigitList, and adjust the
1403
// exponent as needed.
1404

1405            digits.decimalAt = digits.count = 0;
1406            char zero = symbols.getZeroDigit();
1407            char decimal = isCurrencyFormat ?
1408                symbols.getMonetaryDecimalSeparator() :
1409                symbols.getDecimalSeparator();
1410            char grouping = symbols.getGroupingSeparator();
1411            char exponentChar = symbols.getExponentialSymbol();
1412            boolean sawDecimal = false;
1413            boolean sawExponent = false;
1414            boolean sawDigit = false;
1415            int exponent = 0; // Set to the exponent value, if any
1416

1417            // We have to track digitCount ourselves, because digits.count will
1418
// pin when the maximum allowable digits is reached.
1419
int digitCount = 0;
1420
1421            backup = -1;
1422            for (; position < text.length(); ++position) {
1423                char ch = text.charAt(position);
1424
1425                /* We recognize all digit ranges, not only the Latin digit range
1426                 * '0'..'9'. We do so by using the Character.digit() method,
1427                 * which converts a valid Unicode digit to the range 0..9.
1428                 *
1429                 * The character 'ch' may be a digit. If so, place its value
1430                 * from 0 to 9 in 'digit'. First try using the locale digit,
1431                 * which may or MAY NOT be a standard Unicode digit range. If
1432                 * this fails, try using the standard Unicode digit ranges by
1433                 * calling Character.digit(). If this also fails, digit will
1434                 * have a value outside the range 0..9.
1435                 */

1436                int digit = ch - zero;
1437                if (digit < 0 || digit > 9) {
1438                    digit = Character.digit(ch, 10);
1439                }
1440
1441                if (digit == 0) {
1442                    // Cancel out backup setting (see grouping handler below)
1443
backup = -1; // Do this BEFORE continue statement below!!!
1444
sawDigit = true;
1445
1446                    // Handle leading zeros
1447
if (digits.count == 0) {
1448                        // Ignore leading zeros in integer part of number.
1449
if (!sawDecimal) {
1450                            continue;
1451                        }
1452
1453                        // If we have seen the decimal, but no significant
1454
// digits yet, then we account for leading zeros by
1455
// decrementing the digits.decimalAt into negative
1456
// values.
1457
--digits.decimalAt;
1458                    } else {
1459                        ++digitCount;
1460                        digits.append((char)(digit + '0'));
1461                    }
1462                } else if (digit > 0 && digit <= 9) { // [sic] digit==0 handled above
1463
sawDigit = true;
1464                    ++digitCount;
1465                    digits.append((char)(digit + '0'));
1466
1467                    // Cancel out backup setting (see grouping handler below)
1468
backup = -1;
1469                } else if (!isExponent && ch == decimal) {
1470                    // If we're only parsing integers, or if we ALREADY saw the
1471
// decimal, then don't parse this one.
1472
if (isParseIntegerOnly() || sawDecimal) {
1473                        break;
1474                    }
1475                    digits.decimalAt = digitCount; // Not digits.count!
1476
sawDecimal = true;
1477                } else if (!isExponent && ch == grouping && isGroupingUsed()) {
1478                    if (sawDecimal) {
1479                        break;
1480                    }
1481                    // Ignore grouping characters, if we are using them, but
1482
// require that they be followed by a digit. Otherwise
1483
// we backup and reprocess them.
1484
backup = position;
1485                } else if (!isExponent && ch == exponentChar && !sawExponent) {
1486                    // Process the exponent by recursively calling this method.
1487
ParsePosition JavaDoc pos = new ParsePosition JavaDoc(position + 1);
1488                    boolean[] stat = new boolean[STATUS_LENGTH];
1489                    DigitList JavaDoc exponentDigits = new DigitList JavaDoc();
1490
1491                    if (subparse(text, pos, "", Character.toString(symbols.getMinusSign()), exponentDigits, true, stat) &&
1492                        exponentDigits.fitsIntoLong(stat[STATUS_POSITIVE], true)) {
1493                        position = pos.index; // Advance past the exponent
1494
exponent = (int)exponentDigits.getLong();
1495                        if (!stat[STATUS_POSITIVE]) {
1496                            exponent = -exponent;
1497                        }
1498                        sawExponent = true;
1499                    }
1500                    break; // Whether we fail or succeed, we exit this loop
1501
}
1502                else {
1503                    break;
1504                }
1505            }
1506
1507            if (backup != -1) {
1508                position = backup;
1509            }
1510
1511            // If there was no decimal point we have an integer
1512
if (!sawDecimal) {
1513                digits.decimalAt = digitCount; // Not digits.count!
1514
}
1515
1516            // Adjust for exponent, if any
1517
digits.decimalAt += exponent;
1518
1519            // If none of the text string was recognized. For example, parse
1520
// "x" with pattern "#0.00" (return index and error index both 0)
1521
// parse "$" with pattern "$#0.00". (return index 0 and error
1522
// index 1).
1523
if (!sawDigit && digitCount == 0) {
1524                parsePosition.index = oldStart;
1525                parsePosition.errorIndex = oldStart;
1526                return false;
1527            }
1528        }
1529
1530        // check for suffix
1531
if (!isExponent) {
1532            if (gotPositive) {
1533                gotPositive = text.regionMatches(position,positiveSuffix,0,
1534                                                 positiveSuffix.length());
1535            }
1536            if (gotNegative) {
1537                gotNegative = text.regionMatches(position,negativeSuffix,0,
1538                                                 negativeSuffix.length());
1539            }
1540
1541        // if both match, take longest
1542
if (gotPositive && gotNegative) {
1543            if (positiveSuffix.length() > negativeSuffix.length()) {
1544                gotNegative = false;
1545            } else if (positiveSuffix.length() < negativeSuffix.length()) {
1546                gotPositive = false;
1547            }
1548        }
1549
1550        // fail if neither or both
1551
if (gotPositive == gotNegative) {
1552            parsePosition.errorIndex = position;
1553            return false;
1554        }
1555
1556        parsePosition.index = position +
1557            (gotPositive ? positiveSuffix.length() : negativeSuffix.length()); // mark success!
1558
} else {
1559            parsePosition.index = position;
1560        }
1561
1562        status[STATUS_POSITIVE] = gotPositive;
1563        if (parsePosition.index == oldStart) {
1564            parsePosition.errorIndex = position;
1565            return false;
1566        }
1567        return true;
1568    }
1569
1570    /**
1571     * Returns the decimal format symbols, which is generally not changed
1572     * by the programmer or user.
1573     * @return desired DecimalFormatSymbols
1574     * @see java.text.DecimalFormatSymbols
1575     */

1576    public DecimalFormatSymbols JavaDoc getDecimalFormatSymbols() {
1577        try {
1578            // don't allow multiple references
1579
return (DecimalFormatSymbols JavaDoc) symbols.clone();
1580        } catch (Exception JavaDoc foo) {
1581            return null; // should never happen
1582
}
1583    }
1584
1585
1586    /**
1587     * Sets the decimal format symbols, which is generally not changed
1588     * by the programmer or user.
1589     * @param newSymbols desired DecimalFormatSymbols
1590     * @see java.text.DecimalFormatSymbols
1591     */

1592    public void setDecimalFormatSymbols(DecimalFormatSymbols JavaDoc newSymbols) {
1593        try {
1594            // don't allow multiple references
1595
symbols = (DecimalFormatSymbols JavaDoc) newSymbols.clone();
1596            expandAffixes();
1597        } catch (Exception JavaDoc foo) {
1598            // should never happen
1599
}
1600    }
1601
1602    /**
1603     * Get the positive prefix.
1604     * <P>Examples: +123, $123, sFr123
1605     */

1606    public String JavaDoc getPositivePrefix () {
1607        return positivePrefix;
1608    }
1609
1610    /**
1611     * Set the positive prefix.
1612     * <P>Examples: +123, $123, sFr123
1613     */

1614    public void setPositivePrefix (String JavaDoc newValue) {
1615        positivePrefix = newValue;
1616        posPrefixPattern = null;
1617        positivePrefixFieldPositions = null;
1618    }
1619
1620    /**
1621     * Returns the FieldPositions of the fields in the prefix used for
1622     * positive numbers. This is not used if the user has explicitly set
1623     * a positive prefix via <code>setPositivePrefix</code>. This is
1624     * lazily created.
1625     *
1626     * @return FieldPositions in positive prefix
1627     */

1628    private FieldPosition JavaDoc[] getPositivePrefixFieldPositions() {
1629        if (positivePrefixFieldPositions == null) {
1630            if (posPrefixPattern != null) {
1631                positivePrefixFieldPositions = expandAffix(posPrefixPattern);
1632            }
1633            else {
1634                positivePrefixFieldPositions = EmptyFieldPositionArray;
1635            }
1636        }
1637        return positivePrefixFieldPositions;
1638    }
1639
1640    /**
1641     * Get the negative prefix.
1642     * <P>Examples: -123, ($123) (with negative suffix), sFr-123
1643     */

1644    public String JavaDoc getNegativePrefix () {
1645        return negativePrefix;
1646    }
1647
1648    /**
1649     * Set the negative prefix.
1650     * <P>Examples: -123, ($123) (with negative suffix), sFr-123
1651     */

1652    public void setNegativePrefix (String JavaDoc newValue) {
1653        negativePrefix = newValue;
1654        negPrefixPattern = null;
1655    }
1656
1657    /**
1658     * Returns the FieldPositions of the fields in the prefix used for
1659     * negative numbers. This is not used if the user has explicitly set
1660     * a negative prefix via <code>setNegativePrefix</code>. This is
1661     * lazily created.
1662     *
1663     * @return FieldPositions in positive prefix
1664     */

1665    private FieldPosition JavaDoc[] getNegativePrefixFieldPositions() {
1666        if (negativePrefixFieldPositions == null) {
1667            if (negPrefixPattern != null) {
1668                negativePrefixFieldPositions = expandAffix(negPrefixPattern);
1669            }
1670            else {
1671                negativePrefixFieldPositions = EmptyFieldPositionArray;
1672            }
1673        }
1674        return negativePrefixFieldPositions;
1675    }
1676
1677    /**
1678     * Get the positive suffix.
1679     * <P>Example: 123%
1680     */

1681    public String JavaDoc getPositiveSuffix () {
1682        return positiveSuffix;
1683    }
1684
1685    /**
1686     * Set the positive suffix.
1687     * <P>Example: 123%
1688     */

1689    public void setPositiveSuffix (String JavaDoc newValue) {
1690        positiveSuffix = newValue;
1691        posSuffixPattern = null;
1692    }
1693
1694    /**
1695     * Returns the FieldPositions of the fields in the suffix used for
1696     * positive numbers. This is not used if the user has explicitly set
1697     * a positive suffix via <code>setPositiveSuffix</code>. This is
1698     * lazily created.
1699     *
1700     * @return FieldPositions in positive prefix
1701     */

1702    private FieldPosition JavaDoc[] getPositiveSuffixFieldPositions() {
1703        if (positiveSuffixFieldPositions == null) {
1704            if (posSuffixPattern != null) {
1705                positiveSuffixFieldPositions = expandAffix(posSuffixPattern);
1706            }
1707            else {
1708                positiveSuffixFieldPositions = EmptyFieldPositionArray;
1709            }
1710        }
1711        return positiveSuffixFieldPositions;
1712    }
1713
1714    /**
1715     * Get the negative suffix.
1716     * <P>Examples: -123%, ($123) (with positive suffixes)
1717     */

1718    public String JavaDoc getNegativeSuffix () {
1719        return negativeSuffix;
1720    }
1721
1722    /**
1723     * Set the negative suffix.
1724     * <P>Examples: 123%
1725     */

1726    public void setNegativeSuffix (String JavaDoc newValue) {
1727        negativeSuffix = newValue;
1728        negSuffixPattern = null;
1729    }
1730
1731    /**
1732     * Returns the FieldPositions of the fields in the suffix used for
1733     * negative numbers. This is not used if the user has explicitly set
1734     * a negative suffix via <code>setNegativeSuffix</code>. This is
1735     * lazily created.
1736     *
1737     * @return FieldPositions in positive prefix
1738     */

1739    private FieldPosition JavaDoc[] getNegativeSuffixFieldPositions() {
1740        if (negativeSuffixFieldPositions == null) {
1741            if (negSuffixPattern != null) {
1742                negativeSuffixFieldPositions = expandAffix(negSuffixPattern);
1743            }
1744            else {
1745                negativeSuffixFieldPositions = EmptyFieldPositionArray;
1746            }
1747        }
1748        return negativeSuffixFieldPositions;
1749    }
1750
1751    /**
1752     * Gets the multiplier for use in percent, per mille, and similar
1753     * formats.
1754     *
1755     * @see #setMultiplier(int)
1756     */

1757    public int getMultiplier () {
1758        return multiplier;
1759    }
1760
1761    /**
1762     * Sets the multiplier for use in percent, per mille, and similar
1763     * formats.
1764     * For a percent format, set the multiplier to 100 and the suffixes to
1765     * have '%' (for Arabic, use the Arabic percent sign).
1766     * For a per mille format, set the multiplier to 1000 and the suffixes to
1767     * have '&#92;u2030'.
1768     *
1769     * <P>Example: with multiplier 100, 1.23 is formatted as "123", and
1770     * "123" is parsed into 1.23.
1771     *
1772     * @see #getMultiplier
1773     */

1774    public void setMultiplier (int newValue) {
1775        multiplier = newValue;
1776        bigDecimalMultiplier = null;
1777        bigIntegerMultiplier = null;
1778    }
1779
1780    /**
1781     * Return the grouping size. Grouping size is the number of digits between
1782     * grouping separators in the integer portion of a number. For example,
1783     * in the number "123,456.78", the grouping size is 3.
1784     * @see #setGroupingSize
1785     * @see java.text.NumberFormat#isGroupingUsed
1786     * @see java.text.DecimalFormatSymbols#getGroupingSeparator
1787     */

1788    public int getGroupingSize () {
1789        return groupingSize;
1790    }
1791
1792    /**
1793     * Set the grouping size. Grouping size is the number of digits between
1794     * grouping separators in the integer portion of a number. For example,
1795     * in the number "123,456.78", the grouping size is 3.
1796     * <br>
1797     * The value passed in is converted to a byte, which may lose information.
1798     * @see #getGroupingSize
1799     * @see java.text.NumberFormat#setGroupingUsed
1800     * @see java.text.DecimalFormatSymbols#setGroupingSeparator
1801     */

1802    public void setGroupingSize (int newValue) {
1803        groupingSize = (byte)newValue;
1804    }
1805
1806    /**
1807     * Allows you to get the behavior of the decimal separator with integers.
1808     * (The decimal separator will always appear with decimals.)
1809     * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
1810     */

1811    public boolean isDecimalSeparatorAlwaysShown() {
1812        return decimalSeparatorAlwaysShown;
1813    }
1814
1815    /**
1816     * Allows you to set the behavior of the decimal separator with integers.
1817     * (The decimal separator will always appear with decimals.)
1818     * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
1819     */

1820    public void setDecimalSeparatorAlwaysShown(boolean newValue) {
1821        decimalSeparatorAlwaysShown = newValue;
1822    }
1823
1824    /**
1825     * Returns whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1826     * method returns <code>BigDecimal</code>. The default value is false.
1827     * @see #setParseBigDecimal
1828     * @since 1.5
1829     */

1830    public boolean isParseBigDecimal() {
1831        return parseBigDecimal;
1832    }
1833
1834    /**
1835     * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1836     * method returns <code>BigDecimal</code>.
1837     * @see #isParseBigDecimal
1838     * @since 1.5
1839     */

1840    public void setParseBigDecimal(boolean newValue) {
1841        parseBigDecimal = newValue;
1842    }
1843
1844    /**
1845     * Standard override; no change in semantics.
1846     */

1847    public Object JavaDoc clone() {
1848        try {
1849            DecimalFormat JavaDoc other = (DecimalFormat JavaDoc) super.clone();
1850            other.symbols = (DecimalFormatSymbols JavaDoc) symbols.clone();
1851            other.digitList = (DigitList JavaDoc) digitList.clone();
1852            return other;
1853        } catch (Exception JavaDoc e) {
1854            throw new InternalError JavaDoc();
1855        }
1856    }
1857
1858    /**
1859     * Overrides equals
1860     */

1861    public boolean equals(Object JavaDoc obj)
1862    {
1863        if (obj == null) return false;
1864        if (!super.equals(obj)) return false; // super does class check
1865
DecimalFormat JavaDoc other = (DecimalFormat JavaDoc) obj;
1866        return ((posPrefixPattern == other.posPrefixPattern &&
1867                 positivePrefix.equals(other.positivePrefix))
1868                || (posPrefixPattern != null &&
1869                    posPrefixPattern.equals(other.posPrefixPattern)))
1870            && ((posSuffixPattern == other.posSuffixPattern &&
1871                 positiveSuffix.equals(other.positiveSuffix))
1872                || (posSuffixPattern != null &&
1873                    posSuffixPattern.equals(other.posSuffixPattern)))
1874            && ((negPrefixPattern == other.negPrefixPattern &&
1875                 negativePrefix.equals(other.negativePrefix))
1876                || (negPrefixPattern != null &&
1877                    negPrefixPattern.equals(other.negPrefixPattern)))
1878            && ((negSuffixPattern == other.negSuffixPattern &&
1879                 negativeSuffix.equals(other.negativeSuffix))
1880                || (negSuffixPattern != null &&
1881                    negSuffixPattern.equals(other.negSuffixPattern)))
1882            && multiplier == other.multiplier
1883            && groupingSize == other.groupingSize
1884            && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown
1885            && parseBigDecimal == other.parseBigDecimal
1886            && useExponentialNotation == other.useExponentialNotation
1887            && (!useExponentialNotation ||
1888                minExponentDigits == other.minExponentDigits)
1889            && maximumIntegerDigits == other.maximumIntegerDigits
1890            && minimumIntegerDigits == other.minimumIntegerDigits
1891            && maximumFractionDigits == other.maximumFractionDigits
1892            && minimumFractionDigits == other.minimumFractionDigits
1893            && symbols.equals(other.symbols);
1894    }
1895
1896    /**
1897     * Overrides hashCode
1898     */

1899    public int hashCode() {
1900        return super.hashCode() * 37 + positivePrefix.hashCode();
1901        // just enough fields for a reasonable distribution
1902
}
1903
1904    /**
1905     * Synthesizes a pattern string that represents the current state
1906     * of this Format object.
1907     * @see #applyPattern
1908     */

1909    public String JavaDoc toPattern() {
1910        return toPattern( false );
1911    }
1912
1913    /**
1914     * Synthesizes a localized pattern string that represents the current
1915     * state of this Format object.
1916     * @see #applyPattern
1917     */

1918    public String JavaDoc toLocalizedPattern() {
1919        return toPattern( true );
1920    }
1921
1922    /**
1923     * Expand the affix pattern strings into the expanded affix strings. If any
1924     * affix pattern string is null, do not expand it. This method should be
1925     * called any time the symbols or the affix patterns change in order to keep
1926     * the expanded affix strings up to date.
1927     */

1928    private void expandAffixes() {
1929        // Reuse one StringBuffer for better performance
1930
StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
1931        if (posPrefixPattern != null) {
1932            positivePrefix = expandAffix(posPrefixPattern, buffer);
1933            positivePrefixFieldPositions = null;
1934        }
1935        if (posSuffixPattern != null) {
1936            positiveSuffix = expandAffix(posSuffixPattern, buffer);
1937            positiveSuffixFieldPositions = null;
1938        }
1939        if (negPrefixPattern != null) {
1940            negativePrefix = expandAffix(negPrefixPattern, buffer);
1941            negativePrefixFieldPositions = null;
1942        }
1943        if (negSuffixPattern != null) {
1944            negativeSuffix = expandAffix(negSuffixPattern, buffer);
1945            negativeSuffixFieldPositions = null;
1946        }
1947    }
1948
1949    /**
1950     * Expand an affix pattern into an affix string. All characters in the
1951     * pattern are literal unless prefixed by QUOTE. The following characters
1952     * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
1953     * PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE +
1954     * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
1955     * currency code. Any other character after a QUOTE represents itself.
1956     * QUOTE must be followed by another character; QUOTE may not occur by
1957     * itself at the end of the pattern.
1958     *
1959     * @param pattern the non-null, possibly empty pattern
1960     * @param buffer a scratch StringBuffer; its contents will be lost
1961     * @return the expanded equivalent of pattern
1962     */

1963    private String JavaDoc expandAffix(String JavaDoc pattern, StringBuffer JavaDoc buffer) {
1964        buffer.setLength(0);
1965        for (int i=0; i<pattern.length(); ) {
1966            char c = pattern.charAt(i++);
1967            if (c == QUOTE) {
1968                c = pattern.charAt(i++);
1969                switch (c) {
1970                case CURRENCY_SIGN:
1971                    if (i<pattern.length() &&
1972                        pattern.charAt(i) == CURRENCY_SIGN) {
1973                        ++i;
1974                        buffer.append(symbols.getInternationalCurrencySymbol());
1975                    } else {
1976                        buffer.append(symbols.getCurrencySymbol());
1977                    }
1978                    continue;
1979                case PATTERN_PERCENT:
1980                    c = symbols.getPercent();
1981                    break;
1982                case PATTERN_PER_MILLE:
1983                    c = symbols.getPerMill();
1984                    break;
1985                case PATTERN_MINUS:
1986                    c = symbols.getMinusSign();
1987                    break;
1988                }
1989            }
1990            buffer.append(c);
1991        }
1992        return buffer.toString();
1993    }
1994
1995    /**
1996     * Expand an affix pattern into an array of FieldPositions describing
1997     * how the pattern would be expanded.
1998     * All characters in the
1999     * pattern are literal unless prefixed by QUOTE. The following characters
2000     * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2001     * PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE +
2002     * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
2003     * currency code. Any other character after a QUOTE represents itself.
2004     * QUOTE must be followed by another character; QUOTE may not occur by
2005     * itself at the end of the pattern.
2006     *
2007     * @param pattern the non-null, possibly empty pattern
2008     * @return FieldPosition array of the resulting fields.
2009     */

2010    private FieldPosition JavaDoc[] expandAffix(String JavaDoc pattern) {
2011        ArrayList JavaDoc positions = null;
2012        int stringIndex = 0;
2013        for (int i=0; i<pattern.length(); ) {
2014            char c = pattern.charAt(i++);
2015            if (c == QUOTE) {
2016                int field = -1;
2017                Format.Field JavaDoc fieldID = null;
2018                c = pattern.charAt(i++);
2019                switch (c) {
2020                case CURRENCY_SIGN:
2021                    String JavaDoc string;
2022                    if (i<pattern.length() &&
2023                        pattern.charAt(i) == CURRENCY_SIGN) {
2024                        ++i;
2025                        string = symbols.getInternationalCurrencySymbol();
2026                    } else {
2027                        string = symbols.getCurrencySymbol();
2028                    }
2029                    if (string.length() > 0) {
2030                        if (positions == null) {
2031                            positions = new ArrayList JavaDoc(2);
2032                        }
2033                        FieldPosition JavaDoc fp = new FieldPosition JavaDoc(Field.CURRENCY);
2034                        fp.setBeginIndex(stringIndex);
2035                        fp.setEndIndex(stringIndex + string.length());
2036                        positions.add(fp);
2037                        stringIndex += string.length();
2038                    }
2039                    continue;
2040                case PATTERN_PERCENT:
2041                    c = symbols.getPercent();
2042                    field = -1;
2043                    fieldID = Field.PERCENT;
2044                    break;
2045                case PATTERN_PER_MILLE:
2046                    c = symbols.getPerMill();
2047                    field = -1;
2048                    fieldID = Field.PERMILLE;
2049                    break;
2050                case PATTERN_MINUS:
2051                    c = symbols.getMinusSign();
2052                    field = -1;
2053                    fieldID = Field.SIGN;
2054                    break;
2055                }
2056                if (fieldID != null) {
2057                    if (positions == null) {
2058                        positions = new ArrayList JavaDoc(2);
2059                    }
2060                    FieldPosition JavaDoc fp = new FieldPosition JavaDoc(fieldID, field);
2061                    fp.setBeginIndex(stringIndex);
2062                    fp.setEndIndex(stringIndex + 1);
2063                    positions.add(fp);
2064                }
2065            }
2066            stringIndex++;
2067        }
2068        if (positions != null) {
2069            return (FieldPosition JavaDoc[])positions.toArray(EmptyFieldPositionArray);
2070        }
2071        return EmptyFieldPositionArray;
2072    }
2073
2074    /**
2075     * Appends an affix pattern to the given StringBuffer, quoting special
2076     * characters as needed. Uses the internal affix pattern, if that exists,
2077     * or the literal affix, if the internal affix pattern is null. The
2078     * appended string will generate the same affix pattern (or literal affix)
2079     * when passed to toPattern().
2080     *
2081     * @param buffer the affix string is appended to this
2082     * @param affixPattern a pattern such as posPrefixPattern; may be null
2083     * @param expAffix a corresponding expanded affix, such as positivePrefix.
2084     * Ignored unless affixPattern is null. If affixPattern is null, then
2085     * expAffix is appended as a literal affix.
2086     * @param localized true if the appended pattern should contain localized
2087     * pattern characters; otherwise, non-localized pattern chars are appended
2088     */

2089    private void appendAffix(StringBuffer JavaDoc buffer, String JavaDoc affixPattern,
2090                             String JavaDoc expAffix, boolean localized) {
2091        if (affixPattern == null) {
2092            appendAffix(buffer, expAffix, localized);
2093        } else {
2094            int i;
2095            for (int pos=0; pos<affixPattern.length(); pos=i) {
2096                i = affixPattern.indexOf(QUOTE, pos);
2097                if (i < 0) {
2098                    appendAffix(buffer, affixPattern.substring(pos), localized);
2099                    break;
2100                }
2101                if (i > pos) {
2102                    appendAffix(buffer, affixPattern.substring(pos, i), localized);
2103                }
2104                char c = affixPattern.charAt(++i);
2105                ++i;
2106                if (c == QUOTE) {
2107                    buffer.append(c);
2108                    // Fall through and append another QUOTE below
2109
} else if (c == CURRENCY_SIGN &&
2110                           i<affixPattern.length() &&
2111                           affixPattern.charAt(i) == CURRENCY_SIGN) {
2112                    ++i;
2113                    buffer.append(c);
2114                    // Fall through and append another CURRENCY_SIGN below
2115
} else if (localized) {
2116                    switch (c) {
2117                    case PATTERN_PERCENT:
2118                        c = symbols.getPercent();
2119                        break;
2120                    case PATTERN_PER_MILLE:
2121                        c = symbols.getPerMill();
2122                        break;
2123                    case PATTERN_MINUS:
2124                        c = symbols.getMinusSign();
2125                        break;
2126                    }
2127                }
2128                buffer.append(c);
2129            }
2130        }
2131    }
2132
2133    /**
2134     * Append an affix to the given StringBuffer, using quotes if
2135     * there are special characters. Single quotes themselves must be
2136     * escaped in either case.
2137     */

2138    private void appendAffix(StringBuffer JavaDoc buffer, String JavaDoc affix, boolean localized) {
2139        boolean needQuote;
2140        if (localized) {
2141            needQuote = affix.indexOf(symbols.getZeroDigit()) >= 0
2142                || affix.indexOf(symbols.getGroupingSeparator()) >= 0
2143                || affix.indexOf(symbols.getDecimalSeparator()) >= 0
2144                || affix.indexOf(symbols.getPercent()) >= 0
2145                || affix.indexOf(symbols.getPerMill()) >= 0
2146                || affix.indexOf(symbols.getDigit()) >= 0
2147                || affix.indexOf(symbols.getPatternSeparator()) >= 0
2148                || affix.indexOf(symbols.getMinusSign()) >= 0
2149                || affix.indexOf(CURRENCY_SIGN) >= 0;
2150        }
2151        else {
2152            needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 0
2153                || affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 0
2154                || affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 0
2155                || affix.indexOf(PATTERN_PERCENT) >= 0
2156                || affix.indexOf(PATTERN_PER_MILLE) >= 0
2157                || affix.indexOf(PATTERN_DIGIT) >= 0
2158                || affix.indexOf(PATTERN_SEPARATOR) >= 0
2159                || affix.indexOf(PATTERN_MINUS) >= 0
2160                || affix.indexOf(CURRENCY_SIGN) >= 0;
2161        }
2162        if (needQuote) buffer.append('\'');
2163        if (affix.indexOf('\'') < 0) buffer.append(affix);
2164        else {
2165            for (int j=0; j<affix.length(); ++j) {
2166                char c = affix.charAt(j);
2167                buffer.append(c);
2168                if (c == '\'') buffer.append(c);
2169            }
2170        }
2171        if (needQuote) buffer.append('\'');
2172    }
2173
2174    /**
2175     * Does the real work of generating a pattern. */

2176    private String JavaDoc toPattern(boolean localized) {
2177        StringBuffer JavaDoc result = new StringBuffer JavaDoc();
2178        for (int j = 1; j >= 0; --j) {
2179            if (j == 1)
2180                appendAffix(result, posPrefixPattern, positivePrefix, localized);
2181            else appendAffix(result, negPrefixPattern, negativePrefix, localized);
2182            int i;
2183            int digitCount = useExponentialNotation
2184                        ? getMaximumIntegerDigits()
2185                        : Math.max(groupingSize, getMinimumIntegerDigits())+1;
2186            for (i = digitCount; i > 0; --i) {
2187                if (i != digitCount && isGroupingUsed() && groupingSize != 0 &&
2188                    i % groupingSize == 0) {
2189                    result.append(localized ? symbols.getGroupingSeparator() :
2190                                  PATTERN_GROUPING_SEPARATOR);
2191                }
2192                result.append(i <= getMinimumIntegerDigits()
2193                    ? (localized ? symbols.getZeroDigit() : PATTERN_ZERO_DIGIT)
2194                    : (localized ? symbols.getDigit() : PATTERN_DIGIT));
2195            }
2196            if (getMaximumFractionDigits() > 0 || decimalSeparatorAlwaysShown)
2197                result.append(localized ? symbols.getDecimalSeparator() :
2198                              PATTERN_DECIMAL_SEPARATOR);
2199            for (i = 0; i < getMaximumFractionDigits(); ++i) {
2200                if (i < getMinimumFractionDigits()) {
2201                    result.append(localized ? symbols.getZeroDigit() :
2202                                  PATTERN_ZERO_DIGIT);
2203                } else {
2204                    result.append(localized ? symbols.getDigit() :
2205                                  PATTERN_DIGIT);
2206                }
2207            }
2208        if (useExponentialNotation)
2209        {
2210        result.append(localized ? symbols.getExponentialSymbol() :
2211                  PATTERN_EXPONENT);
2212        for (i=0; i<minExponentDigits; ++i)
2213                    result.append(localized ? symbols.getZeroDigit() :
2214                                  PATTERN_ZERO_DIGIT);
2215        }
2216            if (j == 1) {
2217                appendAffix(result, posSuffixPattern, positiveSuffix, localized);
2218                if ((negSuffixPattern == posSuffixPattern && // n == p == null
2219
negativeSuffix.equals(positiveSuffix))
2220                    || (negSuffixPattern != null &&
2221                        negSuffixPattern.equals(posSuffixPattern))) {
2222                    if ((negPrefixPattern != null && posPrefixPattern != null &&
2223                         negPrefixPattern.equals("'-" + posPrefixPattern)) ||
2224                        (negPrefixPattern == posPrefixPattern && // n == p == null
2225
negativePrefix.equals(symbols.getMinusSign() + positivePrefix)))
2226                        break;
2227                }
2228                result.append(localized ? symbols.getPatternSeparator() :
2229                              PATTERN_SEPARATOR);
2230            } else appendAffix(result, negSuffixPattern, negativeSuffix, localized);
2231        }
2232        return result.toString();
2233    }
2234
2235    /**
2236     * Apply the given pattern to this Format object. A pattern is a
2237     * short-hand specification for the various formatting properties.
2238     * These properties can also be changed individually through the
2239     * various setter methods.
2240     * <p>
2241     * There is no limit to integer digits are set
2242     * by this routine, since that is the typical end-user desire;
2243     * use setMaximumInteger if you want to set a real value.
2244     * For negative numbers, use a second pattern, separated by a semicolon
2245     * <P>Example <code>"#,#00.0#"</code> -> 1,234.56
2246     * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
2247     * a maximum of 2 fraction digits.
2248     * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
2249     * parentheses.
2250     * <p>In negative patterns, the minimum and maximum counts are ignored;
2251     * these are presumed to be set in the positive pattern.
2252     *
2253     * @exception NullPointerException if <code>pattern</code> is null
2254     * @exception IllegalArgumentException if the given pattern is invalid.
2255     */

2256    public void applyPattern(String JavaDoc pattern) {
2257        applyPattern(pattern, false);
2258    }
2259
2260    /**
2261     * Apply the given pattern to this Format object. The pattern
2262     * is assumed to be in a localized notation. A pattern is a
2263     * short-hand specification for the various formatting properties.
2264     * These properties can also be changed individually through the
2265     * various setter methods.
2266     * <p>
2267     * There is no limit to integer digits are set
2268     * by this routine, since that is the typical end-user desire;
2269     * use setMaximumInteger if you want to set a real value.
2270     * For negative numbers, use a second pattern, separated by a semicolon
2271     * <P>Example <code>"#,#00.0#"</code> -> 1,234.56
2272     * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
2273     * a maximum of 2 fraction digits.
2274     * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
2275     * parentheses.
2276     * <p>In negative patterns, the minimum and maximum counts are ignored;
2277     * these are presumed to be set in the positive pattern.
2278     *
2279     * @exception NullPointerException if <code>pattern</code> is null
2280     * @exception IllegalArgumentException if the given pattern is invalid.
2281     */

2282    public void applyLocalizedPattern(String JavaDoc pattern) {
2283        applyPattern(pattern, true);
2284    }
2285
2286    /**
2287     * Does the real work of applying a pattern.
2288     */

2289    private void applyPattern(String JavaDoc pattern, boolean localized) {
2290        char zeroDigit = PATTERN_ZERO_DIGIT;
2291        char groupingSeparator = PATTERN_GROUPING_SEPARATOR;
2292        char decimalSeparator = PATTERN_DECIMAL_SEPARATOR;
2293        char percent = PATTERN_PERCENT;
2294        char perMill = PATTERN_PER_MILLE;
2295        char digit = PATTERN_DIGIT;
2296        char separator = PATTERN_SEPARATOR;
2297        char exponent = PATTERN_EXPONENT;
2298        char minus = PATTERN_MINUS;
2299        if (localized) {
2300            zeroDigit = symbols.getZeroDigit();
2301            groupingSeparator = symbols.getGroupingSeparator();
2302            decimalSeparator = symbols.getDecimalSeparator();
2303            percent = symbols.getPercent();
2304            perMill = symbols.getPerMill();
2305            digit = symbols.getDigit();
2306            separator = symbols.getPatternSeparator();
2307            exponent = symbols.getExponentialSymbol();
2308            minus = symbols.getMinusSign();
2309        }
2310        boolean gotNegative = false;
2311        decimalSeparatorAlwaysShown = false;
2312        isCurrencyFormat = false;
2313        useExponentialNotation = false;
2314
2315        // Two variables are used to record the subrange of the pattern
2316
// occupied by phase 1. This is used during the processing of the
2317
// second pattern (the one representing negative numbers) to ensure
2318
// that no deviation exists in phase 1 between the two patterns.
2319
int phaseOneStart = 0;
2320        int phaseOneLength = 0;
2321
2322        int start = 0;
2323        for (int j = 1; j >= 0 && start < pattern.length(); --j) {
2324            boolean inQuote = false;
2325            StringBuffer JavaDoc prefix = new StringBuffer JavaDoc();
2326            StringBuffer JavaDoc suffix = new StringBuffer JavaDoc();
2327            int decimalPos = -1;
2328            int multiplier = 1;
2329            int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0;
2330            byte groupingCount = -1;
2331
2332            // The phase ranges from 0 to 2. Phase 0 is the prefix. Phase 1 is
2333
// the section of the pattern with digits, decimal separator,
2334
// grouping characters. Phase 2 is the suffix. In phases 0 and 2,
2335
// percent, per mille, and currency symbols are recognized and
2336
// translated. The separation of the characters into phases is
2337
// strictly enforced; if phase 1 characters are to appear in the
2338
// suffix, for example, they must be quoted.
2339
int phase = 0;
2340
2341            // The affix is either the prefix or the suffix.
2342
StringBuffer JavaDoc affix = prefix;
2343
2344            for (int pos = start; pos < pattern.length(); ++pos) {
2345                char ch = pattern.charAt(pos);
2346                switch (phase) {
2347                case 0:
2348                case 2:
2349                    // Process the prefix / suffix characters
2350
if (inQuote) {
2351                        // A quote within quotes indicates either the closing
2352
// quote or two quotes, which is a quote literal. That
2353
// is, we have the second quote in 'do' or 'don''t'.
2354
if (ch == QUOTE) {
2355                            if ((pos+1) < pattern.length() &&
2356                                pattern.charAt(pos+1) == QUOTE) {
2357                                ++pos;
2358                                affix.append("''"); // 'don''t'
2359
} else {
2360                                inQuote = false; // 'do'
2361
}
2362                            continue;
2363                        }
2364                    } else {
2365                        // Process unquoted characters seen in prefix or suffix
2366
// phase.
2367
if (ch == digit ||
2368                            ch == zeroDigit ||
2369                            ch == groupingSeparator ||
2370                            ch == decimalSeparator) {
2371                            phase = 1;
2372                            if (j == 1) {
2373                                phaseOneStart = pos;
2374                            }
2375                            --pos; // Reprocess this character
2376
continue;
2377                        } else if (ch == CURRENCY_SIGN) {
2378                            // Use lookahead to determine if the currency sign
2379
// is doubled or not.
2380
boolean doubled = (pos + 1) < pattern.length() &&
2381                                pattern.charAt(pos + 1) == CURRENCY_SIGN;
2382                            if (doubled) { // Skip over the doubled character
2383
++pos;
2384                            }
2385                            isCurrencyFormat = true;
2386                            affix.append(doubled ? "'\u00A4\u00A4" : "'\u00A4");
2387                            continue;
2388                        } else if (ch == QUOTE) {
2389                            // A quote outside quotes indicates either the
2390
// opening quote or two quotes, which is a quote
2391
// literal. That is, we have the first quote in 'do'
2392
// or o''clock.
2393
if (ch == QUOTE) {
2394                                if ((pos+1) < pattern.length() &&
2395                                    pattern.charAt(pos+1) == QUOTE) {
2396                                    ++pos;
2397                                    affix.append("''"); // o''clock
2398
} else {
2399                                    inQuote = true; // 'do'
2400
}
2401                                continue;
2402                            }
2403                        } else if (ch == separator) {
2404                            // Don't allow separators before we see digit
2405
// characters of phase 1, and don't allow separators
2406
// in the second pattern (j == 0).
2407
if (phase == 0 || j == 0) {
2408                                throw new IllegalArgumentException JavaDoc("Unquoted special character '" +
2409                                    ch + "' in pattern \"" + pattern + '"');
2410                            }
2411                            start = pos + 1;
2412                            pos = pattern.length();
2413                            continue;
2414                        }
2415
2416                        // Next handle characters which are appended directly.
2417
else if (ch == percent) {
2418                            if (multiplier != 1) {
2419                                throw new IllegalArgumentException JavaDoc("Too many percent/per mille characters in pattern \"" +
2420                                    pattern + '"');
2421                            }
2422                            multiplier = 100;
2423                            affix.append("'%");
2424                            continue;
2425                        } else if (ch == perMill) {
2426                            if (multiplier != 1) {
2427                                throw new IllegalArgumentException JavaDoc("Too many percent/per mille characters in pattern \"" +
2428                                    pattern + '"');
2429                            }
2430                            multiplier = 1000;
2431                            affix.append("'\u2030");
2432                            continue;
2433                        } else if (ch == minus) {
2434                            affix.append("'-");
2435                            continue;
2436                        }
2437                    }
2438                    // Note that if we are within quotes, or if this is an
2439
// unquoted, non-special character, then we usually fall
2440
// through to here.
2441
affix.append(ch);
2442                    break;
2443
2444                case 1:
2445                    // Phase one must be identical in the two sub-patterns. We
2446
// enforce this by doing a direct comparison. While
2447
// processing the first sub-pattern, we just record its
2448
// length. While processing the second, we compare
2449
// characters.
2450
if (j == 1) {
2451                        ++phaseOneLength;
2452                    } else {
2453                        if (--phaseOneLength == 0) {
2454                            phase = 2;
2455                            affix = suffix;
2456                        }
2457                        continue;
2458                    }
2459
2460                    // Process the digits, decimal, and grouping characters. We
2461
// record five pieces of information. We expect the digits
2462
// to occur in the pattern ####0000.####, and we record the
2463
// number of left digits, zero (central) digits, and right
2464
// digits. The position of the last grouping character is
2465
// recorded (should be somewhere within the first two blocks
2466
// of characters), as is the position of the decimal point,
2467
// if any (should be in the zero digits). If there is no
2468
// decimal point, then there should be no right digits.
2469
if (ch == digit) {
2470                        if (zeroDigitCount > 0) {
2471                            ++digitRightCount;
2472                        } else {
2473                            ++digitLeftCount;
2474                        }
2475                        if (groupingCount >= 0 && decimalPos < 0) {
2476                            ++groupingCount;
2477                        }
2478                    } else if (ch == zeroDigit) {
2479                        if (digitRightCount > 0) {
2480                            throw new IllegalArgumentException JavaDoc("Unexpected '0' in pattern \"" +
2481                                pattern + '"');
2482                        }
2483                        ++zeroDigitCount;
2484                        if (groupingCount >= 0 && decimalPos < 0) {
2485                            ++groupingCount;
2486                        }
2487                    } else if (ch == groupingSeparator) {
2488                        groupingCount = 0;
2489                    } else if (ch == decimalSeparator) {
2490                        if (decimalPos >= 0) {
2491                            throw new IllegalArgumentException JavaDoc("Multiple decimal separators in pattern \"" +
2492                                pattern + '"');
2493                        }
2494                        decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
2495                    } else if (ch == exponent) {
2496                        if (useExponentialNotation) {
2497                            throw new IllegalArgumentException JavaDoc("Multiple exponential " +
2498                                "symbols in pattern \"" + pattern + '"');
2499                        }
2500                        useExponentialNotation = true;
2501                        minExponentDigits = 0;
2502
2503                        // Use lookahead to parse out the exponential part
2504
// of the pattern, then jump into phase 2.
2505
while (++pos < pattern.length() &&
2506                               pattern.charAt(pos) == zeroDigit) {
2507                            ++minExponentDigits;
2508                            ++phaseOneLength;
2509                        }
2510
2511                        if ((digitLeftCount + zeroDigitCount) < 1 ||
2512                            minExponentDigits < 1) {
2513                            throw new IllegalArgumentException JavaDoc("Malformed exponential " +
2514                                "pattern \"" + pattern + '"');
2515                        }
2516
2517                        // Transition to phase 2
2518
phase = 2;
2519                        affix = suffix;
2520                        --pos;
2521                        continue;
2522                    } else {
2523                        phase = 2;
2524                        affix = suffix;
2525                        --pos;
2526                        --phaseOneLength;
2527                        continue;
2528                    }
2529                    break;
2530                }
2531            }
2532
2533            // Handle patterns with no '0' pattern character. These patterns
2534
// are legal, but must be interpreted. "##.###" -> "#0.###".
2535
// ".###" -> ".0##".
2536
/* We allow patterns of the form "####" to produce a zeroDigitCount
2537             * of zero (got that?); although this seems like it might make it
2538             * possible for format() to produce empty strings, format() checks
2539             * for this condition and outputs a zero digit in this situation.
2540             * Having a zeroDigitCount of zero yields a minimum integer digits
2541             * of zero, which allows proper round-trip patterns. That is, we
2542             * don't want "#" to become "#0" when toPattern() is called (even
2543             * though that's what it really is, semantically).
2544             */

2545            if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {
2546                // Handle "###.###" and "###." and ".###"
2547
int n = decimalPos;
2548                if (n == 0) { // Handle ".###"
2549
++n;
2550                }
2551                digitRightCount = digitLeftCount - n;
2552                digitLeftCount = n - 1;
2553                zeroDigitCount = 1;
2554            }
2555
2556            // Do syntax checking on the digits.
2557
if ((decimalPos < 0 && digitRightCount > 0) ||
2558                (decimalPos >= 0 && (decimalPos < digitLeftCount ||
2559                 decimalPos > (digitLeftCount + zeroDigitCount))) ||
2560                 groupingCount == 0 || inQuote) {
2561                throw new IllegalArgumentException JavaDoc("Malformed pattern \"" +
2562                    pattern + '"');
2563            }
2564
2565            if (j == 1) {
2566                posPrefixPattern = prefix.toString();
2567                posSuffixPattern = suffix.toString();
2568                negPrefixPattern = posPrefixPattern; // assume these for now
2569
negSuffixPattern = posSuffixPattern;
2570                int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
2571                /* The effectiveDecimalPos is the position the decimal is at or
2572                 * would be at if there is no decimal. Note that if decimalPos<0,
2573                 * then digitTotalCount == digitLeftCount + zeroDigitCount.
2574                 */

2575                int effectiveDecimalPos = decimalPos >= 0 ?
2576                    decimalPos : digitTotalCount;
2577                setMinimumIntegerDigits(effectiveDecimalPos - digitLeftCount);
2578                setMaximumIntegerDigits(useExponentialNotation ?
2579                    digitLeftCount + getMinimumIntegerDigits() :
2580                    MAXIMUM_INTEGER_DIGITS);
2581                setMaximumFractionDigits(decimalPos >= 0 ?
2582                    (digitTotalCount - decimalPos) : 0);
2583                setMinimumFractionDigits(decimalPos >= 0 ?
2584                    (digitLeftCount + zeroDigitCount - decimalPos) : 0);
2585                setGroupingUsed(groupingCount > 0);
2586                this.groupingSize = (groupingCount > 0) ? groupingCount : 0;
2587                this.multiplier = multiplier;
2588                setDecimalSeparatorAlwaysShown(decimalPos == 0 ||
2589                    decimalPos == digitTotalCount);
2590            } else {
2591                negPrefixPattern = prefix.toString();
2592                negSuffixPattern = suffix.toString();
2593                gotNegative = true;
2594            }
2595        }
2596
2597        if (pattern.length() == 0) {
2598            posPrefixPattern = posSuffixPattern = "";
2599            setMinimumIntegerDigits(0);
2600            setMaximumIntegerDigits(MAXIMUM_INTEGER_DIGITS);
2601            setMinimumFractionDigits(0);
2602            setMaximumFractionDigits(MAXIMUM_FRACTION_DIGITS);
2603        }
2604
2605        // If there was no negative pattern, or if the negative pattern is
2606
// identical to the positive pattern, then prepend the minus sign to
2607
// the positive pattern to form the negative pattern.
2608
if (!gotNegative ||
2609            (negPrefixPattern.equals(posPrefixPattern)
2610             && negSuffixPattern.equals(posSuffixPattern))) {
2611            negSuffixPattern = posSuffixPattern;
2612            negPrefixPattern = "'-" + posPrefixPattern;
2613        }
2614
2615        expandAffixes();
2616    }
2617
2618    /**
2619     * Sets the maximum number of digits allowed in the integer portion of a
2620     * number.
2621     * For formatting numbers other than <code>BigInteger</code> and
2622     * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2623     * 309 is used. Negative input values are replaced with 0.
2624     * @see NumberFormat#setMaximumIntegerDigits
2625     */

2626    public void setMaximumIntegerDigits(int newValue) {
2627        maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
2628        super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2629            DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
2630        if (minimumIntegerDigits > maximumIntegerDigits) {
2631            minimumIntegerDigits = maximumIntegerDigits;
2632            super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2633                DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
2634        }
2635    }
2636
2637    /**
2638     * Sets the minimum number of digits allowed in the integer portion of a
2639     * number.
2640     * For formatting numbers other than <code>BigInteger</code> and
2641     * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2642     * 309 is used. Negative input values are replaced with 0.
2643     * @see NumberFormat#setMinimumIntegerDigits
2644     */

2645    public void setMinimumIntegerDigits(int newValue) {
2646        minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
2647        super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2648            DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
2649        if (minimumIntegerDigits > maximumIntegerDigits) {
2650            maximumIntegerDigits = minimumIntegerDigits;
2651            super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2652                DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
2653        }
2654    }
2655
2656    /**
2657     * Sets the maximum number of digits allowed in the fraction portion of a
2658     * number.
2659     * For formatting numbers other than <code>BigInteger</code> and
2660     * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2661     * 340 is used. Negative input values are replaced with 0.
2662     * @see NumberFormat#setMaximumFractionDigits
2663     */

2664    public void setMaximumFractionDigits(int newValue) {
2665        maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
2666        super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2667            DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
2668        if (minimumFractionDigits > maximumFractionDigits) {
2669            minimumFractionDigits = maximumFractionDigits;
2670            super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2671                DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
2672        }
2673    }
2674
2675    /**
2676     * Sets the minimum number of digits allowed in the fraction portion of a
2677     * number.
2678     * For formatting numbers other than <code>BigInteger</code> and
2679     * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2680     * 340 is used. Negative input values are replaced with 0.
2681     * @see NumberFormat#setMinimumFractionDigits
2682     */

2683    public void setMinimumFractionDigits(int newValue) {
2684        minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
2685        super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2686            DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
2687        if (minimumFractionDigits > maximumFractionDigits) {
2688            maximumFractionDigits = minimumFractionDigits;
2689            super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2690                DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
2691        }
2692    }
2693
2694    /**
2695     * Gets the maximum number of digits allowed in the integer portion of a
2696     * number.
2697     * For formatting numbers other than <code>BigInteger</code> and
2698     * <code>BigDecimal</code> objects, the lower of the return value and
2699     * 309 is used.
2700     * @see #setMaximumIntegerDigits
2701     */

2702    public int getMaximumIntegerDigits() {
2703        return maximumIntegerDigits;
2704    }
2705
2706    /**
2707     * Gets the minimum number of digits allowed in the integer portion of a
2708     * number.
2709     * For formatting numbers other than <code>BigInteger</code> and
2710     * <code>BigDecimal</code> objects, the lower of the return value and
2711     * 309 is used.
2712     * @see #setMinimumIntegerDigits
2713     */

2714    public int getMinimumIntegerDigits() {
2715        return minimumIntegerDigits;
2716    }
2717
2718    /**
2719     * Gets the maximum number of digits allowed in the fraction portion of a
2720     * number.
2721     * For formatting numbers other than <code>BigInteger</code> and
2722     * <code>BigDecimal</code> objects, the lower of the return value and
2723     * 340 is used.
2724     * @see #setMaximumFractionDigits
2725     */

2726    public int getMaximumFractionDigits() {
2727        return maximumFractionDigits;
2728    }
2729
2730    /**
2731     * Gets the minimum number of digits allowed in the fraction portion of a
2732     * number.
2733     * For formatting numbers other than <code>BigInteger</code> and
2734     * <code>BigDecimal</code> objects, the lower of the return value and
2735     * 340 is used.
2736     * @see #setMinimumFractionDigits
2737     */

2738    public int getMinimumFractionDigits() {
2739        return minimumFractionDigits;
2740    }
2741
2742    /**
2743     * Gets the currency used by this decimal format when formatting
2744     * currency values.
2745     * The currency is obtained by calling
2746     * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency}
2747     * on this number format's symbols.
2748     *
2749     * @return the currency used by this decimal format, or <code>null</code>
2750     * @since 1.4
2751     */

2752    public Currency JavaDoc getCurrency() {
2753        return symbols.getCurrency();
2754    }
2755    
2756    /**
2757     * Sets the currency used by this number format when formatting
2758     * currency values. This does not update the minimum or maximum
2759     * number of fraction digits used by the number format.
2760     * The currency is set by calling
2761     * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency}
2762     * on this number format's symbols.
2763     *
2764     * @param currency the new currency to be used by this decimal format
2765     * @exception NullPointerException if <code>currency</code> is null
2766     * @since 1.4
2767     */

2768    public void setCurrency(Currency JavaDoc currency) {
2769        if (currency != symbols.getCurrency()) {
2770            symbols.setCurrency(currency);
2771            if (isCurrencyFormat) {
2772                expandAffixes();
2773            }
2774        }
2775    }
2776    
2777    /**
2778     * Adjusts the minimum and maximum fraction digits to values that
2779     * are reasonable for the currency's default fraction digits.
2780     */

2781    void adjustForCurrencyDefaultFractionDigits() {
2782        Currency JavaDoc currency = symbols.getCurrency();
2783        if (currency == null) {
2784            try {
2785                currency = Currency.getInstance(symbols.getInternationalCurrencySymbol());
2786            } catch (IllegalArgumentException JavaDoc e) {
2787            }
2788        }
2789        if (currency != null) {
2790            int digits = currency.getDefaultFractionDigits();
2791            if (digits != -1) {
2792                int oldMinDigits = getMinimumFractionDigits();
2793                // Common patterns are "#.##", "#.00", "#".
2794
// Try to adjust all of them in a reasonable way.
2795
if (oldMinDigits == getMaximumFractionDigits()) {
2796                    setMinimumFractionDigits(digits);
2797                    setMaximumFractionDigits(digits);
2798                } else {
2799                    setMinimumFractionDigits(Math.min(digits, oldMinDigits));
2800                    setMaximumFractionDigits(digits);
2801                }
2802            }
2803        }
2804    }
2805
2806    /**
2807     * Reads the default serializable fields from the stream and performs
2808     * validations and adjustments for older serialized versions. The
2809     * validations and adjustments are:
2810     * <ol>
2811     * <li>
2812     * Verify that the superclass's digit count fields correctly reflect
2813     * the limits imposed on formatting numbers other than
2814     * <code>BigInteger</code> and <code>BigDecimal</code> objects. These
2815     * limits are stored in the superclass for serialization compatibility
2816     * with older versions, while the limits for <code>BigInteger</code> and
2817     * <code>BigDecimal</code> objects are kept in this class.
2818     * If, in the superclass, the minimum or maximum integer digit count is
2819     * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or
2820     * maximum fraction digit count is larger than
2821     * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid
2822     * and this method throws an <code>InvalidObjectException</code>.
2823     * <li>
2824     * If <code>serialVersionOnStream</code> is less than 3, then call
2825     * the setters for the minimum and maximum integer and fraction digits with
2826     * the values of the corresponding superclass getters to initialize the
2827     * fields in this class. The fields in this class are new with version 3.
2828     * <li>
2829     * If <code>serialVersionOnStream</code> is less than 1, indicating that
2830     * the stream was written by JDK 1.1, initialize
2831     * <code>useExponentialNotation</code>
2832     * to false, since it was not present in JDK 1.1.
2833     * <li>
2834     * Set <code>serialVersionOnStream</code> to the maximum allowed value so
2835     * that default serialization will work properly if this object is streamed
2836     * out again.
2837     * </ol>
2838     *
2839     * <p>Stream versions older than 2 will not have the affix pattern variables
2840     * <code>posPrefixPattern</code> etc. As a result, they will be initialized
2841     * to <code>null</code>, which means the affix strings will be taken as
2842     * literal values. This is exactly what we want, since that corresponds to
2843     * the pre-version-2 behavior.
2844     */

2845    private void readObject(ObjectInputStream JavaDoc stream)
2846         throws IOException JavaDoc, ClassNotFoundException JavaDoc
2847    {
2848        stream.defaultReadObject();
2849
2850        // We only need to check the maximum counts because NumberFormat
2851
// .readObject has already ensured that the maximum is greater than the
2852
// minimum count.
2853
if (super.getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS ||
2854            super.getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {
2855            throw new InvalidObjectException JavaDoc("Digit count out of range");
2856        }
2857        if (serialVersionOnStream < 3) {
2858            setMaximumIntegerDigits(super.getMaximumIntegerDigits());
2859            setMinimumIntegerDigits(super.getMinimumIntegerDigits());
2860            setMaximumFractionDigits(super.getMaximumFractionDigits());
2861            setMinimumFractionDigits(super.getMinimumFractionDigits());
2862        }
2863        if (serialVersionOnStream < 1) {
2864            // Didn't have exponential fields
2865
useExponentialNotation = false;
2866        }
2867        serialVersionOnStream = currentSerialVersion;
2868        digitList = new DigitList JavaDoc();
2869    }
2870
2871    //----------------------------------------------------------------------
2872
// INSTANCE VARIABLES
2873
//----------------------------------------------------------------------
2874

2875    private transient DigitList JavaDoc digitList = new DigitList JavaDoc();
2876
2877    /**
2878     * The symbol used as a prefix when formatting positive numbers, e.g. "+".
2879     *
2880     * @serial
2881     * @see #getPositivePrefix
2882     */

2883    private String JavaDoc positivePrefix = "";
2884
2885    /**
2886     * The symbol used as a suffix when formatting positive numbers.
2887     * This is often an empty string.
2888     *
2889     * @serial
2890     * @see #getPositiveSuffix
2891     */

2892    private String JavaDoc positiveSuffix = "";
2893
2894    /**
2895     * The symbol used as a prefix when formatting negative numbers, e.g. "-".
2896     *
2897     * @serial
2898     * @see #getNegativePrefix
2899     */

2900    private String JavaDoc negativePrefix = "-";
2901
2902    /**
2903     * The symbol used as a suffix when formatting negative numbers.
2904     * This is often an empty string.
2905     *
2906     * @serial
2907     * @see #getNegativeSuffix
2908     */

2909    private String JavaDoc negativeSuffix = "";
2910
2911    /**
2912     * The prefix pattern for non-negative numbers. This variable corresponds
2913     * to <code>positivePrefix</code>.
2914     *
2915     * <p>This pattern is expanded by the method <code>expandAffix()</code> to
2916     * <code>positivePrefix</code> to update the latter to reflect changes in
2917     * <code>symbols</code>. If this variable is <code>null</code> then
2918     * <code>positivePrefix</code> is taken as a literal value that does not
2919     * change when <code>symbols</code> changes. This variable is always
2920     * <code>null</code> for <code>DecimalFormat</code> objects older than
2921     * stream version 2 restored from stream.
2922     *
2923     * @serial
2924     * @since 1.3
2925     */

2926    private String JavaDoc posPrefixPattern;
2927
2928    /**
2929     * The suffix pattern for non-negative numbers. This variable corresponds
2930     * to <code>positiveSuffix</code>. This variable is analogous to
2931     * <code>posPrefixPattern</code>; see that variable for further
2932     * documentation.
2933     *
2934     * @serial
2935     * @since 1.3
2936     */

2937    private String JavaDoc posSuffixPattern;
2938
2939    /**
2940     * The prefix pattern for negative numbers. This variable corresponds
2941     * to <code>negativePrefix</code>. This variable is analogous to
2942     * <code>posPrefixPattern</code>; see that variable for further
2943     * documentation.
2944     *
2945     * @serial
2946     * @since 1.3
2947     */

2948    private String JavaDoc negPrefixPattern;
2949
2950    /**
2951     * The suffix pattern for negative numbers. This variable corresponds
2952     * to <code>negativeSuffix</code>. This variable is analogous to
2953     * <code>posPrefixPattern</code>; see that variable for further
2954     * documentation.
2955     *
2956     * @serial
2957     * @since 1.3
2958     */

2959    private String JavaDoc negSuffixPattern;
2960
2961    /**
2962     * The multiplier for use in percent, per mille, etc.
2963     *
2964     * @serial
2965     * @see #getMultiplier
2966     */

2967    private int multiplier = 1;
2968    
2969    /**
2970     * The number of digits between grouping separators in the integer
2971     * portion of a number. Must be greater than 0 if
2972     * <code>NumberFormat.groupingUsed</code> is true.
2973     *
2974     * @serial
2975     * @see #getGroupingSize
2976     * @see java.text.NumberFormat#isGroupingUsed
2977     */

2978    private byte groupingSize = 3; // invariant, > 0 if useThousands
2979

2980    /**
2981     * If true, forces the decimal separator to always appear in a formatted
2982     * number, even if the fractional part of the number is zero.
2983     *
2984     * @serial
2985     * @see #isDecimalSeparatorAlwaysShown
2986     */

2987    private boolean decimalSeparatorAlwaysShown = false;
2988
2989    /**
2990     * If true, parse returns BigDecimal wherever possible.
2991     *
2992     * @serial
2993     * @see #isParseBigDecimal
2994     * @since 1.5
2995     */

2996    private boolean parseBigDecimal = false;
2997
2998    
2999    /**
3000     * True if this object represents a currency format. This determines
3001     * whether the monetary decimal separator is used instead of the normal one.
3002     */

3003    private transient boolean isCurrencyFormat = false;
3004    
3005    /**
3006     * The <code>DecimalFormatSymbols</code> object used by this format.
3007     * It contains the symbols used to format numbers, e.g. the grouping separator,
3008     * decimal separator, and so on.
3009     *
3010     * @serial
3011     * @see #setDecimalFormatSymbols
3012     * @see java.text.DecimalFormatSymbols
3013     */

3014    private DecimalFormatSymbols JavaDoc symbols = null; // LIU new DecimalFormatSymbols();
3015

3016    /**
3017     * True to force the use of exponential (i.e. scientific) notation when formatting
3018     * numbers.
3019     *
3020     * @serial
3021     * @since 1.2
3022     */

3023    private boolean useExponentialNotation; // Newly persistent in the Java 2 platform
3024

3025    /**
3026     * FieldPositions describing the positive prefix String. This is
3027     * lazily created. Use <code>getPositivePrefixFieldPositions</code>
3028     * when needed.
3029     */

3030    private transient FieldPosition JavaDoc[] positivePrefixFieldPositions;
3031
3032    /**
3033     * FieldPositions describing the positive suffix String. This is
3034     * lazily created. Use <code>getPositiveSuffixFieldPositions</code>
3035     * when needed.
3036     */

3037    private transient FieldPosition JavaDoc[] positiveSuffixFieldPositions;
3038
3039    /**
3040     * FieldPositions describing the negative prefix String. This is
3041     * lazily created. Use <code>getNegativePrefixFieldPositions</code>
3042     * when needed.
3043     */

3044    private transient FieldPosition JavaDoc[] negativePrefixFieldPositions;
3045
3046    /**
3047     * FieldPositions describing the negative suffix String. This is
3048     * lazily created. Use <code>getNegativeSuffixFieldPositions</code>
3049     * when needed.
3050     */

3051    private transient FieldPosition JavaDoc[] negativeSuffixFieldPositions;
3052
3053    /**
3054     * The minimum number of digits used to display the exponent when a number is
3055     * formatted in exponential notation. This field is ignored if
3056     * <code>useExponentialNotation</code> is not true.
3057     *
3058     * @serial
3059     * @since 1.2
3060     */

3061    private byte minExponentDigits; // Newly persistent in the Java 2 platform
3062

3063    /**
3064     * The maximum number of digits allowed in the integer portion of a
3065     * <code>BigInteger</code> or <code>BigDecimal</code> number.
3066     * <code>maximumIntegerDigits</code> must be greater than or equal to
3067     * <code>minimumIntegerDigits</code>.
3068     *
3069     * @serial
3070     * @see #getMaximumIntegerDigits
3071     * @since 1.5
3072     */

3073    private int maximumIntegerDigits = super.getMaximumIntegerDigits();
3074
3075    /**
3076     * The minimum number of digits allowed in the integer portion of a
3077     * <code>BigInteger</code> or <code>BigDecimal</code> number.
3078     * <code>minimumIntegerDigits</code> must be less than or equal to
3079     * <code>maximumIntegerDigits</code>.
3080     *
3081     * @serial
3082     * @see #getMinimumIntegerDigits
3083     * @since 1.5
3084     */

3085    private int minimumIntegerDigits = super.getMinimumIntegerDigits();
3086
3087    /**
3088     * The maximum number of digits allowed in the fractional portion of a
3089     * <code>BigInteger</code> or <code>BigDecimal</code> number.
3090     * <code>maximumFractionDigits</code> must be greater than or equal to
3091     * <code>minimumFractionDigits</code>.
3092     *
3093     * @serial
3094     * @see #getMaximumFractionDigits
3095     * @since 1.5
3096     */

3097    private int maximumFractionDigits = super.getMaximumFractionDigits();
3098
3099    /**
3100     * The minimum number of digits allowed in the fractional portion of a
3101     * <code>BigInteger</code> or <code>BigDecimal</code> number.
3102     * <code>minimumFractionDigits</code> must be less than or equal to
3103     * <code>maximumFractionDigits</code>.
3104     *
3105     * @serial
3106     * @see #getMinimumFractionDigits
3107     * @since 1.5
3108     */

3109    private int minimumFractionDigits = super.getMinimumFractionDigits();
3110
3111    //----------------------------------------------------------------------
3112

3113    static final int currentSerialVersion = 3;
3114
3115    /**
3116     * The internal serial version which says which version was written.
3117     * Possible values are:
3118     * <ul>
3119     * <li><b>0</b> (default): versions before the Java 2 platform v1.2
3120     * <li><b>1</b>: version for 1.2, which includes the two new fields
3121     * <code>useExponentialNotation</code> and
3122     * <code>minExponentDigits</code>.
3123     * <li><b>2</b>: version for 1.3 and later, which adds four new fields:
3124     * <code>posPrefixPattern</code>, <code>posSuffixPattern</code>,
3125     * <code>negPrefixPattern</code>, and <code>negSuffixPattern</code>.
3126     * <li><b>3</b>: version for 5 and later, which adds five new fields:
3127     * <code>maximumIntegerDigits</code>,
3128     * <code>minimumIntegerDigits</code>,
3129     * <code>maximumFractionDigits</code>,
3130     * <code>minimumFractionDigits</code>, and
3131     * <code>parseBigDecimal</code>.
3132     * </ul>
3133     * @since 1.2
3134     * @serial
3135     */

3136    private int serialVersionOnStream = currentSerialVersion;
3137
3138    //----------------------------------------------------------------------
3139
// CONSTANTS
3140
//----------------------------------------------------------------------
3141

3142    // Constants for characters used in programmatic (unlocalized) patterns.
3143
private static final char PATTERN_ZERO_DIGIT = '0';
3144    private static final char PATTERN_GROUPING_SEPARATOR = ',';
3145    private static final char PATTERN_DECIMAL_SEPARATOR = '.';
3146    private static final char PATTERN_PER_MILLE = '\u2030';
3147    private static final char PATTERN_PERCENT = '%';
3148    private static final char PATTERN_DIGIT = '#';
3149    private static final char PATTERN_SEPARATOR = ';';
3150    private static final char PATTERN_EXPONENT = 'E';
3151    private static final char PATTERN_MINUS = '-';
3152
3153    /**
3154     * The CURRENCY_SIGN is the standard Unicode symbol for currency. It
3155     * is used in patterns and substituted with either the currency symbol,
3156     * or if it is doubled, with the international currency symbol. If the
3157     * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
3158     * replaced with the monetary decimal separator.
3159     *
3160     * The CURRENCY_SIGN is not localized.
3161     */

3162    private static final char CURRENCY_SIGN = '\u00A4';
3163
3164    private static final char QUOTE = '\'';
3165
3166    private static FieldPosition JavaDoc[] EmptyFieldPositionArray = new FieldPosition JavaDoc[0];
3167
3168    // Upper limit on integer and fraction digits for a Java double
3169
static final int DOUBLE_INTEGER_DIGITS = 309;
3170    static final int DOUBLE_FRACTION_DIGITS = 340;
3171
3172    // Upper limit on integer and fraction digits for BigDecimal and BigInteger
3173
static final int MAXIMUM_INTEGER_DIGITS = Integer.MAX_VALUE;
3174    static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE;
3175
3176    // Proclaim JDK 1.1 serial compatibility.
3177
static final long serialVersionUID = 864413376551465018L;
3178
3179    /**
3180     * Cache to hold the NumberPattern of a Locale.
3181     */

3182    private static Hashtable JavaDoc cachedLocaleData = new Hashtable JavaDoc(3);
3183}
3184
Popular Tags