History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/text/DecimalFormat.java (1 of 18352 files). Show all

Unified · Split

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