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.
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.
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).
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.
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
27 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
28 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
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.
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;
57 * <code>DecimalFormat</code> is a concrete subclass of
58 * <code>NumberFormat</code> that formats decimal numbers. It has a variety of
59 * features designed to make it possible to parse and format numbers in any
60 * locale, including support for Western, Arabic, and Indic digits. It also
61 * supports different kinds of numbers, including integers (123), fixed-point
62 * numbers (123.4), scientific notation (1.23E4), percentages (12%), and
63 * currency amounts ($123). All of these can be localized.
65 * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the
66 * default locale, call one of <code>NumberFormat</code>'s factory methods, such
67 * as <code>getInstance()</code>. In general, do not call the
68 * <code>DecimalFormat</code> constructors directly, since the
69 * <code>NumberFormat</code> factory methods may return subclasses other than
70 * <code>DecimalFormat</code>. If you need to customize the format object, do
71 * something like this:
74 * NumberFormat f = NumberFormat.getInstance(loc);
75 * if (f instanceof DecimalFormat) {
76 * ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
80 * <p>A <code>DecimalFormat</code> comprises a <em>pattern</em> and a set of
81 * <em>symbols</em>. The pattern may be set directly using
82 * <code>applyPattern()</code>, or indirectly using the API methods. The
83 * symbols are stored in a <code>DecimalFormatSymbols</code> object. When using
84 * the <code>NumberFormat</code> factory methods, the pattern and symbols are
85 * read from localized <code>ResourceBundle</code>s.
89 * <code>DecimalFormat</code> patterns have the following syntax:
92 * <i>PositivePattern</i>
93 * <i>PositivePattern</i> ; <i>NegativePattern</i>
94 * <i>PositivePattern:</i>
95 * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
96 * <i>NegativePattern:</i>
97 * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
99 * any Unicode characters except \uFFFE, \uFFFF, and special characters
101 * any Unicode characters except \uFFFE, \uFFFF, and special characters
103 * <i>Integer</i> <i>Exponent<sub>opt</sub></i>
104 * <i>Integer</i> . <i>Fraction</i> <i>Exponent<sub>opt</sub></i>
106 * <i>MinimumInteger</i>
110 * <i>MinimumInteger:</i>
112 * 0 <i>MinimumInteger</i>
113 * 0 , <i>MinimumInteger</i>
115 * <i>MinimumFraction<sub>opt</sub></i> <i>OptionalFraction<sub>opt</sub></i>
116 * <i>MinimumFraction:</i>
117 * 0 <i>MinimumFraction<sub>opt</sub></i>
118 * <i>OptionalFraction:</i>
119 * # <i>OptionalFraction<sub>opt</sub></i>
121 * E <i>MinimumExponent</i>
122 * <i>MinimumExponent:</i>
123 * 0 <i>MinimumExponent<sub>opt</sub></i>
124 * </pre></blockquote>
126 * <p>A <code>DecimalFormat</code> pattern contains a positive and negative
127 * subpattern, for example, <code>"#,##0.00;(#,##0.00)"</code>. Each
128 * subpattern has a prefix, numeric part, and suffix. The negative subpattern
129 * is optional; if absent, then the positive subpattern prefixed with the
130 * localized minus sign (<code>'-'</code> in most locales) is used as the
131 * negative subpattern. That is, <code>"0.00"</code> alone is equivalent to
132 * <code>"0.00;-0.00"</code>. If there is an explicit negative subpattern, it
133 * serves only to specify the negative prefix and suffix; the number of digits,
134 * minimal digits, and other characteristics are all the same as the positive
135 * pattern. That means that <code>"#,##0.0#;(#)"</code> produces precisely
136 * the same behavior as <code>"#,##0.0#;(#,##0.0#)"</code>.
138 * <p>The prefixes, suffixes, and various symbols used for infinity, digits,
139 * thousands separators, decimal separators, etc. may be set to arbitrary
140 * values, and they will appear properly during formatting. However, care must
141 * be taken that the symbols and strings do not conflict, or parsing will be
142 * unreliable. For example, either the positive and negative prefixes or the
143 * suffixes must be distinct for <code>DecimalFormat.parse()</code> to be able
144 * to distinguish positive from negative values. (If they are identical, then
145 * <code>DecimalFormat</code> will behave as if no negative subpattern was
146 * specified.) Another example is that the decimal separator and thousands
147 * separator should be distinct characters, or parsing will be impossible.
149 * <p>The grouping separator is commonly used for thousands, but in some
150 * countries it separates ten-thousands. The grouping size is a constant number
151 * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for
152 * 1,0000,0000. If you supply a pattern with multiple grouping characters, the
153 * interval between the last one and the end of the integer is the one that is
154 * used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> ==
155 * <code>"##,####,####"</code>.
157 * <h4>Special Pattern Characters</h4>
159 * <p>Many characters in a pattern are taken literally; they are matched during
160 * parsing and output unchanged during formatting. Special characters, on the
161 * other hand, stand for other characters, strings, or classes of characters.
162 * They must be quoted, unless noted otherwise, if they are to appear in the
163 * prefix or suffix as literals.
165 * <p>The characters listed here are used in non-localized patterns. Localized
166 * patterns use the corresponding characters taken from this formatter's
167 * <code>DecimalFormatSymbols</code> object instead, and these characters lose
168 * their special status. Two exceptions are the currency sign and quote, which
172 * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol,
173 * location, localized, and meaning.">
174 * <tr bgcolor="#ccccff">
175 * <th align=left>Symbol
176 * <th align=left>Location
177 * <th align=left>Localized?
178 * <th align=left>Meaning
184 * <tr valign=top bgcolor="#eeeeff">
188 * <td>Digit, zero shows as absent
193 * <td>Decimal separator or monetary decimal separator
194 * <tr valign=top bgcolor="#eeeeff">
203 * <td>Grouping separator
204 * <tr valign=top bgcolor="#eeeeff">
208 * <td>Separates mantissa and exponent in scientific notation.
209 * <em>Need not be quoted in prefix or suffix.</em>
212 * <td>Subpattern boundary
214 * <td>Separates positive and negative subpatterns
215 * <tr valign=top bgcolor="#eeeeff">
217 * <td>Prefix or suffix
219 * <td>Multiply by 100 and show as percentage
221 * <td><code>\u2030</code>
222 * <td>Prefix or suffix
224 * <td>Multiply by 1000 and show as per mille value
225 * <tr valign=top bgcolor="#eeeeff">
226 * <td><code>¤</code> (<code>\u00A4</code>)
227 * <td>Prefix or suffix
229 * <td>Currency sign, replaced by currency symbol. If
230 * doubled, replaced by international currency symbol.
231 * If present in a pattern, the monetary decimal separator
232 * is used instead of the decimal separator.
235 * <td>Prefix or suffix
237 * <td>Used to quote special characters in a prefix or suffix,
238 * for example, <code>"'#'#"</code> formats 123 to
239 * <code>"#123"</code>. To create a single quote
240 * itself, use two in a row: <code>"# o''clock"</code>.
244 * <h4>Scientific Notation</h4>
246 * <p>Numbers in scientific notation are expressed as the product of a mantissa
247 * and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3. The
248 * mantissa is often in the range 1.0 <= x < 10.0, but it need not be.
249 * <code>DecimalFormat</code> can be instructed to format and parse scientific
250 * notation <em>only via a pattern</em>; there is currently no factory method
251 * that creates a scientific notation format. In a pattern, the exponent
252 * character immediately followed by one or more digit characters indicates
253 * scientific notation. Example: <code>"0.###E0"</code> formats the number
254 * 1234 as <code>"1.234E3"</code>.
257 * <li>The number of digit characters after the exponent character gives the
258 * minimum exponent digit count. There is no maximum. Negative exponents are
259 * formatted using the localized minus sign, <em>not</em> the prefix and suffix
260 * from the pattern. This allows patterns such as <code>"0.###E0 m/s"</code>.
262 * <li>The minimum and maximum number of integer digits are interpreted
266 * <li>If the maximum number of integer digits is greater than their minimum number
267 * and greater than 1, it forces the exponent to be a multiple of the maximum
268 * number of integer digits, and the minimum number of integer digits to be
269 * interpreted as 1. The most common use of this is to generate
270 * <em>engineering notation</em>, in which the exponent is a multiple of three,
271 * e.g., <code>"##0.#####E0"</code>. Using this pattern, the number 12345
272 * formats to <code>"12.345E3"</code>, and 123456 formats to
273 * <code>"123.456E3"</code>.
275 * <li>Otherwise, the minimum number of integer digits is achieved by adjusting the
276 * exponent. Example: 0.00123 formatted with <code>"00.###E0"</code> yields
277 * <code>"12.3E-4"</code>.
280 * <li>The number of significant digits in the mantissa is the sum of the
281 * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is
282 * unaffected by the maximum integer digits. For example, 12345 formatted with
283 * <code>"##0.##E0"</code> is <code>"12.3E3"</code>. To show all digits, set
284 * the significant digits count to zero. The number of significant digits
285 * does not affect parsing.
287 * <li>Exponential patterns may not contain grouping separators.
292 * <code>DecimalFormat</code> provides rounding modes defined in
293 * {@link java.math.RoundingMode} for formatting. By default, it uses
294 * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
298 * For formatting, <code>DecimalFormat</code> uses the ten consecutive
299 * characters starting with the localized zero digit defined in the
300 * <code>DecimalFormatSymbols</code> object as digits. For parsing, these
301 * digits as well as all Unicode decimal digits, as defined by
302 * {@link Character#digit Character.digit}, are recognized.
304 * <h4>Special Values</h4>
306 * <p><code>NaN</code> is formatted as a string, which typically has a single character
307 * <code>\uFFFD</code>. This string is determined by the
308 * <code>DecimalFormatSymbols</code> object. This is the only value for which
309 * the prefixes and suffixes are not used.
311 * <p>Infinity is formatted as a string, which typically has a single character
312 * <code>\u221E</code>, with the positive or negative prefixes and suffixes
313 * applied. The infinity string is determined by the
314 * <code>DecimalFormatSymbols</code> object.
316 * <p>Negative zero (<code>"-0"</code>) parses to
318 * <li><code>BigDecimal(0)</code> if <code>isParseBigDecimal()</code> is
320 * <li><code>Long(0)</code> if <code>isParseBigDecimal()</code> is false
321 * and <code>isParseIntegerOnly()</code> is true,
322 * <li><code>Double(-0.0)</code> if both <code>isParseBigDecimal()</code>
323 * and <code>isParseIntegerOnly()</code> are false.
326 * <h4><a name="synchronization">Synchronization</a></h4>
329 * Decimal formats are generally not synchronized.
330 * It is recommended to create separate format instances for each thread.
331 * If multiple threads access a format concurrently, it must be synchronized
337 * <strong>// Print out a number using the localized number, integer, currency,
338 * // and percent format for each locale</strong>
339 * Locale[] locales = NumberFormat.getAvailableLocales();
340 * double myNumber = -1234.56;
342 * for (int j=0; j<4; ++j) {
343 * System.out.println("FORMAT");
344 * for (int i = 0; i < locales.length; ++i) {
345 * if (locales[i].getCountry().length() == 0) {
346 * continue; // Skip language-only locales
348 * System.out.print(locales[i].getDisplayName());
351 * form = NumberFormat.getInstance(locales[i]); break;
353 * form = NumberFormat.getIntegerInstance(locales[i]); break;
355 * form = NumberFormat.getCurrencyInstance(locales[i]); break;
357 * form = NumberFormat.getPercentInstance(locales[i]); break;
359 * if (form instanceof DecimalFormat) {
360 * System.out.print(": " + ((DecimalFormat) form).toPattern());
362 * System.out.print(" -> " + form.format(myNumber));
364 * System.out.println(" -> " + form.parse(form.format(myNumber)));
365 * } catch (ParseException e) {}
368 * </pre></blockquote>
370 * @see <a href="http://java.sun.com/docs/books/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a>
372 * @see DecimalFormatSymbols
377 public class DecimalFormat extends NumberFormat {
380 * Creates a DecimalFormat using the default pattern and symbols
381 * for the default locale. This is a convenient way to obtain a
382 * DecimalFormat when internationalization is not the main concern.
384 * To obtain standard formats for a given locale, use the factory methods
385 * on NumberFormat such as getNumberInstance. These factories will
386 * return the most appropriate sub-class of NumberFormat for a given
389 * @see java.text.NumberFormat#getInstance
390 * @see java.text.NumberFormat#getNumberInstance
391 * @see java.text.NumberFormat#getCurrencyInstance
392 * @see java.text.NumberFormat#getPercentInstance
394 public DecimalFormat() {
395 Locale def = Locale.getDefault(Locale.Category.FORMAT);
396 // try to get the pattern from the cache
397 String pattern = cachedLocaleData.get(def);
398 if (pattern == null) { /* cache miss */
399 // Get the pattern for the default locale.
400 // ResourceBundle rb = LocaleData.getNumberFormatData(def);
401 // String[] all = rb.getStringArray("NumberPatterns");
403 // /* update cache */
404 // cachedLocaleData.putIfAbsent(def, pattern);
407 // Always applyPattern after the symbols are set
408 this.symbols = new DecimalFormatSymbols(def);
409 applyPattern(pattern, false);
414 * Creates a DecimalFormat using the given pattern and the symbols
415 * for the default locale. This is a convenient way to obtain a
416 * DecimalFormat when internationalization is not the main concern.
418 * To obtain standard formats for a given locale, use the factory methods
419 * on NumberFormat such as getNumberInstance. These factories will
420 * return the most appropriate sub-class of NumberFormat for a given
423 * @param pattern A non-localized pattern string.
424 * @exception NullPointerException if <code>pattern</code> is null
425 * @exception IllegalArgumentException if the given pattern is invalid.
426 * @see java.text.NumberFormat#getInstance
427 * @see java.text.NumberFormat#getNumberInstance
428 * @see java.text.NumberFormat#getCurrencyInstance
429 * @see java.text.NumberFormat#getPercentInstance
431 public DecimalFormat(String pattern) {
432 // Always applyPattern after the symbols are set
433 this.symbols = new DecimalFormatSymbols(Locale.getDefault(Locale.Category.FORMAT));
434 applyPattern(pattern, false);
439 * Creates a DecimalFormat using the given pattern and symbols.
440 * Use this constructor when you need to completely customize the
441 * behavior of the format.
443 * To obtain standard formats for a given
444 * locale, use the factory methods on NumberFormat such as
445 * getInstance or getCurrencyInstance. If you need only minor adjustments
446 * to a standard format, you can modify the format returned by
447 * a NumberFormat factory method.
449 * @param pattern a non-localized pattern string
450 * @param symbols the set of symbols to be used
451 * @exception NullPointerException if any of the given arguments is null
452 * @exception IllegalArgumentException if the given pattern is invalid
453 * @see java.text.NumberFormat#getInstance
454 * @see java.text.NumberFormat#getNumberInstance
455 * @see java.text.NumberFormat#getCurrencyInstance
456 * @see java.text.NumberFormat#getPercentInstance
457 * @see java.text.DecimalFormatSymbols
459 public DecimalFormat (String pattern, DecimalFormatSymbols symbols) {
460 // Always applyPattern after the symbols are set
461 this.symbols = (DecimalFormatSymbols)symbols.clone();
462 applyPattern(pattern, false);
468 * Formats a number and appends the resulting text to the given string
470 * The number can be of any subclass of {@link java.lang.Number}.
472 * This implementation uses the maximum precision permitted.
473 * @param number the number to format
474 * @param toAppendTo the <code>StringBuffer</code> to which the formatted
475 * text is to be appended
476 * @param pos On input: an alignment field, if desired.
477 * On output: the offsets of the alignment field.
478 * @return the value passed in as <code>toAppendTo</code>
479 * @exception IllegalArgumentException if <code>number</code> is
480 * null or not an instance of <code>Number</code>.
481 * @exception NullPointerException if <code>toAppendTo</code> or
482 * <code>pos</code> is null
483 * @exception ArithmeticException if rounding is needed with rounding
484 * mode being set to RoundingMode.UNNECESSARY
485 * @see java.text.FieldPosition
487 public final StringBuffer format(Object number,
488 StringBuffer toAppendTo,
490 if (number instanceof Long || number instanceof Integer ||
491 number instanceof Short || number instanceof Byte ||
492 number instanceof AtomicInteger ||
493 number instanceof AtomicLong ||
494 (number instanceof BigInteger &&
495 ((BigInteger)number).bitLength () < 64)) {
496 return format(((Number)number).longValue(), toAppendTo, pos);
497 } else if (number instanceof BigDecimal) {
498 return format((BigDecimal)number, toAppendTo, pos);
499 } else if (number instanceof BigInteger) {
500 return format((BigInteger)number, toAppendTo, pos);
501 } else if (number instanceof Number) {
502 return format(((Number)number).doubleValue(), toAppendTo, pos);
504 throw new IllegalArgumentException("Cannot format given Object as a Number");
509 * Formats a double to produce a string.
510 * @param number The double to format
511 * @param result where the text is to be appended
512 * @param fieldPosition On input: an alignment field, if desired.
513 * On output: the offsets of the alignment field.
514 * @exception ArithmeticException if rounding is needed with rounding
515 * mode being set to RoundingMode.UNNECESSARY
516 * @return The formatted number string
517 * @see java.text.FieldPosition
519 public StringBuffer format(double number, StringBuffer result,
520 FieldPosition fieldPosition) {
521 fieldPosition.setBeginIndex(0);
522 fieldPosition.setEndIndex(0);
524 return format(number, result, fieldPosition.getFieldDelegate());
528 * Formats a double to produce a string.
529 * @param number The double to format
530 * @param result where the text is to be appended
531 * @param delegate notified of locations of sub fields
532 * @exception ArithmeticException if rounding is needed with rounding
533 * mode being set to RoundingMode.UNNECESSARY
534 * @return The formatted number string
536 private StringBuffer format(double number, StringBuffer result,
537 FieldDelegate delegate) {
538 if (Double.isNaN(number) ||
539 (Double.isInfinite(number) && multiplier == 0)) {
540 int iFieldStart = result.length();
541 result.append(symbols.getNaN());
542 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
543 iFieldStart, result.length(), result);
547 /* Detecting whether a double is negative is easy with the exception of
548 * the value -0.0. This is a double which has a zero mantissa (and
549 * exponent), but a negative sign bit. It is semantically distinct from
550 * a zero with a positive sign bit, and this distinction is important
551 * to certain kinds of computations. However, it's a little tricky to
552 * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0). How then, you may
553 * ask, does it behave distinctly from +0.0? Well, 1/(-0.0) ==
554 * -Infinity. Proper detection of -0.0 is needed to deal with the
555 * issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98.
557 boolean isNegative = ((number < 0.0) || (number == 0.0 && 1/number < 0.0)) ^ (multiplier < 0);
559 if (multiplier != 1) {
560 number *= multiplier;
563 if (Double.isInfinite(number)) {
565 append(result, negativePrefix, delegate,
566 getNegativePrefixFieldPositions(), Field.SIGN);
568 append(result, positivePrefix, delegate,
569 getPositivePrefixFieldPositions(), Field.SIGN);
572 int iFieldStart = result.length();
573 result.append(symbols.getInfinity());
574 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
575 iFieldStart, result.length(), result);
578 append(result, negativeSuffix, delegate,
579 getNegativeSuffixFieldPositions(), Field.SIGN);
581 append(result, positiveSuffix, delegate,
582 getPositiveSuffixFieldPositions(), Field.SIGN);
592 // at this point we are guaranteed a nonnegative finite number.
593 assert(number >= 0 && !Double.isInfinite(number));
595 synchronized(digitList) {
596 int maxIntDigits = super.getMaximumIntegerDigits();
597 int minIntDigits = super.getMinimumIntegerDigits();
598 int maxFraDigits = super.getMaximumFractionDigits();
599 int minFraDigits = super.getMinimumFractionDigits();
601 digitList.set(isNegative, number, useExponentialNotation ?
602 maxIntDigits + maxFraDigits : maxFraDigits,
603 !useExponentialNotation);
604 return subformat(result, delegate, isNegative, false,
605 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
610 * Format a long to produce a string.
611 * @param number The long to format
612 * @param result where the text is to be appended
613 * @param fieldPosition On input: an alignment field, if desired.
614 * On output: the offsets of the alignment field.
615 * @exception ArithmeticException if rounding is needed with rounding
616 * mode being set to RoundingMode.UNNECESSARY
617 * @return The formatted number string
618 * @see java.text.FieldPosition
620 public StringBuffer format(long number, StringBuffer result,
621 FieldPosition fieldPosition) {
622 fieldPosition.setBeginIndex(0);
623 fieldPosition.setEndIndex(0);
625 return format(number, result, fieldPosition.getFieldDelegate());
629 * Format a long to produce a string.
630 * @param number The long to format
631 * @param result where the text is to be appended
632 * @param delegate notified of locations of sub fields
633 * @return The formatted number string
634 * @exception ArithmeticException if rounding is needed with rounding
635 * mode being set to RoundingMode.UNNECESSARY
636 * @see java.text.FieldPosition
638 private StringBuffer format(long number, StringBuffer result,
639 FieldDelegate delegate) {
640 boolean isNegative = (number < 0);
645 // In general, long values always represent real finite numbers, so
646 // we don't have to check for +/- Infinity or NaN. However, there
647 // is one case we have to be careful of: The multiplier can push
648 // a number near MIN_VALUE or MAX_VALUE outside the legal range. We
649 // check for this before multiplying, and if it happens we use
650 // BigInteger instead.
651 boolean useBigInteger = false;
652 if (number < 0) { // This can only happen if number == Long.MIN_VALUE.
653 if (multiplier != 0) {
654 useBigInteger = true;
656 } else if (multiplier != 1 && multiplier != 0) {
657 long cutoff = Long.MAX_VALUE / multiplier;
661 useBigInteger = (number > cutoff);
668 BigInteger bigIntegerValue = BigInteger.valueOf(number);
669 return format(bigIntegerValue, result, delegate, true);
672 number *= multiplier;
676 if (multiplier < 0) {
678 isNegative = !isNegative;
682 synchronized(digitList) {
683 int maxIntDigits = super.getMaximumIntegerDigits();
684 int minIntDigits = super.getMinimumIntegerDigits();
685 int maxFraDigits = super.getMaximumFractionDigits();
686 int minFraDigits = super.getMinimumFractionDigits();
688 digitList.set(isNegative, number,
689 useExponentialNotation ? maxIntDigits + maxFraDigits : 0);
691 return subformat(result, delegate, isNegative, true,
692 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
697 * Formats a BigDecimal to produce a string.
698 * @param number The BigDecimal to format
699 * @param result where the text is to be appended
700 * @param fieldPosition On input: an alignment field, if desired.
701 * On output: the offsets of the alignment field.
702 * @return The formatted number string
703 * @exception ArithmeticException if rounding is needed with rounding
704 * mode being set to RoundingMode.UNNECESSARY
705 * @see java.text.FieldPosition
707 private StringBuffer format(BigDecimal number, StringBuffer result,
708 FieldPosition fieldPosition) {
709 fieldPosition.setBeginIndex(0);
710 fieldPosition.setEndIndex(0);
711 return format(number, result, fieldPosition.getFieldDelegate());
715 * Formats a BigDecimal to produce a string.
716 * @param number The BigDecimal to format
717 * @param result where the text is to be appended
718 * @param delegate notified of locations of sub fields
719 * @exception ArithmeticException if rounding is needed with rounding
720 * mode being set to RoundingMode.UNNECESSARY
721 * @return The formatted number string
723 private StringBuffer format(BigDecimal number, StringBuffer result,
724 FieldDelegate delegate) {
725 if (multiplier != 1) {
726 number = number.multiply(getBigDecimalMultiplier());
728 boolean isNegative = number.signum() == -1;
730 number = number.negate();
733 synchronized(digitList) {
734 int maxIntDigits = getMaximumIntegerDigits();
735 int minIntDigits = getMinimumIntegerDigits();
736 int maxFraDigits = getMaximumFractionDigits();
737 int minFraDigits = getMinimumFractionDigits();
738 int maximumDigits = maxIntDigits + maxFraDigits;
740 digitList.set(isNegative, number, useExponentialNotation ?
741 ((maximumDigits < 0) ? Integer.MAX_VALUE : maximumDigits) :
742 maxFraDigits, !useExponentialNotation);
744 return subformat(result, delegate, isNegative, false,
745 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
750 * Format a BigInteger to produce a string.
751 * @param number The BigInteger to format
752 * @param result where the text is to be appended
753 * @param fieldPosition On input: an alignment field, if desired.
754 * On output: the offsets of the alignment field.
755 * @return The formatted number string
756 * @exception ArithmeticException if rounding is needed with rounding
757 * mode being set to RoundingMode.UNNECESSARY
758 * @see java.text.FieldPosition
760 private StringBuffer format(BigInteger number, StringBuffer result,
761 FieldPosition fieldPosition) {
762 fieldPosition.setBeginIndex(0);
763 fieldPosition.setEndIndex(0);
765 return format(number, result, fieldPosition.getFieldDelegate(), false);
769 * Format a BigInteger to produce a string.
770 * @param number The BigInteger to format
771 * @param result where the text is to be appended
772 * @param delegate notified of locations of sub fields
773 * @return The formatted number string
774 * @exception ArithmeticException if rounding is needed with rounding
775 * mode being set to RoundingMode.UNNECESSARY
776 * @see java.text.FieldPosition
778 private StringBuffer format(BigInteger number, StringBuffer result,
779 FieldDelegate delegate, boolean formatLong) {
780 if (multiplier != 1) {
781 number = number.multiply(getBigIntegerMultiplier());
783 boolean isNegative = number.signum() == -1;
785 number = number.negate();
788 synchronized(digitList) {
789 int maxIntDigits, minIntDigits, maxFraDigits, minFraDigits, maximumDigits;
791 maxIntDigits = super.getMaximumIntegerDigits();
792 minIntDigits = super.getMinimumIntegerDigits();
793 maxFraDigits = super.getMaximumFractionDigits();
794 minFraDigits = super.getMinimumFractionDigits();
795 maximumDigits = maxIntDigits + maxFraDigits;
797 maxIntDigits = getMaximumIntegerDigits();
798 minIntDigits = getMinimumIntegerDigits();
799 maxFraDigits = getMaximumFractionDigits();
800 minFraDigits = getMinimumFractionDigits();
801 maximumDigits = maxIntDigits + maxFraDigits;
802 if (maximumDigits < 0) {
803 maximumDigits = Integer.MAX_VALUE;
807 digitList.set(isNegative, number,
808 useExponentialNotation ? maximumDigits : 0);
810 return subformat(result, delegate, isNegative, true,
811 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
816 * Formats an Object producing an <code>AttributedCharacterIterator</code>.
817 * You can use the returned <code>AttributedCharacterIterator</code>
818 * to build the resulting String, as well as to determine information
819 * about the resulting String.
821 * Each attribute key of the AttributedCharacterIterator will be of type
822 * <code>NumberFormat.Field</code>, with the attribute value being the
823 * same as the attribute key.
825 * @exception NullPointerException if obj is null.
826 * @exception IllegalArgumentException when the Format cannot format the
828 * @exception ArithmeticException if rounding is needed with rounding
829 * mode being set to RoundingMode.UNNECESSARY
830 * @param obj The object to format
831 * @return AttributedCharacterIterator describing the formatted value.
834 public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
835 CharacterIteratorFieldDelegate delegate =
836 new CharacterIteratorFieldDelegate();
837 StringBuffer sb = new StringBuffer();
839 if (obj instanceof Double || obj instanceof Float) {
840 format(((Number)obj).doubleValue(), sb, delegate);
841 } else if (obj instanceof Long || obj instanceof Integer ||
842 obj instanceof Short || obj instanceof Byte ||
843 obj instanceof AtomicInteger || obj instanceof AtomicLong) {
844 format(((Number)obj).longValue(), sb, delegate);
845 } else if (obj instanceof BigDecimal) {
846 format((BigDecimal)obj, sb, delegate);
847 } else if (obj instanceof BigInteger) {
848 format((BigInteger)obj, sb, delegate, false);
849 } else if (obj == null) {
850 throw new NullPointerException(
851 "formatToCharacterIterator must be passed non-null object");
853 throw new IllegalArgumentException(
854 "Cannot format given Object as a Number");
856 return delegate.getIterator(sb.toString());
860 * Complete the formatting of a finite number. On entry, the digitList must
861 * be filled in with the correct digits.
863 private StringBuffer subformat(StringBuffer result, FieldDelegate delegate,
864 boolean isNegative, boolean isInteger,
865 int maxIntDigits, int minIntDigits,
866 int maxFraDigits, int minFraDigits) {
867 // NOTE: This isn't required anymore because DigitList takes care of this.
869 // // The negative of the exponent represents the number of leading
870 // // zeros between the decimal and the first non-zero digit, for
871 // // a value < 0.1 (e.g., for 0.00123, -fExponent == 2). If this
872 // // is more than the maximum fraction digits, then we have an underflow
873 // // for the printed representation. We recognize this here and set
874 // // the DigitList representation to zero in this situation.
876 // if (-digitList.decimalAt >= getMaximumFractionDigits())
878 // digitList.count = 0;
881 char zero = symbols.getZeroDigit();
882 int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
883 char grouping = symbols.getGroupingSeparator();
884 char decimal = isCurrencyFormat ?
885 symbols.getMonetaryDecimalSeparator() :
886 symbols.getDecimalSeparator();
888 /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
889 * format as zero. This allows sensible computations and preserves
890 * relations such as signum(1/x) = signum(x), where x is +Infinity or
891 * -Infinity. Prior to this fix, we always formatted zero values as if
892 * they were positive. Liu 7/6/98.
894 if (digitList.isZero()) {
895 digitList.decimalAt = 0; // Normalize
899 append(result, negativePrefix, delegate,
900 getNegativePrefixFieldPositions(), Field.SIGN);
902 append(result, positivePrefix, delegate,
903 getPositivePrefixFieldPositions(), Field.SIGN);
906 if (useExponentialNotation) {
907 int iFieldStart = result.length();
909 int fFieldStart = -1;
911 // Minimum integer digits are handled in exponential format by
912 // adjusting the exponent. For example, 0.01234 with 3 minimum
913 // integer digits is "123.4E-4".
915 // Maximum integer digits are interpreted as indicating the
916 // repeating range. This is useful for engineering notation, in
917 // which the exponent is restricted to a multiple of 3. For
918 // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
919 // If maximum integer digits are > 1 and are larger than
920 // minimum integer digits, then minimum integer digits are
922 int exponent = digitList.decimalAt;
923 int repeat = maxIntDigits;
924 int minimumIntegerDigits = minIntDigits;
925 if (repeat > 1 && repeat > minIntDigits) {
926 // A repeating range is defined; adjust to it as follows.
927 // If repeat == 3, we have 6,5,4=>3; 3,2,1=>0; 0,-1,-2=>-3;
928 // -3,-4,-5=>-6, etc. This takes into account that the
929 // exponent we have here is off by one from what we expect;
930 // it is for the format 0.MMMMMx10^n.
932 exponent = ((exponent - 1) / repeat) * repeat;
934 // integer division rounds towards 0
935 exponent = ((exponent - repeat) / repeat) * repeat;
937 minimumIntegerDigits = 1;
939 // No repeating range is defined; use minimum integer digits.
940 exponent -= minimumIntegerDigits;
943 // We now output a minimum number of digits, and more if there
944 // are more digits, up to the maximum number of digits. We
945 // place the decimal point after the "integer" digits, which
946 // are the first (decimalAt - exponent) digits.
947 int minimumDigits = minIntDigits + minFraDigits;
948 if (minimumDigits < 0) { // overflow?
949 minimumDigits = Integer.MAX_VALUE;
952 // The number of integer digits is handled specially if the number
953 // is zero, since then there may be no digits.
954 int integerDigits = digitList.isZero() ? minimumIntegerDigits :
955 digitList.decimalAt - exponent;
956 if (minimumDigits < integerDigits) {
957 minimumDigits = integerDigits;
959 int totalDigits = digitList.count;
960 if (minimumDigits > totalDigits) {
961 totalDigits = minimumDigits;
963 boolean addedDecimalSeparator = false;
965 for (int i=0; i<totalDigits; ++i) {
966 if (i == integerDigits) {
967 // Record field information for caller.
968 iFieldEnd = result.length();
970 result.append(decimal);
971 addedDecimalSeparator = true;
973 // Record field information for caller.
974 fFieldStart = result.length();
976 result.append((i < digitList.count) ?
977 (char)(digitList.digits[i] + zeroDelta) :
981 if (decimalSeparatorAlwaysShown && totalDigits == integerDigits) {
982 // Record field information for caller.
983 iFieldEnd = result.length();
985 result.append(decimal);
986 addedDecimalSeparator = true;
988 // Record field information for caller.
989 fFieldStart = result.length();
992 // Record field information
993 if (iFieldEnd == -1) {
994 iFieldEnd = result.length();
996 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
997 iFieldStart, iFieldEnd, result);
998 if (addedDecimalSeparator) {
999 delegate.formatted(Field.DECIMAL_SEPARATOR,
1000 Field.DECIMAL_SEPARATOR,
1001 iFieldEnd, fFieldStart, result);
1003 if (fFieldStart == -1) {
1004 fFieldStart = result.length();
1006 delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
1007 fFieldStart, result.length(), result);
1009 // The exponent is output using the pattern-specified minimum
1010 // exponent digits. There is no maximum limit to the exponent
1011 // digits, since truncating the exponent would result in an
1012 // unacceptable inaccuracy.
1013 int fieldStart = result.length();
1015 result.append(symbols.getExponentSeparator());
1017 delegate.formatted(Field.EXPONENT_SYMBOL, Field.EXPONENT_SYMBOL,
1018 fieldStart, result.length(), result);
1020 // For zero values, we force the exponent to zero. We
1021 // must do this here, and not earlier, because the value
1022 // is used to determine integer digit count above.
1023 if (digitList.isZero()) {
1027 boolean negativeExponent = exponent < 0;
1028 if (negativeExponent) {
1029 exponent = -exponent;
1030 fieldStart = result.length();
1031 result.append(symbols.getMinusSign());
1032 delegate.formatted(Field.EXPONENT_SIGN, Field.EXPONENT_SIGN,
1033 fieldStart, result.length(), result);
1035 digitList.set(negativeExponent, exponent);
1037 int eFieldStart = result.length();
1039 for (int i=digitList.decimalAt; i<minExponentDigits; ++i) {
1040 result.append(zero);
1042 for (int i=0; i<digitList.decimalAt; ++i) {
1043 result.append((i < digitList.count) ?
1044 (char)(digitList.digits[i] + zeroDelta) : zero);
1046 delegate.formatted(Field.EXPONENT, Field.EXPONENT, eFieldStart,
1047 result.length(), result);
1049 int iFieldStart = result.length();
1051 // Output the integer portion. Here 'count' is the total
1052 // number of integer digits we will display, including both
1053 // leading zeros required to satisfy getMinimumIntegerDigits,
1054 // and actual digits present in the number.
1055 int count = minIntDigits;
1056 int digitIndex = 0; // Index into digitList.fDigits[]
1057 if (digitList.decimalAt > 0 && count < digitList.decimalAt) {
1058 count = digitList.decimalAt;
1061 // Handle the case where getMaximumIntegerDigits() is smaller
1062 // than the real number of integer digits. If this is so, we
1063 // output the least significant max integer digits. For example,
1064 // the value 1997 printed with 2 max integer digits is just "97".
1065 if (count > maxIntDigits) {
1066 count = maxIntDigits;
1067 digitIndex = digitList.decimalAt - count;
1070 int sizeBeforeIntegerPart = result.length();
1071 for (int i=count-1; i>=0; --i) {
1072 if (i < digitList.decimalAt && digitIndex < digitList.count) {
1073 // Output a real digit
1074 result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
1076 // Output a leading zero
1077 result.append(zero);
1080 // Output grouping separator if necessary. Don't output a
1081 // grouping separator if i==0 though; that's at the end of
1082 // the integer part.
1083 if (isGroupingUsed() && i>0 && (groupingSize != 0) &&
1084 (i % groupingSize == 0)) {
1085 int gStart = result.length();
1086 result.append(grouping);
1087 delegate.formatted(Field.GROUPING_SEPARATOR,
1088 Field.GROUPING_SEPARATOR, gStart,
1089 result.length(), result);
1093 // Determine whether or not there are any printable fractional
1094 // digits. If we've used up the digits we know there aren't.
1095 boolean fractionPresent = (minFraDigits > 0) ||
1096 (!isInteger && digitIndex < digitList.count);
1098 // If there is no fraction present, and we haven't printed any
1099 // integer digits, then print a zero. Otherwise we won't print
1100 // _any_ digits, and we won't be able to parse this string.
1101 if (!fractionPresent && result.length() == sizeBeforeIntegerPart) {
1102 result.append(zero);
1105 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
1106 iFieldStart, result.length(), result);
1108 // Output the decimal separator if we always do so.
1109 int sStart = result.length();
1110 if (decimalSeparatorAlwaysShown || fractionPresent) {
1111 result.append(decimal);
1114 if (sStart != result.length()) {
1115 delegate.formatted(Field.DECIMAL_SEPARATOR,
1116 Field.DECIMAL_SEPARATOR,
1117 sStart, result.length(), result);
1119 int fFieldStart = result.length();
1121 for (int i=0; i < maxFraDigits; ++i) {
1122 // Here is where we escape from the loop. We escape if we've
1123 // output the maximum fraction digits (specified in the for
1124 // expression above).
1125 // We also stop when we've output the minimum digits and either:
1126 // we have an integer, so there is no fractional stuff to
1127 // display, or we're out of significant digits.
1128 if (i >= minFraDigits &&
1129 (isInteger || digitIndex >= digitList.count)) {
1133 // Output leading fractional zeros. These are zeros that come
1134 // after the decimal but before any significant digits. These
1135 // are only output if abs(number being formatted) < 1.0.
1136 if (-1-i > (digitList.decimalAt-1)) {
1137 result.append(zero);
1141 // Output a digit, if we have any precision left, or a
1142 // zero if we don't. We don't want to output noise digits.
1143 if (!isInteger && digitIndex < digitList.count) {
1144 result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
1146 result.append(zero);
1150 // Record field information for caller.
1151 delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
1152 fFieldStart, result.length(), result);
1156 append(result, negativeSuffix, delegate,
1157 getNegativeSuffixFieldPositions(), Field.SIGN);
1160 append(result, positiveSuffix, delegate,
1161 getPositiveSuffixFieldPositions(), Field.SIGN);
1168 * Appends the String <code>string</code> to <code>result</code>.
1169 * <code>delegate</code> is notified of all the
1170 * <code>FieldPosition</code>s in <code>positions</code>.
1172 * If one of the <code>FieldPosition</code>s in <code>positions</code>
1173 * identifies a <code>SIGN</code> attribute, it is mapped to
1174 * <code>signAttribute</code>. This is used
1175 * to map the <code>SIGN</code> attribute to the <code>EXPONENT</code>
1176 * attribute as necessary.
1178 * This is used by <code>subformat</code> to add the prefix/suffix.
1180 private void append(StringBuffer result, String string,
1181 FieldDelegate delegate,
1182 FieldPosition[] positions,
1183 Format.Field signAttribute) {
1184 int start = result.length();
1186 if (string.length() > 0) {
1187 result.append(string);
1188 for (int counter = 0, max = positions.length; counter < max;
1190 FieldPosition fp = positions[counter];
1191 Format.Field attribute = fp.getFieldAttribute();
1193 if (attribute == Field.SIGN) {
1194 attribute = signAttribute;
1196 delegate.formatted(attribute, attribute,
1197 start + fp.getBeginIndex(),
1198 start + fp.getEndIndex(), result);
1204 * Parses text from a string to produce a <code>Number</code>.
1206 * The method attempts to parse text starting at the index given by
1208 * If parsing succeeds, then the index of <code>pos</code> is updated
1209 * to the index after the last character used (parsing does not necessarily
1210 * use all characters up to the end of the string), and the parsed
1211 * number is returned. The updated <code>pos</code> can be used to
1212 * indicate the starting point for the next call to this method.
1213 * If an error occurs, then the index of <code>pos</code> is not
1214 * changed, the error index of <code>pos</code> is set to the index of
1215 * the character where the error occurred, and null is returned.
1217 * The subclass returned depends on the value of {@link #isParseBigDecimal}
1218 * as well as on the string being parsed.
1220 * <li>If <code>isParseBigDecimal()</code> is false (the default),
1221 * most integer values are returned as <code>Long</code>
1222 * objects, no matter how they are written: <code>"17"</code> and
1223 * <code>"17.000"</code> both parse to <code>Long(17)</code>.
1224 * Values that cannot fit into a <code>Long</code> are returned as
1225 * <code>Double</code>s. This includes values with a fractional part,
1226 * infinite values, <code>NaN</code>, and the value -0.0.
1227 * <code>DecimalFormat</code> does <em>not</em> decide whether to
1228 * return a <code>Double</code> or a <code>Long</code> based on the
1229 * presence of a decimal separator in the source string. Doing so
1230 * would prevent integers that overflow the mantissa of a double,
1231 * such as <code>"-9,223,372,036,854,775,808.00"</code>, from being
1232 * parsed accurately.
1234 * Callers may use the <code>Number</code> methods
1235 * <code>doubleValue</code>, <code>longValue</code>, etc., to obtain
1236 * the type they want.
1237 * <li>If <code>isParseBigDecimal()</code> is true, values are returned
1238 * as <code>BigDecimal</code> objects. The values are the ones
1239 * constructed by {@link java.math.BigDecimal#BigDecimal(String)}
1240 * for corresponding strings in locale-independent format. The
1241 * special cases negative and positive infinity and NaN are returned
1242 * as <code>Double</code> instances holding the values of the
1243 * corresponding <code>Double</code> constants.
1246 * <code>DecimalFormat</code> parses all Unicode characters that represent
1247 * decimal digits, as defined by <code>Character.digit()</code>. In
1248 * addition, <code>DecimalFormat</code> also recognizes as digits the ten
1249 * consecutive characters starting with the localized zero digit defined in
1250 * the <code>DecimalFormatSymbols</code> object.
1252 * @param text the string to be parsed
1253 * @param pos A <code>ParsePosition</code> object with index and error
1254 * index information as described above.
1255 * @return the parsed value, or <code>null</code> if the parse fails
1256 * @exception NullPointerException if <code>text</code> or
1257 * <code>pos</code> is null.
1259 public Number parse(String text, ParsePosition pos) {
1261 if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) {
1262 pos.index = pos.index + symbols.getNaN().length();
1263 return new Double(Double.NaN);
1266 boolean[] status = new boolean[STATUS_LENGTH];
1267 if (!subparse(text, pos, positivePrefix, negativePrefix, digitList, false, status)) {
1271 // special case INFINITY
1272 if (status[STATUS_INFINITE]) {
1273 if (status[STATUS_POSITIVE] == (multiplier >= 0)) {
1274 return new Double(Double.POSITIVE_INFINITY);
1276 return new Double(Double.NEGATIVE_INFINITY);
1280 if (multiplier == 0) {
1281 if (digitList.isZero()) {
1282 return new Double(Double.NaN);
1283 } else if (status[STATUS_POSITIVE]) {
1284 return new Double(Double.POSITIVE_INFINITY);
1286 return new Double(Double.NEGATIVE_INFINITY);
1290 if (isParseBigDecimal()) {
1291 BigDecimal bigDecimalResult = digitList.getBigDecimal();
1293 if (multiplier != 1) {
1295 bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier());
1297 catch (ArithmeticException e) { // non-terminating decimal expansion
1298 bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier(), roundingMode);
1302 if (!status[STATUS_POSITIVE]) {
1303 bigDecimalResult = bigDecimalResult.negate();
1305 return bigDecimalResult;
1307 boolean gotDouble = true;
1308 boolean gotLongMinimum = false;
1309 double doubleResult = 0.0;
1310 long longResult = 0;
1312 // Finally, have DigitList parse the digits into a value.
1313 if (digitList.fitsIntoLong(status[STATUS_POSITIVE], isParseIntegerOnly())) {
1315 longResult = digitList.getLong();
1316 if (longResult < 0) { // got Long.MIN_VALUE
1317 gotLongMinimum = true;
1320 doubleResult = digitList.getDouble();
1323 // Divide by multiplier. We have to be careful here not to do
1324 // unneeded conversions between double and long.
1325 if (multiplier != 1) {
1327 doubleResult /= multiplier;
1329 // Avoid converting to double if we can
1330 if (longResult % multiplier == 0) {
1331 longResult /= multiplier;
1333 doubleResult = ((double)longResult) / multiplier;
1339 if (!status[STATUS_POSITIVE] && !gotLongMinimum) {
1340 doubleResult = -doubleResult;
1341 longResult = -longResult;
1344 // At this point, if we divided the result by the multiplier, the
1345 // result may fit into a long. We check for this case and return
1346 // a long if possible.
1347 // We must do this AFTER applying the negative (if appropriate)
1348 // in order to handle the case of LONG_MIN; otherwise, if we do
1349 // this with a positive value -LONG_MIN, the double is > 0, but
1350 // the long is < 0. We also must retain a double in the case of
1351 // -0.0, which will compare as == to a long 0 cast to a double
1353 if (multiplier != 1 && gotDouble) {
1354 longResult = (long)doubleResult;
1355 gotDouble = ((doubleResult != (double)longResult) ||
1356 (doubleResult == 0.0 && 1/doubleResult < 0.0)) &&
1357 !isParseIntegerOnly();
1361 (Number)new Double(doubleResult) : (Number)new Long(longResult);
1366 * Return a BigInteger multiplier.
1368 private BigInteger getBigIntegerMultiplier() {
1369 if (bigIntegerMultiplier == null) {
1370 bigIntegerMultiplier = BigInteger.valueOf(multiplier);
1372 return bigIntegerMultiplier;
1374 private transient BigInteger bigIntegerMultiplier;
1377 * Return a BigDecimal multiplier.
1379 private BigDecimal getBigDecimalMultiplier() {
1380 if (bigDecimalMultiplier == null) {
1381 bigDecimalMultiplier = new BigDecimal(multiplier);
1383 return bigDecimalMultiplier;
1385 private transient BigDecimal bigDecimalMultiplier;
1387 private static final int STATUS_INFINITE = 0;
1388 private static final int STATUS_POSITIVE = 1;
1389 private static final int STATUS_LENGTH = 2;
1392 * Parse the given text into a number. The text is parsed beginning at
1393 * parsePosition, until an unparseable character is seen.
1394 * @param text The string to parse.
1395 * @param parsePosition The position at which to being parsing. Upon
1396 * return, the first unparseable character.
1397 * @param digits The DigitList to set to the parsed value.
1398 * @param isExponent If true, parse an exponent. This means no
1399 * infinite values and integer only.
1400 * @param status Upon return contains boolean status flags indicating
1401 * whether the value was infinite and whether it was positive.
1403 private final boolean subparse(String text, ParsePosition parsePosition,
1404 String positivePrefix, String negativePrefix,
1405 DigitList digits, boolean isExponent,
1407 int position = parsePosition.index;
1408 int oldStart = parsePosition.index;
1410 boolean gotPositive, gotNegative;
1412 // check for positivePrefix; take longest
1413 gotPositive = text.regionMatches(position, positivePrefix, 0,
1414 positivePrefix.length());
1415 gotNegative = text.regionMatches(position, negativePrefix, 0,
1416 negativePrefix.length());
1418 if (gotPositive && gotNegative) {
1419 if (positivePrefix.length() > negativePrefix.length()) {
1420 gotNegative = false;
1421 } else if (positivePrefix.length() < negativePrefix.length()) {
1422 gotPositive = false;
1427 position += positivePrefix.length();
1428 } else if (gotNegative) {
1429 position += negativePrefix.length();
1431 parsePosition.errorIndex = position;
1435 // process digits or Inf, find decimal position
1436 status[STATUS_INFINITE] = false;
1437 if (!isExponent && text.regionMatches(position,symbols.getInfinity(),0,
1438 symbols.getInfinity().length())) {
1439 position += symbols.getInfinity().length();
1440 status[STATUS_INFINITE] = true;
1442 // We now have a string of digits, possibly with grouping symbols,
1443 // and decimal points. We want to process these into a DigitList.
1444 // We don't want to put a bunch of leading zeros into the DigitList
1445 // though, so we keep track of the location of the decimal point,
1446 // put only significant digits into the DigitList, and adjust the
1447 // exponent as needed.
1449 digits.decimalAt = digits.count = 0;
1450 char zero = symbols.getZeroDigit();
1451 char decimal = isCurrencyFormat ?
1452 symbols.getMonetaryDecimalSeparator() :
1453 symbols.getDecimalSeparator();
1454 char grouping = symbols.getGroupingSeparator();
1455 String exponentString = symbols.getExponentSeparator();
1456 boolean sawDecimal = false;
1457 boolean sawExponent = false;
1458 boolean sawDigit = false;
1459 int exponent = 0; // Set to the exponent value, if any
1461 // We have to track digitCount ourselves, because digits.count will
1462 // pin when the maximum allowable digits is reached.
1466 for (; position < text.length(); ++position) {
1467 char ch = text.charAt(position);
1469 /* We recognize all digit ranges, not only the Latin digit range
1470 * '0'..'9'. We do so by using the Character.digit() method,
1471 * which converts a valid Unicode digit to the range 0..9.
1473 * The character 'ch' may be a digit. If so, place its value
1474 * from 0 to 9 in 'digit'. First try using the locale digit,
1475 * which may or MAY NOT be a standard Unicode digit range. If
1476 * this fails, try using the standard Unicode digit ranges by
1477 * calling Character.digit(). If this also fails, digit will
1478 * have a value outside the range 0..9.
1480 int digit = ch - zero;
1481 if (digit < 0 || digit > 9) {
1482 digit = Character.digit(ch, 10);
1486 // Cancel out backup setting (see grouping handler below)
1487 backup = -1; // Do this BEFORE continue statement below!!!
1490 // Handle leading zeros
1491 if (digits.count == 0) {
1492 // Ignore leading zeros in integer part of number.
1497 // If we have seen the decimal, but no significant
1498 // digits yet, then we account for leading zeros by
1499 // decrementing the digits.decimalAt into negative
1504 digits.append((char)(digit + '0'));
1506 } else if (digit > 0 && digit <= 9) { // [sic] digit==0 handled above
1509 digits.append((char)(digit + '0'));
1511 // Cancel out backup setting (see grouping handler below)
1513 } else if (!isExponent && ch == decimal) {
1514 // If we're only parsing integers, or if we ALREADY saw the
1515 // decimal, then don't parse this one.
1516 if (isParseIntegerOnly() || sawDecimal) {
1519 digits.decimalAt = digitCount; // Not digits.count!
1521 } else if (!isExponent && ch == grouping && isGroupingUsed()) {
1525 // Ignore grouping characters, if we are using them, but
1526 // require that they be followed by a digit. Otherwise
1527 // we backup and reprocess them.
1529 } else if (!isExponent && text.regionMatches(position, exponentString, 0, exponentString.length())
1531 // Process the exponent by recursively calling this method.
1532 ParsePosition pos = new ParsePosition(position + exponentString.length());
1533 boolean[] stat = new boolean[STATUS_LENGTH];
1534 DigitList exponentDigits = new DigitList();
1536 if (subparse(text, pos, "", Character.toString(symbols.getMinusSign()), exponentDigits, true, stat) &&
1537 exponentDigits.fitsIntoLong(stat[STATUS_POSITIVE], true)) {
1538 position = pos.index; // Advance past the exponent
1539 exponent = (int)exponentDigits.getLong();
1540 if (!stat[STATUS_POSITIVE]) {
1541 exponent = -exponent;
1545 break; // Whether we fail or succeed, we exit this loop
1556 // If there was no decimal point we have an integer
1558 digits.decimalAt = digitCount; // Not digits.count!
1561 // Adjust for exponent, if any
1562 digits.decimalAt += exponent;
1564 // If none of the text string was recognized. For example, parse
1565 // "x" with pattern "#0.00" (return index and error index both 0)
1566 // parse "$" with pattern "$#0.00". (return index 0 and error
1568 if (!sawDigit && digitCount == 0) {
1569 parsePosition.index = oldStart;
1570 parsePosition.errorIndex = oldStart;
1578 gotPositive = text.regionMatches(position,positiveSuffix,0,
1579 positiveSuffix.length());
1582 gotNegative = text.regionMatches(position,negativeSuffix,0,
1583 negativeSuffix.length());
1586 // if both match, take longest
1587 if (gotPositive && gotNegative) {
1588 if (positiveSuffix.length() > negativeSuffix.length()) {
1589 gotNegative = false;
1590 } else if (positiveSuffix.length() < negativeSuffix.length()) {
1591 gotPositive = false;
1595 // fail if neither or both
1596 if (gotPositive == gotNegative) {
1597 parsePosition.errorIndex = position;
1601 parsePosition.index = position +
1602 (gotPositive ? positiveSuffix.length() : negativeSuffix.length()); // mark success!
1604 parsePosition.index = position;
1607 status[STATUS_POSITIVE] = gotPositive;
1608 if (parsePosition.index == oldStart) {
1609 parsePosition.errorIndex = position;
1616 * Returns a copy of the decimal format symbols, which is generally not
1617 * changed by the programmer or user.
1618 * @return a copy of the desired DecimalFormatSymbols
1619 * @see java.text.DecimalFormatSymbols
1621 public DecimalFormatSymbols getDecimalFormatSymbols() {
1623 // don't allow multiple references
1624 return (DecimalFormatSymbols) symbols.clone();
1625 } catch (Exception foo) {
1626 return null; // should never happen
1632 * Sets the decimal format symbols, which is generally not changed
1633 * by the programmer or user.
1634 * @param newSymbols desired DecimalFormatSymbols
1635 * @see java.text.DecimalFormatSymbols
1637 public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
1639 // don't allow multiple references
1640 symbols = (DecimalFormatSymbols) newSymbols.clone();
1642 } catch (Exception foo) {
1643 // should never happen
1648 * Get the positive prefix.
1649 * <P>Examples: +123, $123, sFr123
1651 public String getPositivePrefix () {
1652 return positivePrefix;
1656 * Set the positive prefix.
1657 * <P>Examples: +123, $123, sFr123
1659 public void setPositivePrefix (String newValue) {
1660 positivePrefix = newValue;
1661 posPrefixPattern = null;
1662 positivePrefixFieldPositions = null;
1666 * Returns the FieldPositions of the fields in the prefix used for
1667 * positive numbers. This is not used if the user has explicitly set
1668 * a positive prefix via <code>setPositivePrefix</code>. This is
1671 * @return FieldPositions in positive prefix
1673 private FieldPosition[] getPositivePrefixFieldPositions() {
1674 if (positivePrefixFieldPositions == null) {
1675 if (posPrefixPattern != null) {
1676 positivePrefixFieldPositions = expandAffix(posPrefixPattern);
1679 positivePrefixFieldPositions = EmptyFieldPositionArray;
1682 return positivePrefixFieldPositions;
1686 * Get the negative prefix.
1687 * <P>Examples: -123, ($123) (with negative suffix), sFr-123
1689 public String getNegativePrefix () {
1690 return negativePrefix;
1694 * Set the negative prefix.
1695 * <P>Examples: -123, ($123) (with negative suffix), sFr-123
1697 public void setNegativePrefix (String newValue) {
1698 negativePrefix = newValue;
1699 negPrefixPattern = null;
1703 * Returns the FieldPositions of the fields in the prefix used for
1704 * negative numbers. This is not used if the user has explicitly set
1705 * a negative prefix via <code>setNegativePrefix</code>. This is
1708 * @return FieldPositions in positive prefix
1710 private FieldPosition[] getNegativePrefixFieldPositions() {
1711 if (negativePrefixFieldPositions == null) {
1712 if (negPrefixPattern != null) {
1713 negativePrefixFieldPositions = expandAffix(negPrefixPattern);
1716 negativePrefixFieldPositions = EmptyFieldPositionArray;
1719 return negativePrefixFieldPositions;
1723 * Get the positive suffix.
1726 public String getPositiveSuffix () {
1727 return positiveSuffix;
1731 * Set the positive suffix.
1734 public void setPositiveSuffix (String newValue) {
1735 positiveSuffix = newValue;
1736 posSuffixPattern = null;
1740 * Returns the FieldPositions of the fields in the suffix used for
1741 * positive numbers. This is not used if the user has explicitly set
1742 * a positive suffix via <code>setPositiveSuffix</code>. This is
1745 * @return FieldPositions in positive prefix
1747 private FieldPosition[] getPositiveSuffixFieldPositions() {
1748 if (positiveSuffixFieldPositions == null) {
1749 if (posSuffixPattern != null) {
1750 positiveSuffixFieldPositions = expandAffix(posSuffixPattern);
1753 positiveSuffixFieldPositions = EmptyFieldPositionArray;
1756 return positiveSuffixFieldPositions;
1760 * Get the negative suffix.
1761 * <P>Examples: -123%, ($123) (with positive suffixes)
1763 public String getNegativeSuffix () {
1764 return negativeSuffix;
1768 * Set the negative suffix.
1771 public void setNegativeSuffix (String newValue) {
1772 negativeSuffix = newValue;
1773 negSuffixPattern = null;
1777 * Returns the FieldPositions of the fields in the suffix used for
1778 * negative numbers. This is not used if the user has explicitly set
1779 * a negative suffix via <code>setNegativeSuffix</code>. This is
1782 * @return FieldPositions in positive prefix
1784 private FieldPosition[] getNegativeSuffixFieldPositions() {
1785 if (negativeSuffixFieldPositions == null) {
1786 if (negSuffixPattern != null) {
1787 negativeSuffixFieldPositions = expandAffix(negSuffixPattern);
1790 negativeSuffixFieldPositions = EmptyFieldPositionArray;
1793 return negativeSuffixFieldPositions;
1797 * Gets the multiplier for use in percent, per mille, and similar
1800 * @see #setMultiplier(int)
1802 public int getMultiplier () {
1807 * Sets the multiplier for use in percent, per mille, and similar
1809 * For a percent format, set the multiplier to 100 and the suffixes to
1810 * have '%' (for Arabic, use the Arabic percent sign).
1811 * For a per mille format, set the multiplier to 1000 and the suffixes to
1812 * have '\u2030'.
1814 * <P>Example: with multiplier 100, 1.23 is formatted as "123", and
1815 * "123" is parsed into 1.23.
1817 * @see #getMultiplier
1819 public void setMultiplier (int newValue) {
1820 multiplier = newValue;
1821 bigDecimalMultiplier = null;
1822 bigIntegerMultiplier = null;
1826 * Return the grouping size. Grouping size is the number of digits between
1827 * grouping separators in the integer portion of a number. For example,
1828 * in the number "123,456.78", the grouping size is 3.
1829 * @see #setGroupingSize
1830 * @see java.text.NumberFormat#isGroupingUsed
1831 * @see java.text.DecimalFormatSymbols#getGroupingSeparator
1833 public int getGroupingSize () {
1834 return groupingSize;
1838 * Set the grouping size. Grouping size is the number of digits between
1839 * grouping separators in the integer portion of a number. For example,
1840 * in the number "123,456.78", the grouping size is 3.
1842 * The value passed in is converted to a byte, which may lose information.
1843 * @see #getGroupingSize
1844 * @see java.text.NumberFormat#setGroupingUsed
1845 * @see java.text.DecimalFormatSymbols#setGroupingSeparator
1847 public void setGroupingSize (int newValue) {
1848 groupingSize = (byte)newValue;
1852 * Allows you to get the behavior of the decimal separator with integers.
1853 * (The decimal separator will always appear with decimals.)
1854 * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
1856 public boolean isDecimalSeparatorAlwaysShown() {
1857 return decimalSeparatorAlwaysShown;
1861 * Allows you to set the behavior of the decimal separator with integers.
1862 * (The decimal separator will always appear with decimals.)
1863 * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
1865 public void setDecimalSeparatorAlwaysShown(boolean newValue) {
1866 decimalSeparatorAlwaysShown = newValue;
1870 * Returns whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1871 * method returns <code>BigDecimal</code>. The default value is false.
1872 * @see #setParseBigDecimal
1875 public boolean isParseBigDecimal() {
1876 return parseBigDecimal;
1880 * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1881 * method returns <code>BigDecimal</code>.
1882 * @see #isParseBigDecimal
1885 public void setParseBigDecimal(boolean newValue) {
1886 parseBigDecimal = newValue;
1890 * Standard override; no change in semantics.
1892 public Object clone() {
1894 DecimalFormat other = (DecimalFormat) super.clone();
1895 other.symbols = (DecimalFormatSymbols) symbols.clone();
1896 other.digitList = (DigitList) digitList.clone();
1898 } catch (Exception e) {
1899 throw new InternalError();
1906 public boolean equals(Object obj)
1908 if (obj == null) return false;
1909 if (!super.equals(obj)) return false; // super does class check
1910 DecimalFormat other = (DecimalFormat) obj;
1911 return ((posPrefixPattern == other.posPrefixPattern &&
1912 positivePrefix.equals(other.positivePrefix))
1913 || (posPrefixPattern != null &&
1914 posPrefixPattern.equals(other.posPrefixPattern)))
1915 && ((posSuffixPattern == other.posSuffixPattern &&
1916 positiveSuffix.equals(other.positiveSuffix))
1917 || (posSuffixPattern != null &&
1918 posSuffixPattern.equals(other.posSuffixPattern)))
1919 && ((negPrefixPattern == other.negPrefixPattern &&
1920 negativePrefix.equals(other.negativePrefix))
1921 || (negPrefixPattern != null &&
1922 negPrefixPattern.equals(other.negPrefixPattern)))
1923 && ((negSuffixPattern == other.negSuffixPattern &&
1924 negativeSuffix.equals(other.negativeSuffix))
1925 || (negSuffixPattern != null &&
1926 negSuffixPattern.equals(other.negSuffixPattern)))
1927 && multiplier == other.multiplier
1928 && groupingSize == other.groupingSize
1929 && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown
1930 && parseBigDecimal == other.parseBigDecimal
1931 && useExponentialNotation == other.useExponentialNotation
1932 && (!useExponentialNotation ||
1933 minExponentDigits == other.minExponentDigits)
1934 && maximumIntegerDigits == other.maximumIntegerDigits
1935 && minimumIntegerDigits == other.minimumIntegerDigits
1936 && maximumFractionDigits == other.maximumFractionDigits
1937 && minimumFractionDigits == other.minimumFractionDigits
1938 && roundingMode == other.roundingMode
1939 && symbols.equals(other.symbols);
1943 * Overrides hashCode
1945 public int hashCode() {
1946 return super.hashCode() * 37 + positivePrefix.hashCode();
1947 // just enough fields for a reasonable distribution
1951 * Synthesizes a pattern string that represents the current state
1952 * of this Format object.
1953 * @see #applyPattern
1955 public String toPattern() {
1956 return toPattern( false );
1960 * Synthesizes a localized pattern string that represents the current
1961 * state of this Format object.
1962 * @see #applyPattern
1964 public String toLocalizedPattern() {
1965 return toPattern( true );
1969 * Expand the affix pattern strings into the expanded affix strings. If any
1970 * affix pattern string is null, do not expand it. This method should be
1971 * called any time the symbols or the affix patterns change in order to keep
1972 * the expanded affix strings up to date.
1974 private void expandAffixes() {
1975 // Reuse one StringBuffer for better performance
1976 StringBuffer buffer = new StringBuffer();
1977 if (posPrefixPattern != null) {
1978 positivePrefix = expandAffix(posPrefixPattern, buffer);
1979 positivePrefixFieldPositions = null;
1981 if (posSuffixPattern != null) {
1982 positiveSuffix = expandAffix(posSuffixPattern, buffer);
1983 positiveSuffixFieldPositions = null;
1985 if (negPrefixPattern != null) {
1986 negativePrefix = expandAffix(negPrefixPattern, buffer);
1987 negativePrefixFieldPositions = null;
1989 if (negSuffixPattern != null) {
1990 negativeSuffix = expandAffix(negSuffixPattern, buffer);
1991 negativeSuffixFieldPositions = null;
1996 * Expand an affix pattern into an affix string. All characters in the
1997 * pattern are literal unless prefixed by QUOTE. The following characters
1998 * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
1999 * PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE +
2000 * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
2001 * currency code. Any other character after a QUOTE represents itself.
2002 * QUOTE must be followed by another character; QUOTE may not occur by
2003 * itself at the end of the pattern.
2005 * @param pattern the non-null, possibly empty pattern
2006 * @param buffer a scratch StringBuffer; its contents will be lost
2007 * @return the expanded equivalent of pattern
2009 private String expandAffix(String pattern, StringBuffer buffer) {
2010 buffer.setLength(0);
2011 for (int i=0; i<pattern.length(); ) {
2012 char c = pattern.charAt(i++);
2014 c = pattern.charAt(i++);
2017 if (i<pattern.length() &&
2018 pattern.charAt(i) == CURRENCY_SIGN) {
2020 buffer.append(symbols.getInternationalCurrencySymbol());
2022 buffer.append(symbols.getCurrencySymbol());
2025 case PATTERN_PERCENT:
2026 c = symbols.getPercent();
2028 case PATTERN_PER_MILLE:
2029 c = symbols.getPerMill();
2032 c = symbols.getMinusSign();
2038 return buffer.toString();
2042 * Expand an affix pattern into an array of FieldPositions describing
2043 * how the pattern would be expanded.
2044 * All characters in the
2045 * pattern are literal unless prefixed by QUOTE. The following characters
2046 * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2047 * PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE +
2048 * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
2049 * currency code. Any other character after a QUOTE represents itself.
2050 * QUOTE must be followed by another character; QUOTE may not occur by
2051 * itself at the end of the pattern.
2053 * @param pattern the non-null, possibly empty pattern
2054 * @return FieldPosition array of the resulting fields.
2056 private FieldPosition[] expandAffix(String pattern) {
2057 ArrayList positions = null;
2058 int stringIndex = 0;
2059 for (int i=0; i<pattern.length(); ) {
2060 char c = pattern.charAt(i++);
2063 Format.Field fieldID = null;
2064 c = pattern.charAt(i++);
2068 if (i<pattern.length() &&
2069 pattern.charAt(i) == CURRENCY_SIGN) {
2071 string = symbols.getInternationalCurrencySymbol();
2073 string = symbols.getCurrencySymbol();
2075 if (string.length() > 0) {
2076 if (positions == null) {
2077 positions = new ArrayList(2);
2079 FieldPosition fp = new FieldPosition(Field.CURRENCY);
2080 fp.setBeginIndex(stringIndex);
2081 fp.setEndIndex(stringIndex + string.length());
2083 stringIndex += string.length();
2086 case PATTERN_PERCENT:
2087 c = symbols.getPercent();
2089 fieldID = Field.PERCENT;
2091 case PATTERN_PER_MILLE:
2092 c = symbols.getPerMill();
2094 fieldID = Field.PERMILLE;
2097 c = symbols.getMinusSign();
2099 fieldID = Field.SIGN;
2102 if (fieldID != null) {
2103 if (positions == null) {
2104 positions = new ArrayList(2);
2106 FieldPosition fp = new FieldPosition(fieldID, field);
2107 fp.setBeginIndex(stringIndex);
2108 fp.setEndIndex(stringIndex + 1);
2114 if (positions != null) {
2115 return (FieldPosition[])positions.toArray(EmptyFieldPositionArray);
2117 return EmptyFieldPositionArray;
2121 * Appends an affix pattern to the given StringBuffer, quoting special
2122 * characters as needed. Uses the internal affix pattern, if that exists,
2123 * or the literal affix, if the internal affix pattern is null. The
2124 * appended string will generate the same affix pattern (or literal affix)
2125 * when passed to toPattern().
2127 * @param buffer the affix string is appended to this
2128 * @param affixPattern a pattern such as posPrefixPattern; may be null
2129 * @param expAffix a corresponding expanded affix, such as positivePrefix.
2130 * Ignored unless affixPattern is null. If affixPattern is null, then
2131 * expAffix is appended as a literal affix.
2132 * @param localized true if the appended pattern should contain localized
2133 * pattern characters; otherwise, non-localized pattern chars are appended
2135 private void appendAffix(StringBuffer buffer, String affixPattern,
2136 String expAffix, boolean localized) {
2137 if (affixPattern == null) {
2138 appendAffix(buffer, expAffix, localized);
2141 for (int pos=0; pos<affixPattern.length(); pos=i) {
2142 i = affixPattern.indexOf(QUOTE, pos);
2144 appendAffix(buffer, affixPattern.substring(pos), localized);
2148 appendAffix(buffer, affixPattern.substring(pos, i), localized);
2150 char c = affixPattern.charAt(++i);
2154 // Fall through and append another QUOTE below
2155 } else if (c == CURRENCY_SIGN &&
2156 i<affixPattern.length() &&
2157 affixPattern.charAt(i) == CURRENCY_SIGN) {
2160 // Fall through and append another CURRENCY_SIGN below
2161 } else if (localized) {
2163 case PATTERN_PERCENT:
2164 c = symbols.getPercent();
2166 case PATTERN_PER_MILLE:
2167 c = symbols.getPerMill();
2170 c = symbols.getMinusSign();
2180 * Append an affix to the given StringBuffer, using quotes if
2181 * there are special characters. Single quotes themselves must be
2182 * escaped in either case.
2184 private void appendAffix(StringBuffer buffer, String affix, boolean localized) {
2187 needQuote = affix.indexOf(symbols.getZeroDigit()) >= 0
2188 || affix.indexOf(symbols.getGroupingSeparator()) >= 0
2189 || affix.indexOf(symbols.getDecimalSeparator()) >= 0
2190 || affix.indexOf(symbols.getPercent()) >= 0
2191 || affix.indexOf(symbols.getPerMill()) >= 0
2192 || affix.indexOf(symbols.getDigit()) >= 0
2193 || affix.indexOf(symbols.getPatternSeparator()) >= 0
2194 || affix.indexOf(symbols.getMinusSign()) >= 0
2195 || affix.indexOf(CURRENCY_SIGN) >= 0;
2198 needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 0
2199 || affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 0
2200 || affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 0
2201 || affix.indexOf(PATTERN_PERCENT) >= 0
2202 || affix.indexOf(PATTERN_PER_MILLE) >= 0
2203 || affix.indexOf(PATTERN_DIGIT) >= 0
2204 || affix.indexOf(PATTERN_SEPARATOR) >= 0
2205 || affix.indexOf(PATTERN_MINUS) >= 0
2206 || affix.indexOf(CURRENCY_SIGN) >= 0;
2208 if (needQuote) buffer.append('\'');
2209 if (affix.indexOf('\'') < 0) buffer.append(affix);
2211 for (int j=0; j<affix.length(); ++j) {
2212 char c = affix.charAt(j);
2214 if (c == '\'') buffer.append(c);
2217 if (needQuote) buffer.append('\'');
2221 * Does the real work of generating a pattern. */
2222 private String toPattern(boolean localized) {
2223 StringBuffer result = new StringBuffer();
2224 for (int j = 1; j >= 0; --j) {
2226 appendAffix(result, posPrefixPattern, positivePrefix, localized);
2227 else appendAffix(result, negPrefixPattern, negativePrefix, localized);
2229 int digitCount = useExponentialNotation
2230 ? getMaximumIntegerDigits()
2231 : Math.max(groupingSize, getMinimumIntegerDigits())+1;
2232 for (i = digitCount; i > 0; --i) {
2233 if (i != digitCount && isGroupingUsed() && groupingSize != 0 &&
2234 i % groupingSize == 0) {
2235 result.append(localized ? symbols.getGroupingSeparator() :
2236 PATTERN_GROUPING_SEPARATOR);
2238 result.append(i <= getMinimumIntegerDigits()
2239 ? (localized ? symbols.getZeroDigit() : PATTERN_ZERO_DIGIT)
2240 : (localized ? symbols.getDigit() : PATTERN_DIGIT));
2242 if (getMaximumFractionDigits() > 0 || decimalSeparatorAlwaysShown)
2243 result.append(localized ? symbols.getDecimalSeparator() :
2244 PATTERN_DECIMAL_SEPARATOR);
2245 for (i = 0; i < getMaximumFractionDigits(); ++i) {
2246 if (i < getMinimumFractionDigits()) {
2247 result.append(localized ? symbols.getZeroDigit() :
2248 PATTERN_ZERO_DIGIT);
2250 result.append(localized ? symbols.getDigit() :
2254 if (useExponentialNotation)
2256 result.append(localized ? symbols.getExponentSeparator() :
2258 for (i=0; i<minExponentDigits; ++i)
2259 result.append(localized ? symbols.getZeroDigit() :
2260 PATTERN_ZERO_DIGIT);
2263 appendAffix(result, posSuffixPattern, positiveSuffix, localized);
2264 if ((negSuffixPattern == posSuffixPattern && // n == p == null
2265 negativeSuffix.equals(positiveSuffix))
2266 || (negSuffixPattern != null &&
2267 negSuffixPattern.equals(posSuffixPattern))) {
2268 if ((negPrefixPattern != null && posPrefixPattern != null &&
2269 negPrefixPattern.equals("'-" + posPrefixPattern)) ||
2270 (negPrefixPattern == posPrefixPattern && // n == p == null
2271 negativePrefix.equals(symbols.getMinusSign() + positivePrefix)))
2274 result.append(localized ? symbols.getPatternSeparator() :
2276 } else appendAffix(result, negSuffixPattern, negativeSuffix, localized);
2278 return result.toString();
2282 * Apply the given pattern to this Format object. A pattern is a
2283 * short-hand specification for the various formatting properties.
2284 * These properties can also be changed individually through the
2285 * various setter methods.
2287 * There is no limit to integer digits set
2288 * by this routine, since that is the typical end-user desire;
2289 * use setMaximumInteger if you want to set a real value.
2290 * For negative numbers, use a second pattern, separated by a semicolon
2291 * <P>Example <code>"#,#00.0#"</code> -> 1,234.56
2292 * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
2293 * a maximum of 2 fraction digits.
2294 * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
2296 * <p>In negative patterns, the minimum and maximum counts are ignored;
2297 * these are presumed to be set in the positive pattern.
2299 * @exception NullPointerException if <code>pattern</code> is null
2300 * @exception IllegalArgumentException if the given pattern is invalid.
2302 public void applyPattern(String pattern) {
2303 applyPattern(pattern, false);
2307 * Apply the given pattern to this Format object. The pattern
2308 * is assumed to be in a localized notation. A pattern is a
2309 * short-hand specification for the various formatting properties.
2310 * These properties can also be changed individually through the
2311 * various setter methods.
2313 * There is no limit to integer digits set
2314 * by this routine, since that is the typical end-user desire;
2315 * use setMaximumInteger if you want to set a real value.
2316 * For negative numbers, use a second pattern, separated by a semicolon
2317 * <P>Example <code>"#,#00.0#"</code> -> 1,234.56
2318 * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
2319 * a maximum of 2 fraction digits.
2320 * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
2322 * <p>In negative patterns, the minimum and maximum counts are ignored;
2323 * these are presumed to be set in the positive pattern.
2325 * @exception NullPointerException if <code>pattern</code> is null
2326 * @exception IllegalArgumentException if the given pattern is invalid.
2328 public void applyLocalizedPattern(String pattern) {
2329 applyPattern(pattern, true);
2333 * Does the real work of applying a pattern.
2335 private void applyPattern(String pattern, boolean localized) {
2336 char zeroDigit = PATTERN_ZERO_DIGIT;
2337 char groupingSeparator = PATTERN_GROUPING_SEPARATOR;
2338 char decimalSeparator = PATTERN_DECIMAL_SEPARATOR;
2339 char percent = PATTERN_PERCENT;
2340 char perMill = PATTERN_PER_MILLE;
2341 char digit = PATTERN_DIGIT;
2342 char separator = PATTERN_SEPARATOR;
2343 String exponent = PATTERN_EXPONENT;
2344 char minus = PATTERN_MINUS;
2346 zeroDigit = symbols.getZeroDigit();
2347 groupingSeparator = symbols.getGroupingSeparator();
2348 decimalSeparator = symbols.getDecimalSeparator();
2349 percent = symbols.getPercent();
2350 perMill = symbols.getPerMill();
2351 digit = symbols.getDigit();
2352 separator = symbols.getPatternSeparator();
2353 exponent = symbols.getExponentSeparator();
2354 minus = symbols.getMinusSign();
2356 boolean gotNegative = false;
2357 decimalSeparatorAlwaysShown = false;
2358 isCurrencyFormat = false;
2359 useExponentialNotation = false;
2361 // Two variables are used to record the subrange of the pattern
2362 // occupied by phase 1. This is used during the processing of the
2363 // second pattern (the one representing negative numbers) to ensure
2364 // that no deviation exists in phase 1 between the two patterns.
2365 int phaseOneStart = 0;
2366 int phaseOneLength = 0;
2369 for (int j = 1; j >= 0 && start < pattern.length(); --j) {
2370 boolean inQuote = false;
2371 StringBuffer prefix = new StringBuffer();
2372 StringBuffer suffix = new StringBuffer();
2373 int decimalPos = -1;
2375 int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0;
2376 byte groupingCount = -1;
2378 // The phase ranges from 0 to 2. Phase 0 is the prefix. Phase 1 is
2379 // the section of the pattern with digits, decimal separator,
2380 // grouping characters. Phase 2 is the suffix. In phases 0 and 2,
2381 // percent, per mille, and currency symbols are recognized and
2382 // translated. The separation of the characters into phases is
2383 // strictly enforced; if phase 1 characters are to appear in the
2384 // suffix, for example, they must be quoted.
2387 // The affix is either the prefix or the suffix.
2388 StringBuffer affix = prefix;
2390 for (int pos = start; pos < pattern.length(); ++pos) {
2391 char ch = pattern.charAt(pos);
2395 // Process the prefix / suffix characters
2397 // A quote within quotes indicates either the closing
2398 // quote or two quotes, which is a quote literal. That
2399 // is, we have the second quote in 'do' or 'don''t'.
2401 if ((pos+1) < pattern.length() &&
2402 pattern.charAt(pos+1) == QUOTE) {
2404 affix.append("''"); // 'don''t'
2406 inQuote = false; // 'do'
2411 // Process unquoted characters seen in prefix or suffix
2415 ch == groupingSeparator ||
2416 ch == decimalSeparator) {
2419 phaseOneStart = pos;
2421 --pos; // Reprocess this character
2423 } else if (ch == CURRENCY_SIGN) {
2424 // Use lookahead to determine if the currency sign
2425 // is doubled or not.
2426 boolean doubled = (pos + 1) < pattern.length() &&
2427 pattern.charAt(pos + 1) == CURRENCY_SIGN;
2428 if (doubled) { // Skip over the doubled character
2431 isCurrencyFormat = true;
2432 affix.append(doubled ? "'\u00A4\u00A4" : "'\u00A4");
2434 } else if (ch == QUOTE) {
2435 // A quote outside quotes indicates either the
2436 // opening quote or two quotes, which is a quote
2437 // literal. That is, we have the first quote in 'do'
2440 if ((pos+1) < pattern.length() &&
2441 pattern.charAt(pos+1) == QUOTE) {
2443 affix.append("''"); // o''clock
2445 inQuote = true; // 'do'
2449 } else if (ch == separator) {
2450 // Don't allow separators before we see digit
2451 // characters of phase 1, and don't allow separators
2452 // in the second pattern (j == 0).
2453 if (phase == 0 || j == 0) {
2454 throw new IllegalArgumentException("Unquoted special character '" +
2455 ch + "' in pattern \"" + pattern + '"');
2458 pos = pattern.length();
2462 // Next handle characters which are appended directly.
2463 else if (ch == percent) {
2464 if (multiplier != 1) {
2465 throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +
2471 } else if (ch == perMill) {
2472 if (multiplier != 1) {
2473 throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +
2477 affix.append("'\u2030");
2479 } else if (ch == minus) {
2484 // Note that if we are within quotes, or if this is an
2485 // unquoted, non-special character, then we usually fall
2491 // Phase one must be identical in the two sub-patterns. We
2492 // enforce this by doing a direct comparison. While
2493 // processing the first sub-pattern, we just record its
2494 // length. While processing the second, we compare
2499 if (--phaseOneLength == 0) {
2506 // Process the digits, decimal, and grouping characters. We
2507 // record five pieces of information. We expect the digits
2508 // to occur in the pattern ####0000.####, and we record the
2509 // number of left digits, zero (central) digits, and right
2510 // digits. The position of the last grouping character is
2511 // recorded (should be somewhere within the first two blocks
2512 // of characters), as is the position of the decimal point,
2513 // if any (should be in the zero digits). If there is no
2514 // decimal point, then there should be no right digits.
2516 if (zeroDigitCount > 0) {
2521 if (groupingCount >= 0 && decimalPos < 0) {
2524 } else if (ch == zeroDigit) {
2525 if (digitRightCount > 0) {
2526 throw new IllegalArgumentException("Unexpected '0' in pattern \"" +
2530 if (groupingCount >= 0 && decimalPos < 0) {
2533 } else if (ch == groupingSeparator) {
2535 } else if (ch == decimalSeparator) {
2536 if (decimalPos >= 0) {
2537 throw new IllegalArgumentException("Multiple decimal separators in pattern \"" +
2540 decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
2541 } else if (pattern.regionMatches(pos, exponent, 0, exponent.length())){
2542 if (useExponentialNotation) {
2543 throw new IllegalArgumentException("Multiple exponential " +
2544 "symbols in pattern \"" + pattern + '"');
2546 useExponentialNotation = true;
2547 minExponentDigits = 0;
2549 // Use lookahead to parse out the exponential part
2550 // of the pattern, then jump into phase 2.
2551 pos = pos+exponent.length();
2552 while (pos < pattern.length() &&
2553 pattern.charAt(pos) == zeroDigit) {
2554 ++minExponentDigits;
2559 if ((digitLeftCount + zeroDigitCount) < 1 ||
2560 minExponentDigits < 1) {
2561 throw new IllegalArgumentException("Malformed exponential " +
2562 "pattern \"" + pattern + '"');
2565 // Transition to phase 2
2581 // Handle patterns with no '0' pattern character. These patterns
2582 // are legal, but must be interpreted. "##.###" -> "#0.###".
2583 // ".###" -> ".0##".
2584 /* We allow patterns of the form "####" to produce a zeroDigitCount
2585 * of zero (got that?); although this seems like it might make it
2586 * possible for format() to produce empty strings, format() checks
2587 * for this condition and outputs a zero digit in this situation.
2588 * Having a zeroDigitCount of zero yields a minimum integer digits
2589 * of zero, which allows proper round-trip patterns. That is, we
2590 * don't want "#" to become "#0" when toPattern() is called (even
2591 * though that's what it really is, semantically).
2593 if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {
2594 // Handle "###.###" and "###." and ".###"
2596 if (n == 0) { // Handle ".###"
2599 digitRightCount = digitLeftCount - n;
2600 digitLeftCount = n - 1;
2604 // Do syntax checking on the digits.
2605 if ((decimalPos < 0 && digitRightCount > 0) ||
2606 (decimalPos >= 0 && (decimalPos < digitLeftCount ||
2607 decimalPos > (digitLeftCount + zeroDigitCount))) ||
2608 groupingCount == 0 || inQuote) {
2609 throw new IllegalArgumentException("Malformed pattern \"" +
2614 posPrefixPattern = prefix.toString();
2615 posSuffixPattern = suffix.toString();
2616 negPrefixPattern = posPrefixPattern; // assume these for now
2617 negSuffixPattern = posSuffixPattern;
2618 int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
2619 /* The effectiveDecimalPos is the position the decimal is at or
2620 * would be at if there is no decimal. Note that if decimalPos<0,
2621 * then digitTotalCount == digitLeftCount + zeroDigitCount.
2623 int effectiveDecimalPos = decimalPos >= 0 ?
2624 decimalPos : digitTotalCount;
2625 setMinimumIntegerDigits(effectiveDecimalPos - digitLeftCount);
2626 setMaximumIntegerDigits(useExponentialNotation ?
2627 digitLeftCount + getMinimumIntegerDigits() :
2628 MAXIMUM_INTEGER_DIGITS);
2629 setMaximumFractionDigits(decimalPos >= 0 ?
2630 (digitTotalCount - decimalPos) : 0);
2631 setMinimumFractionDigits(decimalPos >= 0 ?
2632 (digitLeftCount + zeroDigitCount - decimalPos) : 0);
2633 setGroupingUsed(groupingCount > 0);
2634 this.groupingSize = (groupingCount > 0) ? groupingCount : 0;
2635 this.multiplier = multiplier;
2636 setDecimalSeparatorAlwaysShown(decimalPos == 0 ||
2637 decimalPos == digitTotalCount);
2639 negPrefixPattern = prefix.toString();
2640 negSuffixPattern = suffix.toString();
2645 if (pattern.length() == 0) {
2646 posPrefixPattern = posSuffixPattern = "";
2647 setMinimumIntegerDigits(0);
2648 setMaximumIntegerDigits(MAXIMUM_INTEGER_DIGITS);
2649 setMinimumFractionDigits(0);
2650 setMaximumFractionDigits(MAXIMUM_FRACTION_DIGITS);
2653 // If there was no negative pattern, or if the negative pattern is
2654 // identical to the positive pattern, then prepend the minus sign to
2655 // the positive pattern to form the negative pattern.
2657 (negPrefixPattern.equals(posPrefixPattern)
2658 && negSuffixPattern.equals(posSuffixPattern))) {
2659 negSuffixPattern = posSuffixPattern;
2660 negPrefixPattern = "'-" + posPrefixPattern;
2667 * Sets the maximum number of digits allowed in the integer portion of a
2669 * For formatting numbers other than <code>BigInteger</code> and
2670 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2671 * 309 is used. Negative input values are replaced with 0.
2672 * @see NumberFormat#setMaximumIntegerDigits
2674 public void setMaximumIntegerDigits(int newValue) {
2675 maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
2676 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2677 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
2678 if (minimumIntegerDigits > maximumIntegerDigits) {
2679 minimumIntegerDigits = maximumIntegerDigits;
2680 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2681 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
2686 * Sets the minimum number of digits allowed in the integer portion of a
2688 * For formatting numbers other than <code>BigInteger</code> and
2689 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2690 * 309 is used. Negative input values are replaced with 0.
2691 * @see NumberFormat#setMinimumIntegerDigits
2693 public void setMinimumIntegerDigits(int newValue) {
2694 minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
2695 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2696 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
2697 if (minimumIntegerDigits > maximumIntegerDigits) {
2698 maximumIntegerDigits = minimumIntegerDigits;
2699 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2700 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
2705 * Sets the maximum number of digits allowed in the fraction portion of a
2707 * For formatting numbers other than <code>BigInteger</code> and
2708 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2709 * 340 is used. Negative input values are replaced with 0.
2710 * @see NumberFormat#setMaximumFractionDigits
2712 public void setMaximumFractionDigits(int newValue) {
2713 maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
2714 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2715 DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
2716 if (minimumFractionDigits > maximumFractionDigits) {
2717 minimumFractionDigits = maximumFractionDigits;
2718 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2719 DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
2724 * Sets the minimum number of digits allowed in the fraction portion of a
2726 * For formatting numbers other than <code>BigInteger</code> and
2727 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2728 * 340 is used. Negative input values are replaced with 0.
2729 * @see NumberFormat#setMinimumFractionDigits
2731 public void setMinimumFractionDigits(int newValue) {
2732 minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
2733 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2734 DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
2735 if (minimumFractionDigits > maximumFractionDigits) {
2736 maximumFractionDigits = minimumFractionDigits;
2737 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2738 DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
2743 * Gets the maximum number of digits allowed in the integer portion of a
2745 * For formatting numbers other than <code>BigInteger</code> and
2746 * <code>BigDecimal</code> objects, the lower of the return value and
2748 * @see #setMaximumIntegerDigits
2750 public int getMaximumIntegerDigits() {
2751 return maximumIntegerDigits;
2755 * Gets the minimum number of digits allowed in the integer portion of a
2757 * For formatting numbers other than <code>BigInteger</code> and
2758 * <code>BigDecimal</code> objects, the lower of the return value and
2760 * @see #setMinimumIntegerDigits
2762 public int getMinimumIntegerDigits() {
2763 return minimumIntegerDigits;
2767 * Gets the maximum number of digits allowed in the fraction portion of a
2769 * For formatting numbers other than <code>BigInteger</code> and
2770 * <code>BigDecimal</code> objects, the lower of the return value and
2772 * @see #setMaximumFractionDigits
2774 public int getMaximumFractionDigits() {
2775 return maximumFractionDigits;
2779 * Gets the minimum number of digits allowed in the fraction portion of a
2781 * For formatting numbers other than <code>BigInteger</code> and
2782 * <code>BigDecimal</code> objects, the lower of the return value and
2784 * @see #setMinimumFractionDigits
2786 public int getMinimumFractionDigits() {
2787 return minimumFractionDigits;
2791 * Gets the currency used by this decimal format when formatting
2793 * The currency is obtained by calling
2794 * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency}
2795 * on this number format's symbols.
2797 * @return the currency used by this decimal format, or <code>null</code>
2800 public Currency getCurrency() {
2801 return symbols.getCurrency();
2805 * Sets the currency used by this number format when formatting
2806 * currency values. This does not update the minimum or maximum
2807 * number of fraction digits used by the number format.
2808 * The currency is set by calling
2809 * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency}
2810 * on this number format's symbols.
2812 * @param currency the new currency to be used by this decimal format
2813 * @exception NullPointerException if <code>currency</code> is null
2816 public void setCurrency(Currency currency) {
2817 if (currency != symbols.getCurrency()) {
2818 symbols.setCurrency(currency);
2819 if (isCurrencyFormat) {
2826 * Gets the {@link java.math.RoundingMode} used in this DecimalFormat.
2828 * @return The <code>RoundingMode</code> used for this DecimalFormat.
2829 * @see #setRoundingMode(RoundingMode)
2832 public RoundingMode getRoundingMode() {
2833 return roundingMode;
2837 * Sets the {@link java.math.RoundingMode} used in this DecimalFormat.
2839 * @param roundingMode The <code>RoundingMode</code> to be used
2840 * @see #getRoundingMode()
2841 * @exception NullPointerException if <code>roundingMode</code> is null.
2844 public void setRoundingMode(RoundingMode roundingMode) {
2845 if (roundingMode == null) {
2846 throw new NullPointerException();
2849 this.roundingMode = roundingMode;
2850 digitList.setRoundingMode(roundingMode);
2854 * Adjusts the minimum and maximum fraction digits to values that
2855 * are reasonable for the currency's default fraction digits.
2857 void adjustForCurrencyDefaultFractionDigits() {
2858 Currency currency = symbols.getCurrency();
2859 if (currency == null) {
2861 currency = Currency.getInstance(symbols.getInternationalCurrencySymbol());
2862 } catch (IllegalArgumentException e) {
2865 if (currency != null) {
2866 int digits = currency.getDefaultFractionDigits();
2868 int oldMinDigits = getMinimumFractionDigits();
2869 // Common patterns are "#.##", "#.00", "#".
2870 // Try to adjust all of them in a reasonable way.
2871 if (oldMinDigits == getMaximumFractionDigits()) {
2872 setMinimumFractionDigits(digits);
2873 setMaximumFractionDigits(digits);
2875 setMinimumFractionDigits(Math.min(digits, oldMinDigits));
2876 setMaximumFractionDigits(digits);
2883 * Reads the default serializable fields from the stream and performs
2884 * validations and adjustments for older serialized versions. The
2885 * validations and adjustments are:
2888 * Verify that the superclass's digit count fields correctly reflect
2889 * the limits imposed on formatting numbers other than
2890 * <code>BigInteger</code> and <code>BigDecimal</code> objects. These
2891 * limits are stored in the superclass for serialization compatibility
2892 * with older versions, while the limits for <code>BigInteger</code> and
2893 * <code>BigDecimal</code> objects are kept in this class.
2894 * If, in the superclass, the minimum or maximum integer digit count is
2895 * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or
2896 * maximum fraction digit count is larger than
2897 * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid
2898 * and this method throws an <code>InvalidObjectException</code>.
2900 * If <code>serialVersionOnStream</code> is less than 4, initialize
2901 * <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN
2902 * RoundingMode.HALF_EVEN}. This field is new with version 4.
2904 * If <code>serialVersionOnStream</code> is less than 3, then call
2905 * the setters for the minimum and maximum integer and fraction digits with
2906 * the values of the corresponding superclass getters to initialize the
2907 * fields in this class. The fields in this class are new with version 3.
2909 * If <code>serialVersionOnStream</code> is less than 1, indicating that
2910 * the stream was written by JDK 1.1, initialize
2911 * <code>useExponentialNotation</code>
2912 * to false, since it was not present in JDK 1.1.
2914 * Set <code>serialVersionOnStream</code> to the maximum allowed value so
2915 * that default serialization will work properly if this object is streamed
2919 * <p>Stream versions older than 2 will not have the affix pattern variables
2920 * <code>posPrefixPattern</code> etc. As a result, they will be initialized
2921 * to <code>null</code>, which means the affix strings will be taken as
2922 * literal values. This is exactly what we want, since that corresponds to
2923 * the pre-version-2 behavior.
2925 private void readObject(ObjectInputStream stream)
2926 throws IOException, ClassNotFoundException
2928 stream.defaultReadObject();
2929 digitList = new DigitList();
2931 if (serialVersionOnStream < 4) {
2932 setRoundingMode(RoundingMode.HALF_EVEN);
2934 // We only need to check the maximum counts because NumberFormat
2935 // .readObject has already ensured that the maximum is greater than the
2937 if (super.getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS ||
2938 super.getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {
2939 throw new InvalidObjectException("Digit count out of range");
2941 if (serialVersionOnStream < 3) {
2942 setMaximumIntegerDigits(super.getMaximumIntegerDigits());
2943 setMinimumIntegerDigits(super.getMinimumIntegerDigits());
2944 setMaximumFractionDigits(super.getMaximumFractionDigits());
2945 setMinimumFractionDigits(super.getMinimumFractionDigits());
2947 if (serialVersionOnStream < 1) {
2948 // Didn't have exponential fields
2949 useExponentialNotation = false;
2951 serialVersionOnStream = currentSerialVersion;
2954 //----------------------------------------------------------------------
2955 // INSTANCE VARIABLES
2956 //----------------------------------------------------------------------
2958 private transient DigitList digitList = new DigitList();
2961 * The symbol used as a prefix when formatting positive numbers, e.g. "+".
2964 * @see #getPositivePrefix
2966 private String positivePrefix = "";
2969 * The symbol used as a suffix when formatting positive numbers.
2970 * This is often an empty string.
2973 * @see #getPositiveSuffix
2975 private String positiveSuffix = "";
2978 * The symbol used as a prefix when formatting negative numbers, e.g. "-".
2981 * @see #getNegativePrefix
2983 private String negativePrefix = "-";
2986 * The symbol used as a suffix when formatting negative numbers.
2987 * This is often an empty string.
2990 * @see #getNegativeSuffix
2992 private String negativeSuffix = "";
2995 * The prefix pattern for non-negative numbers. This variable corresponds
2996 * to <code>positivePrefix</code>.
2998 * <p>This pattern is expanded by the method <code>expandAffix()</code> to
2999 * <code>positivePrefix</code> to update the latter to reflect changes in
3000 * <code>symbols</code>. If this variable is <code>null</code> then
3001 * <code>positivePrefix</code> is taken as a literal value that does not
3002 * change when <code>symbols</code> changes. This variable is always
3003 * <code>null</code> for <code>DecimalFormat</code> objects older than
3004 * stream version 2 restored from stream.
3009 private String posPrefixPattern;
3012 * The suffix pattern for non-negative numbers. This variable corresponds
3013 * to <code>positiveSuffix</code>. This variable is analogous to
3014 * <code>posPrefixPattern</code>; see that variable for further
3020 private String posSuffixPattern;
3023 * The prefix pattern for negative numbers. This variable corresponds
3024 * to <code>negativePrefix</code>. This variable is analogous to
3025 * <code>posPrefixPattern</code>; see that variable for further
3031 private String negPrefixPattern;
3034 * The suffix pattern for negative numbers. This variable corresponds
3035 * to <code>negativeSuffix</code>. This variable is analogous to
3036 * <code>posPrefixPattern</code>; see that variable for further
3042 private String negSuffixPattern;
3045 * The multiplier for use in percent, per mille, etc.
3048 * @see #getMultiplier
3050 private int multiplier = 1;
3053 * The number of digits between grouping separators in the integer
3054 * portion of a number. Must be greater than 0 if
3055 * <code>NumberFormat.groupingUsed</code> is true.
3058 * @see #getGroupingSize
3059 * @see java.text.NumberFormat#isGroupingUsed
3061 private byte groupingSize = 3; // invariant, > 0 if useThousands
3064 * If true, forces the decimal separator to always appear in a formatted
3065 * number, even if the fractional part of the number is zero.
3068 * @see #isDecimalSeparatorAlwaysShown
3070 private boolean decimalSeparatorAlwaysShown = false;
3073 * If true, parse returns BigDecimal wherever possible.
3076 * @see #isParseBigDecimal
3079 private boolean parseBigDecimal = false;
3083 * True if this object represents a currency format. This determines
3084 * whether the monetary decimal separator is used instead of the normal one.
3086 private transient boolean isCurrencyFormat = false;
3089 * The <code>DecimalFormatSymbols</code> object used by this format.
3090 * It contains the symbols used to format numbers, e.g. the grouping separator,
3091 * decimal separator, and so on.
3094 * @see #setDecimalFormatSymbols
3095 * @see java.text.DecimalFormatSymbols
3097 private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols();
3100 * True to force the use of exponential (i.e. scientific) notation when formatting
3106 private boolean useExponentialNotation; // Newly persistent in the Java 2 platform v.1.2
3109 * FieldPositions describing the positive prefix String. This is
3110 * lazily created. Use <code>getPositivePrefixFieldPositions</code>
3113 private transient FieldPosition[] positivePrefixFieldPositions;
3116 * FieldPositions describing the positive suffix String. This is
3117 * lazily created. Use <code>getPositiveSuffixFieldPositions</code>
3120 private transient FieldPosition[] positiveSuffixFieldPositions;
3123 * FieldPositions describing the negative prefix String. This is
3124 * lazily created. Use <code>getNegativePrefixFieldPositions</code>
3127 private transient FieldPosition[] negativePrefixFieldPositions;
3130 * FieldPositions describing the negative suffix String. This is
3131 * lazily created. Use <code>getNegativeSuffixFieldPositions</code>
3134 private transient FieldPosition[] negativeSuffixFieldPositions;
3137 * The minimum number of digits used to display the exponent when a number is
3138 * formatted in exponential notation. This field is ignored if
3139 * <code>useExponentialNotation</code> is not true.
3144 private byte minExponentDigits; // Newly persistent in the Java 2 platform v.1.2
3147 * The maximum number of digits allowed in the integer portion of a
3148 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3149 * <code>maximumIntegerDigits</code> must be greater than or equal to
3150 * <code>minimumIntegerDigits</code>.
3153 * @see #getMaximumIntegerDigits
3156 private int maximumIntegerDigits = super.getMaximumIntegerDigits();
3159 * The minimum number of digits allowed in the integer portion of a
3160 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3161 * <code>minimumIntegerDigits</code> must be less than or equal to
3162 * <code>maximumIntegerDigits</code>.
3165 * @see #getMinimumIntegerDigits
3168 private int minimumIntegerDigits = super.getMinimumIntegerDigits();
3171 * The maximum number of digits allowed in the fractional portion of a
3172 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3173 * <code>maximumFractionDigits</code> must be greater than or equal to
3174 * <code>minimumFractionDigits</code>.
3177 * @see #getMaximumFractionDigits
3180 private int maximumFractionDigits = super.getMaximumFractionDigits();
3183 * The minimum number of digits allowed in the fractional portion of a
3184 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3185 * <code>minimumFractionDigits</code> must be less than or equal to
3186 * <code>maximumFractionDigits</code>.
3189 * @see #getMinimumFractionDigits
3192 private int minimumFractionDigits = super.getMinimumFractionDigits();
3195 * The {@link java.math.RoundingMode} used in this DecimalFormat.
3200 private RoundingMode roundingMode = RoundingMode.HALF_EVEN;
3202 //----------------------------------------------------------------------
3204 static final int currentSerialVersion = 4;
3207 * The internal serial version which says which version was written.
3208 * Possible values are:
3210 * <li><b>0</b> (default): versions before the Java 2 platform v1.2
3211 * <li><b>1</b>: version for 1.2, which includes the two new fields
3212 * <code>useExponentialNotation</code> and
3213 * <code>minExponentDigits</code>.
3214 * <li><b>2</b>: version for 1.3 and later, which adds four new fields:
3215 * <code>posPrefixPattern</code>, <code>posSuffixPattern</code>,
3216 * <code>negPrefixPattern</code>, and <code>negSuffixPattern</code>.
3217 * <li><b>3</b>: version for 1.5 and later, which adds five new fields:
3218 * <code>maximumIntegerDigits</code>,
3219 * <code>minimumIntegerDigits</code>,
3220 * <code>maximumFractionDigits</code>,
3221 * <code>minimumFractionDigits</code>, and
3222 * <code>parseBigDecimal</code>.
3223 * <li><b>4</b>: version for 1.6 and later, which adds one new field:
3224 * <code>roundingMode</code>.
3229 private int serialVersionOnStream = currentSerialVersion;
3231 //----------------------------------------------------------------------
3233 //----------------------------------------------------------------------
3235 // Constants for characters used in programmatic (unlocalized) patterns.
3236 private static final char PATTERN_ZERO_DIGIT = '0';
3237 private static final char PATTERN_GROUPING_SEPARATOR = ',';
3238 private static final char PATTERN_DECIMAL_SEPARATOR = '.';
3239 private static final char PATTERN_PER_MILLE = '\u2030';
3240 private static final char PATTERN_PERCENT = '%';
3241 private static final char PATTERN_DIGIT = '#';
3242 private static final char PATTERN_SEPARATOR = ';';
3243 private static final String PATTERN_EXPONENT = "E";
3244 private static final char PATTERN_MINUS = '-';
3247 * The CURRENCY_SIGN is the standard Unicode symbol for currency. It
3248 * is used in patterns and substituted with either the currency symbol,
3249 * or if it is doubled, with the international currency symbol. If the
3250 * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
3251 * replaced with the monetary decimal separator.
3253 * The CURRENCY_SIGN is not localized.
3255 private static final char CURRENCY_SIGN = '\u00A4';
3257 private static final char QUOTE = '\'';
3259 private static FieldPosition[] EmptyFieldPositionArray = new FieldPosition[0];
3261 // Upper limit on integer and fraction digits for a Java double
3262 static final int DOUBLE_INTEGER_DIGITS = 309;
3263 static final int DOUBLE_FRACTION_DIGITS = 340;
3265 // Upper limit on integer and fraction digits for BigDecimal and BigInteger
3266 static final int MAXIMUM_INTEGER_DIGITS = Integer.MAX_VALUE;
3267 static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE;
3269 // Proclaim JDK 1.1 serial compatibility.
3270 static final long serialVersionUID = 864413376551465018L;
3273 * Cache to hold the NumberPattern of a Locale.
3275 private static final ConcurrentMap<Locale, String> cachedLocaleData
3276 = new ConcurrentHashMap<Locale, String>(3);