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;
55 import sun.util.resources.LocaleData;
58 * <code>DecimalFormat</code> is a concrete subclass of
59 * <code>NumberFormat</code> that formats decimal numbers. It has a variety of
60 * features designed to make it possible to parse and format numbers in any
61 * locale, including support for Western, Arabic, and Indic digits. It also
62 * supports different kinds of numbers, including integers (123), fixed-point
63 * numbers (123.4), scientific notation (1.23E4), percentages (12%), and
64 * currency amounts ($123). All of these can be localized.
66 * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the
67 * default locale, call one of <code>NumberFormat</code>'s factory methods, such
68 * as <code>getInstance()</code>. In general, do not call the
69 * <code>DecimalFormat</code> constructors directly, since the
70 * <code>NumberFormat</code> factory methods may return subclasses other than
71 * <code>DecimalFormat</code>. If you need to customize the format object, do
72 * something like this:
75 * NumberFormat f = NumberFormat.getInstance(loc);
76 * if (f instanceof DecimalFormat) {
77 * ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
81 * <p>A <code>DecimalFormat</code> comprises a <em>pattern</em> and a set of
82 * <em>symbols</em>. The pattern may be set directly using
83 * <code>applyPattern()</code>, or indirectly using the API methods. The
84 * symbols are stored in a <code>DecimalFormatSymbols</code> object. When using
85 * the <code>NumberFormat</code> factory methods, the pattern and symbols are
86 * read from localized <code>ResourceBundle</code>s.
90 * <code>DecimalFormat</code> patterns have the following syntax:
93 * <i>PositivePattern</i>
94 * <i>PositivePattern</i> ; <i>NegativePattern</i>
95 * <i>PositivePattern:</i>
96 * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
97 * <i>NegativePattern:</i>
98 * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
100 * any Unicode characters except \uFFFE, \uFFFF, and special characters
102 * any Unicode characters except \uFFFE, \uFFFF, and special characters
104 * <i>Integer</i> <i>Exponent<sub>opt</sub></i>
105 * <i>Integer</i> . <i>Fraction</i> <i>Exponent<sub>opt</sub></i>
107 * <i>MinimumInteger</i>
111 * <i>MinimumInteger:</i>
113 * 0 <i>MinimumInteger</i>
114 * 0 , <i>MinimumInteger</i>
116 * <i>MinimumFraction<sub>opt</sub></i> <i>OptionalFraction<sub>opt</sub></i>
117 * <i>MinimumFraction:</i>
118 * 0 <i>MinimumFraction<sub>opt</sub></i>
119 * <i>OptionalFraction:</i>
120 * # <i>OptionalFraction<sub>opt</sub></i>
122 * E <i>MinimumExponent</i>
123 * <i>MinimumExponent:</i>
124 * 0 <i>MinimumExponent<sub>opt</sub></i>
125 * </pre></blockquote>
127 * <p>A <code>DecimalFormat</code> pattern contains a positive and negative
128 * subpattern, for example, <code>"#,##0.00;(#,##0.00)"</code>. Each
129 * subpattern has a prefix, numeric part, and suffix. The negative subpattern
130 * is optional; if absent, then the positive subpattern prefixed with the
131 * localized minus sign (<code>'-'</code> in most locales) is used as the
132 * negative subpattern. That is, <code>"0.00"</code> alone is equivalent to
133 * <code>"0.00;-0.00"</code>. If there is an explicit negative subpattern, it
134 * serves only to specify the negative prefix and suffix; the number of digits,
135 * minimal digits, and other characteristics are all the same as the positive
136 * pattern. That means that <code>"#,##0.0#;(#)"</code> produces precisely
137 * the same behavior as <code>"#,##0.0#;(#,##0.0#)"</code>.
139 * <p>The prefixes, suffixes, and various symbols used for infinity, digits,
140 * thousands separators, decimal separators, etc. may be set to arbitrary
141 * values, and they will appear properly during formatting. However, care must
142 * be taken that the symbols and strings do not conflict, or parsing will be
143 * unreliable. For example, either the positive and negative prefixes or the
144 * suffixes must be distinct for <code>DecimalFormat.parse()</code> to be able
145 * to distinguish positive from negative values. (If they are identical, then
146 * <code>DecimalFormat</code> will behave as if no negative subpattern was
147 * specified.) Another example is that the decimal separator and thousands
148 * separator should be distinct characters, or parsing will be impossible.
150 * <p>The grouping separator is commonly used for thousands, but in some
151 * countries it separates ten-thousands. The grouping size is a constant number
152 * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for
153 * 1,0000,0000. If you supply a pattern with multiple grouping characters, the
154 * interval between the last one and the end of the integer is the one that is
155 * used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> ==
156 * <code>"##,####,####"</code>.
158 * <h4>Special Pattern Characters</h4>
160 * <p>Many characters in a pattern are taken literally; they are matched during
161 * parsing and output unchanged during formatting. Special characters, on the
162 * other hand, stand for other characters, strings, or classes of characters.
163 * They must be quoted, unless noted otherwise, if they are to appear in the
164 * prefix or suffix as literals.
166 * <p>The characters listed here are used in non-localized patterns. Localized
167 * patterns use the corresponding characters taken from this formatter's
168 * <code>DecimalFormatSymbols</code> object instead, and these characters lose
169 * their special status. Two exceptions are the currency sign and quote, which
173 * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol,
174 * location, localized, and meaning.">
175 * <tr bgcolor="#ccccff">
176 * <th align=left>Symbol
177 * <th align=left>Location
178 * <th align=left>Localized?
179 * <th align=left>Meaning
185 * <tr valign=top bgcolor="#eeeeff">
189 * <td>Digit, zero shows as absent
194 * <td>Decimal separator or monetary decimal separator
195 * <tr valign=top bgcolor="#eeeeff">
204 * <td>Grouping separator
205 * <tr valign=top bgcolor="#eeeeff">
209 * <td>Separates mantissa and exponent in scientific notation.
210 * <em>Need not be quoted in prefix or suffix.</em>
213 * <td>Subpattern boundary
215 * <td>Separates positive and negative subpatterns
216 * <tr valign=top bgcolor="#eeeeff">
218 * <td>Prefix or suffix
220 * <td>Multiply by 100 and show as percentage
222 * <td><code>\u2030</code>
223 * <td>Prefix or suffix
225 * <td>Multiply by 1000 and show as per mille value
226 * <tr valign=top bgcolor="#eeeeff">
227 * <td><code>¤</code> (<code>\u00A4</code>)
228 * <td>Prefix or suffix
230 * <td>Currency sign, replaced by currency symbol. If
231 * doubled, replaced by international currency symbol.
232 * If present in a pattern, the monetary decimal separator
233 * is used instead of the decimal separator.
236 * <td>Prefix or suffix
238 * <td>Used to quote special characters in a prefix or suffix,
239 * for example, <code>"'#'#"</code> formats 123 to
240 * <code>"#123"</code>. To create a single quote
241 * itself, use two in a row: <code>"# o''clock"</code>.
245 * <h4>Scientific Notation</h4>
247 * <p>Numbers in scientific notation are expressed as the product of a mantissa
248 * and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3. The
249 * mantissa is often in the range 1.0 <= x < 10.0, but it need not be.
250 * <code>DecimalFormat</code> can be instructed to format and parse scientific
251 * notation <em>only via a pattern</em>; there is currently no factory method
252 * that creates a scientific notation format. In a pattern, the exponent
253 * character immediately followed by one or more digit characters indicates
254 * scientific notation. Example: <code>"0.###E0"</code> formats the number
255 * 1234 as <code>"1.234E3"</code>.
258 * <li>The number of digit characters after the exponent character gives the
259 * minimum exponent digit count. There is no maximum. Negative exponents are
260 * formatted using the localized minus sign, <em>not</em> the prefix and suffix
261 * from the pattern. This allows patterns such as <code>"0.###E0 m/s"</code>.
263 * <li>The minimum and maximum number of integer digits are interpreted
267 * <li>If the maximum number of integer digits is greater than their minimum number
268 * and greater than 1, it forces the exponent to be a multiple of the maximum
269 * number of integer digits, and the minimum number of integer digits to be
270 * interpreted as 1. The most common use of this is to generate
271 * <em>engineering notation</em>, in which the exponent is a multiple of three,
272 * e.g., <code>"##0.#####E0"</code>. Using this pattern, the number 12345
273 * formats to <code>"12.345E3"</code>, and 123456 formats to
274 * <code>"123.456E3"</code>.
276 * <li>Otherwise, the minimum number of integer digits is achieved by adjusting the
277 * exponent. Example: 0.00123 formatted with <code>"00.###E0"</code> yields
278 * <code>"12.3E-4"</code>.
281 * <li>The number of significant digits in the mantissa is the sum of the
282 * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is
283 * unaffected by the maximum integer digits. For example, 12345 formatted with
284 * <code>"##0.##E0"</code> is <code>"12.3E3"</code>. To show all digits, set
285 * the significant digits count to zero. The number of significant digits
286 * does not affect parsing.
288 * <li>Exponential patterns may not contain grouping separators.
293 * <code>DecimalFormat</code> provides rounding modes defined in
294 * {@link java.math.RoundingMode} for formatting. By default, it uses
295 * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
299 * For formatting, <code>DecimalFormat</code> uses the ten consecutive
300 * characters starting with the localized zero digit defined in the
301 * <code>DecimalFormatSymbols</code> object as digits. For parsing, these
302 * digits as well as all Unicode decimal digits, as defined by
303 * {@link Character#digit Character.digit}, are recognized.
305 * <h4>Special Values</h4>
307 * <p><code>NaN</code> is formatted as a string, which typically has a single character
308 * <code>\uFFFD</code>. This string is determined by the
309 * <code>DecimalFormatSymbols</code> object. This is the only value for which
310 * the prefixes and suffixes are not used.
312 * <p>Infinity is formatted as a string, which typically has a single character
313 * <code>\u221E</code>, with the positive or negative prefixes and suffixes
314 * applied. The infinity string is determined by the
315 * <code>DecimalFormatSymbols</code> object.
317 * <p>Negative zero (<code>"-0"</code>) parses to
319 * <li><code>BigDecimal(0)</code> if <code>isParseBigDecimal()</code> is
321 * <li><code>Long(0)</code> if <code>isParseBigDecimal()</code> is false
322 * and <code>isParseIntegerOnly()</code> is true,
323 * <li><code>Double(-0.0)</code> if both <code>isParseBigDecimal()</code>
324 * and <code>isParseIntegerOnly()</code> are false.
327 * <h4><a name="synchronization">Synchronization</a></h4>
330 * Decimal formats are generally not synchronized.
331 * It is recommended to create separate format instances for each thread.
332 * If multiple threads access a format concurrently, it must be synchronized
338 * <strong>// Print out a number using the localized number, integer, currency,
339 * // and percent format for each locale</strong>
340 * Locale[] locales = NumberFormat.getAvailableLocales();
341 * double myNumber = -1234.56;
343 * for (int j=0; j<4; ++j) {
344 * System.out.println("FORMAT");
345 * for (int i = 0; i < locales.length; ++i) {
346 * if (locales[i].getCountry().length() == 0) {
347 * continue; // Skip language-only locales
349 * System.out.print(locales[i].getDisplayName());
352 * form = NumberFormat.getInstance(locales[i]); break;
354 * form = NumberFormat.getIntegerInstance(locales[i]); break;
356 * form = NumberFormat.getCurrencyInstance(locales[i]); break;
358 * form = NumberFormat.getPercentInstance(locales[i]); break;
360 * if (form instanceof DecimalFormat) {
361 * System.out.print(": " + ((DecimalFormat) form).toPattern());
363 * System.out.print(" -> " + form.format(myNumber));
365 * System.out.println(" -> " + form.parse(form.format(myNumber)));
366 * } catch (ParseException e) {}
369 * </pre></blockquote>
371 * @see <a href="http://java.sun.com/docs/books/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a>
373 * @see DecimalFormatSymbols
378 public class DecimalFormat extends NumberFormat {
381 * Creates a DecimalFormat using the default pattern and symbols
382 * for the default locale. This is a convenient way to obtain a
383 * DecimalFormat when internationalization is not the main concern.
385 * To obtain standard formats for a given locale, use the factory methods
386 * on NumberFormat such as getNumberInstance. These factories will
387 * return the most appropriate sub-class of NumberFormat for a given
390 * @see java.text.NumberFormat#getInstance
391 * @see java.text.NumberFormat#getNumberInstance
392 * @see java.text.NumberFormat#getCurrencyInstance
393 * @see java.text.NumberFormat#getPercentInstance
395 public DecimalFormat() {
396 Locale def = Locale.getDefault(Locale.Category.FORMAT);
397 // try to get the pattern from the cache
398 String pattern = cachedLocaleData.get(def);
399 if (pattern == null) { /* cache miss */
400 // Get the pattern for the default locale.
401 ResourceBundle rb = LocaleData.getNumberFormatData(def);
402 String[] all = rb.getStringArray("NumberPatterns");
405 cachedLocaleData.putIfAbsent(def, pattern);
408 // Always applyPattern after the symbols are set
409 this.symbols = new DecimalFormatSymbols(def);
410 applyPattern(pattern, false);
415 * Creates a DecimalFormat using the given pattern and the symbols
416 * for the default locale. This is a convenient way to obtain a
417 * DecimalFormat when internationalization is not the main concern.
419 * To obtain standard formats for a given locale, use the factory methods
420 * on NumberFormat such as getNumberInstance. These factories will
421 * return the most appropriate sub-class of NumberFormat for a given
424 * @param pattern A non-localized pattern string.
425 * @exception NullPointerException if <code>pattern</code> is null
426 * @exception IllegalArgumentException if the given pattern is invalid.
427 * @see java.text.NumberFormat#getInstance
428 * @see java.text.NumberFormat#getNumberInstance
429 * @see java.text.NumberFormat#getCurrencyInstance
430 * @see java.text.NumberFormat#getPercentInstance
432 public DecimalFormat(String pattern) {
433 // Always applyPattern after the symbols are set
434 this.symbols = new DecimalFormatSymbols(Locale.getDefault(Locale.Category.FORMAT));
435 applyPattern(pattern, false);
440 * Creates a DecimalFormat using the given pattern and symbols.
441 * Use this constructor when you need to completely customize the
442 * behavior of the format.
444 * To obtain standard formats for a given
445 * locale, use the factory methods on NumberFormat such as
446 * getInstance or getCurrencyInstance. If you need only minor adjustments
447 * to a standard format, you can modify the format returned by
448 * a NumberFormat factory method.
450 * @param pattern a non-localized pattern string
451 * @param symbols the set of symbols to be used
452 * @exception NullPointerException if any of the given arguments is null
453 * @exception IllegalArgumentException if the given pattern is invalid
454 * @see java.text.NumberFormat#getInstance
455 * @see java.text.NumberFormat#getNumberInstance
456 * @see java.text.NumberFormat#getCurrencyInstance
457 * @see java.text.NumberFormat#getPercentInstance
458 * @see java.text.DecimalFormatSymbols
460 public DecimalFormat (String pattern, DecimalFormatSymbols symbols) {
461 // Always applyPattern after the symbols are set
462 this.symbols = (DecimalFormatSymbols)symbols.clone();
463 applyPattern(pattern, false);
469 * Formats a number and appends the resulting text to the given string
471 * The number can be of any subclass of {@link java.lang.Number}.
473 * This implementation uses the maximum precision permitted.
474 * @param number the number to format
475 * @param toAppendTo the <code>StringBuffer</code> to which the formatted
476 * text is to be appended
477 * @param pos On input: an alignment field, if desired.
478 * On output: the offsets of the alignment field.
479 * @return the value passed in as <code>toAppendTo</code>
480 * @exception IllegalArgumentException if <code>number</code> is
481 * null or not an instance of <code>Number</code>.
482 * @exception NullPointerException if <code>toAppendTo</code> or
483 * <code>pos</code> is null
484 * @exception ArithmeticException if rounding is needed with rounding
485 * mode being set to RoundingMode.UNNECESSARY
486 * @see java.text.FieldPosition
488 public final StringBuffer format(Object number,
489 StringBuffer toAppendTo,
491 if (number instanceof Long || number instanceof Integer ||
492 number instanceof Short || number instanceof Byte ||
493 number instanceof AtomicInteger ||
494 number instanceof AtomicLong ||
495 (number instanceof BigInteger &&
496 ((BigInteger)number).bitLength () < 64)) {
497 return format(((Number)number).longValue(), toAppendTo, pos);
498 } else if (number instanceof BigDecimal) {
499 return format((BigDecimal)number, toAppendTo, pos);
500 } else if (number instanceof BigInteger) {
501 return format((BigInteger)number, toAppendTo, pos);
502 } else if (number instanceof Number) {
503 return format(((Number)number).doubleValue(), toAppendTo, pos);
505 throw new IllegalArgumentException("Cannot format given Object as a Number");
510 * Formats a double to produce a string.
511 * @param number The double to format
512 * @param result where the text is to be appended
513 * @param fieldPosition On input: an alignment field, if desired.
514 * On output: the offsets of the alignment field.
515 * @exception ArithmeticException if rounding is needed with rounding
516 * mode being set to RoundingMode.UNNECESSARY
517 * @return The formatted number string
518 * @see java.text.FieldPosition
520 public StringBuffer format(double number, StringBuffer result,
521 FieldPosition fieldPosition) {
522 fieldPosition.setBeginIndex(0);
523 fieldPosition.setEndIndex(0);
525 return format(number, result, fieldPosition.getFieldDelegate());
529 * Formats a double to produce a string.
530 * @param number The double to format
531 * @param result where the text is to be appended
532 * @param delegate notified of locations of sub fields
533 * @exception ArithmeticException if rounding is needed with rounding
534 * mode being set to RoundingMode.UNNECESSARY
535 * @return The formatted number string
537 private StringBuffer format(double number, StringBuffer result,
538 FieldDelegate delegate) {
539 if (Double.isNaN(number) ||
540 (Double.isInfinite(number) && multiplier == 0)) {
541 int iFieldStart = result.length();
542 result.append(symbols.getNaN());
543 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
544 iFieldStart, result.length(), result);
548 /* Detecting whether a double is negative is easy with the exception of
549 * the value -0.0. This is a double which has a zero mantissa (and
550 * exponent), but a negative sign bit. It is semantically distinct from
551 * a zero with a positive sign bit, and this distinction is important
552 * to certain kinds of computations. However, it's a little tricky to
553 * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0). How then, you may
554 * ask, does it behave distinctly from +0.0? Well, 1/(-0.0) ==
555 * -Infinity. Proper detection of -0.0 is needed to deal with the
556 * issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98.
558 boolean isNegative = ((number < 0.0) || (number == 0.0 && 1/number < 0.0)) ^ (multiplier < 0);
560 if (multiplier != 1) {
561 number *= multiplier;
564 if (Double.isInfinite(number)) {
566 append(result, negativePrefix, delegate,
567 getNegativePrefixFieldPositions(), Field.SIGN);
569 append(result, positivePrefix, delegate,
570 getPositivePrefixFieldPositions(), Field.SIGN);
573 int iFieldStart = result.length();
574 result.append(symbols.getInfinity());
575 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
576 iFieldStart, result.length(), result);
579 append(result, negativeSuffix, delegate,
580 getNegativeSuffixFieldPositions(), Field.SIGN);
582 append(result, positiveSuffix, delegate,
583 getPositiveSuffixFieldPositions(), Field.SIGN);
593 // at this point we are guaranteed a nonnegative finite number.
594 assert(number >= 0 && !Double.isInfinite(number));
596 synchronized(digitList) {
597 int maxIntDigits = super.getMaximumIntegerDigits();
598 int minIntDigits = super.getMinimumIntegerDigits();
599 int maxFraDigits = super.getMaximumFractionDigits();
600 int minFraDigits = super.getMinimumFractionDigits();
602 digitList.set(isNegative, number, useExponentialNotation ?
603 maxIntDigits + maxFraDigits : maxFraDigits,
604 !useExponentialNotation);
605 return subformat(result, delegate, isNegative, false,
606 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
611 * Format a long to produce a string.
612 * @param number The long to format
613 * @param result where the text is to be appended
614 * @param fieldPosition On input: an alignment field, if desired.
615 * On output: the offsets of the alignment field.
616 * @exception ArithmeticException if rounding is needed with rounding
617 * mode being set to RoundingMode.UNNECESSARY
618 * @return The formatted number string
619 * @see java.text.FieldPosition
621 public StringBuffer format(long number, StringBuffer result,
622 FieldPosition fieldPosition) {
623 fieldPosition.setBeginIndex(0);
624 fieldPosition.setEndIndex(0);
626 return format(number, result, fieldPosition.getFieldDelegate());
630 * Format a long to produce a string.
631 * @param number The long to format
632 * @param result where the text is to be appended
633 * @param delegate notified of locations of sub fields
634 * @return The formatted number string
635 * @exception ArithmeticException if rounding is needed with rounding
636 * mode being set to RoundingMode.UNNECESSARY
637 * @see java.text.FieldPosition
639 private StringBuffer format(long number, StringBuffer result,
640 FieldDelegate delegate) {
641 boolean isNegative = (number < 0);
646 // In general, long values always represent real finite numbers, so
647 // we don't have to check for +/- Infinity or NaN. However, there
648 // is one case we have to be careful of: The multiplier can push
649 // a number near MIN_VALUE or MAX_VALUE outside the legal range. We
650 // check for this before multiplying, and if it happens we use
651 // BigInteger instead.
652 boolean useBigInteger = false;
653 if (number < 0) { // This can only happen if number == Long.MIN_VALUE.
654 if (multiplier != 0) {
655 useBigInteger = true;
657 } else if (multiplier != 1 && multiplier != 0) {
658 long cutoff = Long.MAX_VALUE / multiplier;
662 useBigInteger = (number > cutoff);
669 BigInteger bigIntegerValue = BigInteger.valueOf(number);
670 return format(bigIntegerValue, result, delegate, true);
673 number *= multiplier;
677 if (multiplier < 0) {
679 isNegative = !isNegative;
683 synchronized(digitList) {
684 int maxIntDigits = super.getMaximumIntegerDigits();
685 int minIntDigits = super.getMinimumIntegerDigits();
686 int maxFraDigits = super.getMaximumFractionDigits();
687 int minFraDigits = super.getMinimumFractionDigits();
689 digitList.set(isNegative, number,
690 useExponentialNotation ? maxIntDigits + maxFraDigits : 0);
692 return subformat(result, delegate, isNegative, true,
693 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
698 * Formats a BigDecimal to produce a string.
699 * @param number The BigDecimal to format
700 * @param result where the text is to be appended
701 * @param fieldPosition On input: an alignment field, if desired.
702 * On output: the offsets of the alignment field.
703 * @return The formatted number string
704 * @exception ArithmeticException if rounding is needed with rounding
705 * mode being set to RoundingMode.UNNECESSARY
706 * @see java.text.FieldPosition
708 private StringBuffer format(BigDecimal number, StringBuffer result,
709 FieldPosition fieldPosition) {
710 fieldPosition.setBeginIndex(0);
711 fieldPosition.setEndIndex(0);
712 return format(number, result, fieldPosition.getFieldDelegate());
716 * Formats a BigDecimal to produce a string.
717 * @param number The BigDecimal to format
718 * @param result where the text is to be appended
719 * @param delegate notified of locations of sub fields
720 * @exception ArithmeticException if rounding is needed with rounding
721 * mode being set to RoundingMode.UNNECESSARY
722 * @return The formatted number string
724 private StringBuffer format(BigDecimal number, StringBuffer result,
725 FieldDelegate delegate) {
726 if (multiplier != 1) {
727 number = number.multiply(getBigDecimalMultiplier());
729 boolean isNegative = number.signum() == -1;
731 number = number.negate();
734 synchronized(digitList) {
735 int maxIntDigits = getMaximumIntegerDigits();
736 int minIntDigits = getMinimumIntegerDigits();
737 int maxFraDigits = getMaximumFractionDigits();
738 int minFraDigits = getMinimumFractionDigits();
739 int maximumDigits = maxIntDigits + maxFraDigits;
741 digitList.set(isNegative, number, useExponentialNotation ?
742 ((maximumDigits < 0) ? Integer.MAX_VALUE : maximumDigits) :
743 maxFraDigits, !useExponentialNotation);
745 return subformat(result, delegate, isNegative, false,
746 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
751 * Format a BigInteger to produce a string.
752 * @param number The BigInteger to format
753 * @param result where the text is to be appended
754 * @param fieldPosition On input: an alignment field, if desired.
755 * On output: the offsets of the alignment field.
756 * @return The formatted number string
757 * @exception ArithmeticException if rounding is needed with rounding
758 * mode being set to RoundingMode.UNNECESSARY
759 * @see java.text.FieldPosition
761 private StringBuffer format(BigInteger number, StringBuffer result,
762 FieldPosition fieldPosition) {
763 fieldPosition.setBeginIndex(0);
764 fieldPosition.setEndIndex(0);
766 return format(number, result, fieldPosition.getFieldDelegate(), false);
770 * Format a BigInteger to produce a string.
771 * @param number The BigInteger to format
772 * @param result where the text is to be appended
773 * @param delegate notified of locations of sub fields
774 * @return The formatted number string
775 * @exception ArithmeticException if rounding is needed with rounding
776 * mode being set to RoundingMode.UNNECESSARY
777 * @see java.text.FieldPosition
779 private StringBuffer format(BigInteger number, StringBuffer result,
780 FieldDelegate delegate, boolean formatLong) {
781 if (multiplier != 1) {
782 number = number.multiply(getBigIntegerMultiplier());
784 boolean isNegative = number.signum() == -1;
786 number = number.negate();
789 synchronized(digitList) {
790 int maxIntDigits, minIntDigits, maxFraDigits, minFraDigits, maximumDigits;
792 maxIntDigits = super.getMaximumIntegerDigits();
793 minIntDigits = super.getMinimumIntegerDigits();
794 maxFraDigits = super.getMaximumFractionDigits();
795 minFraDigits = super.getMinimumFractionDigits();
796 maximumDigits = maxIntDigits + maxFraDigits;
798 maxIntDigits = getMaximumIntegerDigits();
799 minIntDigits = getMinimumIntegerDigits();
800 maxFraDigits = getMaximumFractionDigits();
801 minFraDigits = getMinimumFractionDigits();
802 maximumDigits = maxIntDigits + maxFraDigits;
803 if (maximumDigits < 0) {
804 maximumDigits = Integer.MAX_VALUE;
808 digitList.set(isNegative, number,
809 useExponentialNotation ? maximumDigits : 0);
811 return subformat(result, delegate, isNegative, true,
812 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
817 * Formats an Object producing an <code>AttributedCharacterIterator</code>.
818 * You can use the returned <code>AttributedCharacterIterator</code>
819 * to build the resulting String, as well as to determine information
820 * about the resulting String.
822 * Each attribute key of the AttributedCharacterIterator will be of type
823 * <code>NumberFormat.Field</code>, with the attribute value being the
824 * same as the attribute key.
826 * @exception NullPointerException if obj is null.
827 * @exception IllegalArgumentException when the Format cannot format the
829 * @exception ArithmeticException if rounding is needed with rounding
830 * mode being set to RoundingMode.UNNECESSARY
831 * @param obj The object to format
832 * @return AttributedCharacterIterator describing the formatted value.
835 public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
836 CharacterIteratorFieldDelegate delegate =
837 new CharacterIteratorFieldDelegate();
838 StringBuffer sb = new StringBuffer();
840 if (obj instanceof Double || obj instanceof Float) {
841 format(((Number)obj).doubleValue(), sb, delegate);
842 } else if (obj instanceof Long || obj instanceof Integer ||
843 obj instanceof Short || obj instanceof Byte ||
844 obj instanceof AtomicInteger || obj instanceof AtomicLong) {
845 format(((Number)obj).longValue(), sb, delegate);
846 } else if (obj instanceof BigDecimal) {
847 format((BigDecimal)obj, sb, delegate);
848 } else if (obj instanceof BigInteger) {
849 format((BigInteger)obj, sb, delegate, false);
850 } else if (obj == null) {
851 throw new NullPointerException(
852 "formatToCharacterIterator must be passed non-null object");
854 throw new IllegalArgumentException(
855 "Cannot format given Object as a Number");
857 return delegate.getIterator(sb.toString());
861 * Complete the formatting of a finite number. On entry, the digitList must
862 * be filled in with the correct digits.
864 private StringBuffer subformat(StringBuffer result, FieldDelegate delegate,
865 boolean isNegative, boolean isInteger,
866 int maxIntDigits, int minIntDigits,
867 int maxFraDigits, int minFraDigits) {
868 // NOTE: This isn't required anymore because DigitList takes care of this.
870 // // The negative of the exponent represents the number of leading
871 // // zeros between the decimal and the first non-zero digit, for
872 // // a value < 0.1 (e.g., for 0.00123, -fExponent == 2). If this
873 // // is more than the maximum fraction digits, then we have an underflow
874 // // for the printed representation. We recognize this here and set
875 // // the DigitList representation to zero in this situation.
877 // if (-digitList.decimalAt >= getMaximumFractionDigits())
879 // digitList.count = 0;
882 char zero = symbols.getZeroDigit();
883 int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
884 char grouping = symbols.getGroupingSeparator();
885 char decimal = isCurrencyFormat ?
886 symbols.getMonetaryDecimalSeparator() :
887 symbols.getDecimalSeparator();
889 /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
890 * format as zero. This allows sensible computations and preserves
891 * relations such as signum(1/x) = signum(x), where x is +Infinity or
892 * -Infinity. Prior to this fix, we always formatted zero values as if
893 * they were positive. Liu 7/6/98.
895 if (digitList.isZero()) {
896 digitList.decimalAt = 0; // Normalize
900 append(result, negativePrefix, delegate,
901 getNegativePrefixFieldPositions(), Field.SIGN);
903 append(result, positivePrefix, delegate,
904 getPositivePrefixFieldPositions(), Field.SIGN);
907 if (useExponentialNotation) {
908 int iFieldStart = result.length();
910 int fFieldStart = -1;
912 // Minimum integer digits are handled in exponential format by
913 // adjusting the exponent. For example, 0.01234 with 3 minimum
914 // integer digits is "123.4E-4".
916 // Maximum integer digits are interpreted as indicating the
917 // repeating range. This is useful for engineering notation, in
918 // which the exponent is restricted to a multiple of 3. For
919 // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
920 // If maximum integer digits are > 1 and are larger than
921 // minimum integer digits, then minimum integer digits are
923 int exponent = digitList.decimalAt;
924 int repeat = maxIntDigits;
925 int minimumIntegerDigits = minIntDigits;
926 if (repeat > 1 && repeat > minIntDigits) {
927 // A repeating range is defined; adjust to it as follows.
928 // If repeat == 3, we have 6,5,4=>3; 3,2,1=>0; 0,-1,-2=>-3;
929 // -3,-4,-5=>-6, etc. This takes into account that the
930 // exponent we have here is off by one from what we expect;
931 // it is for the format 0.MMMMMx10^n.
933 exponent = ((exponent - 1) / repeat) * repeat;
935 // integer division rounds towards 0
936 exponent = ((exponent - repeat) / repeat) * repeat;
938 minimumIntegerDigits = 1;
940 // No repeating range is defined; use minimum integer digits.
941 exponent -= minimumIntegerDigits;
944 // We now output a minimum number of digits, and more if there
945 // are more digits, up to the maximum number of digits. We
946 // place the decimal point after the "integer" digits, which
947 // are the first (decimalAt - exponent) digits.
948 int minimumDigits = minIntDigits + minFraDigits;
949 if (minimumDigits < 0) { // overflow?
950 minimumDigits = Integer.MAX_VALUE;
953 // The number of integer digits is handled specially if the number
954 // is zero, since then there may be no digits.
955 int integerDigits = digitList.isZero() ? minimumIntegerDigits :
956 digitList.decimalAt - exponent;
957 if (minimumDigits < integerDigits) {
958 minimumDigits = integerDigits;
960 int totalDigits = digitList.count;
961 if (minimumDigits > totalDigits) {
962 totalDigits = minimumDigits;
964 boolean addedDecimalSeparator = false;
966 for (int i=0; i<totalDigits; ++i) {
967 if (i == integerDigits) {
968 // Record field information for caller.
969 iFieldEnd = result.length();
971 result.append(decimal);
972 addedDecimalSeparator = true;
974 // Record field information for caller.
975 fFieldStart = result.length();
977 result.append((i < digitList.count) ?
978 (char)(digitList.digits[i] + zeroDelta) :
982 if (decimalSeparatorAlwaysShown && totalDigits == integerDigits) {
983 // Record field information for caller.
984 iFieldEnd = result.length();
986 result.append(decimal);
987 addedDecimalSeparator = true;
989 // Record field information for caller.
990 fFieldStart = result.length();
993 // Record field information
994 if (iFieldEnd == -1) {
995 iFieldEnd = result.length();
997 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
998 iFieldStart, iFieldEnd, result);
999 if (addedDecimalSeparator) {
1000 delegate.formatted(Field.DECIMAL_SEPARATOR,
1001 Field.DECIMAL_SEPARATOR,
1002 iFieldEnd, fFieldStart, result);
1004 if (fFieldStart == -1) {
1005 fFieldStart = result.length();
1007 delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
1008 fFieldStart, result.length(), result);
1010 // The exponent is output using the pattern-specified minimum
1011 // exponent digits. There is no maximum limit to the exponent
1012 // digits, since truncating the exponent would result in an
1013 // unacceptable inaccuracy.
1014 int fieldStart = result.length();
1016 result.append(symbols.getExponentSeparator());
1018 delegate.formatted(Field.EXPONENT_SYMBOL, Field.EXPONENT_SYMBOL,
1019 fieldStart, result.length(), result);
1021 // For zero values, we force the exponent to zero. We
1022 // must do this here, and not earlier, because the value
1023 // is used to determine integer digit count above.
1024 if (digitList.isZero()) {
1028 boolean negativeExponent = exponent < 0;
1029 if (negativeExponent) {
1030 exponent = -exponent;
1031 fieldStart = result.length();
1032 result.append(symbols.getMinusSign());
1033 delegate.formatted(Field.EXPONENT_SIGN, Field.EXPONENT_SIGN,
1034 fieldStart, result.length(), result);
1036 digitList.set(negativeExponent, exponent);
1038 int eFieldStart = result.length();
1040 for (int i=digitList.decimalAt; i<minExponentDigits; ++i) {
1041 result.append(zero);
1043 for (int i=0; i<digitList.decimalAt; ++i) {
1044 result.append((i < digitList.count) ?
1045 (char)(digitList.digits[i] + zeroDelta) : zero);
1047 delegate.formatted(Field.EXPONENT, Field.EXPONENT, eFieldStart,
1048 result.length(), result);
1050 int iFieldStart = result.length();
1052 // Output the integer portion. Here 'count' is the total
1053 // number of integer digits we will display, including both
1054 // leading zeros required to satisfy getMinimumIntegerDigits,
1055 // and actual digits present in the number.
1056 int count = minIntDigits;
1057 int digitIndex = 0; // Index into digitList.fDigits[]
1058 if (digitList.decimalAt > 0 && count < digitList.decimalAt) {
1059 count = digitList.decimalAt;
1062 // Handle the case where getMaximumIntegerDigits() is smaller
1063 // than the real number of integer digits. If this is so, we
1064 // output the least significant max integer digits. For example,
1065 // the value 1997 printed with 2 max integer digits is just "97".
1066 if (count > maxIntDigits) {
1067 count = maxIntDigits;
1068 digitIndex = digitList.decimalAt - count;
1071 int sizeBeforeIntegerPart = result.length();
1072 for (int i=count-1; i>=0; --i) {
1073 if (i < digitList.decimalAt && digitIndex < digitList.count) {
1074 // Output a real digit
1075 result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
1077 // Output a leading zero
1078 result.append(zero);
1081 // Output grouping separator if necessary. Don't output a
1082 // grouping separator if i==0 though; that's at the end of
1083 // the integer part.
1084 if (isGroupingUsed() && i>0 && (groupingSize != 0) &&
1085 (i % groupingSize == 0)) {
1086 int gStart = result.length();
1087 result.append(grouping);
1088 delegate.formatted(Field.GROUPING_SEPARATOR,
1089 Field.GROUPING_SEPARATOR, gStart,
1090 result.length(), result);
1094 // Determine whether or not there are any printable fractional
1095 // digits. If we've used up the digits we know there aren't.
1096 boolean fractionPresent = (minFraDigits > 0) ||
1097 (!isInteger && digitIndex < digitList.count);
1099 // If there is no fraction present, and we haven't printed any
1100 // integer digits, then print a zero. Otherwise we won't print
1101 // _any_ digits, and we won't be able to parse this string.
1102 if (!fractionPresent && result.length() == sizeBeforeIntegerPart) {
1103 result.append(zero);
1106 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
1107 iFieldStart, result.length(), result);
1109 // Output the decimal separator if we always do so.
1110 int sStart = result.length();
1111 if (decimalSeparatorAlwaysShown || fractionPresent) {
1112 result.append(decimal);
1115 if (sStart != result.length()) {
1116 delegate.formatted(Field.DECIMAL_SEPARATOR,
1117 Field.DECIMAL_SEPARATOR,
1118 sStart, result.length(), result);
1120 int fFieldStart = result.length();
1122 for (int i=0; i < maxFraDigits; ++i) {
1123 // Here is where we escape from the loop. We escape if we've
1124 // output the maximum fraction digits (specified in the for
1125 // expression above).
1126 // We also stop when we've output the minimum digits and either:
1127 // we have an integer, so there is no fractional stuff to
1128 // display, or we're out of significant digits.
1129 if (i >= minFraDigits &&
1130 (isInteger || digitIndex >= digitList.count)) {
1134 // Output leading fractional zeros. These are zeros that come
1135 // after the decimal but before any significant digits. These
1136 // are only output if abs(number being formatted) < 1.0.
1137 if (-1-i > (digitList.decimalAt-1)) {
1138 result.append(zero);
1142 // Output a digit, if we have any precision left, or a
1143 // zero if we don't. We don't want to output noise digits.
1144 if (!isInteger && digitIndex < digitList.count) {
1145 result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
1147 result.append(zero);
1151 // Record field information for caller.
1152 delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
1153 fFieldStart, result.length(), result);
1157 append(result, negativeSuffix, delegate,
1158 getNegativeSuffixFieldPositions(), Field.SIGN);
1161 append(result, positiveSuffix, delegate,
1162 getPositiveSuffixFieldPositions(), Field.SIGN);
1169 * Appends the String <code>string</code> to <code>result</code>.
1170 * <code>delegate</code> is notified of all the
1171 * <code>FieldPosition</code>s in <code>positions</code>.
1173 * If one of the <code>FieldPosition</code>s in <code>positions</code>
1174 * identifies a <code>SIGN</code> attribute, it is mapped to
1175 * <code>signAttribute</code>. This is used
1176 * to map the <code>SIGN</code> attribute to the <code>EXPONENT</code>
1177 * attribute as necessary.
1179 * This is used by <code>subformat</code> to add the prefix/suffix.
1181 private void append(StringBuffer result, String string,
1182 FieldDelegate delegate,
1183 FieldPosition[] positions,
1184 Format.Field signAttribute) {
1185 int start = result.length();
1187 if (string.length() > 0) {
1188 result.append(string);
1189 for (int counter = 0, max = positions.length; counter < max;
1191 FieldPosition fp = positions[counter];
1192 Format.Field attribute = fp.getFieldAttribute();
1194 if (attribute == Field.SIGN) {
1195 attribute = signAttribute;
1197 delegate.formatted(attribute, attribute,
1198 start + fp.getBeginIndex(),
1199 start + fp.getEndIndex(), result);
1205 * Parses text from a string to produce a <code>Number</code>.
1207 * The method attempts to parse text starting at the index given by
1209 * If parsing succeeds, then the index of <code>pos</code> is updated
1210 * to the index after the last character used (parsing does not necessarily
1211 * use all characters up to the end of the string), and the parsed
1212 * number is returned. The updated <code>pos</code> can be used to
1213 * indicate the starting point for the next call to this method.
1214 * If an error occurs, then the index of <code>pos</code> is not
1215 * changed, the error index of <code>pos</code> is set to the index of
1216 * the character where the error occurred, and null is returned.
1218 * The subclass returned depends on the value of {@link #isParseBigDecimal}
1219 * as well as on the string being parsed.
1221 * <li>If <code>isParseBigDecimal()</code> is false (the default),
1222 * most integer values are returned as <code>Long</code>
1223 * objects, no matter how they are written: <code>"17"</code> and
1224 * <code>"17.000"</code> both parse to <code>Long(17)</code>.
1225 * Values that cannot fit into a <code>Long</code> are returned as
1226 * <code>Double</code>s. This includes values with a fractional part,
1227 * infinite values, <code>NaN</code>, and the value -0.0.
1228 * <code>DecimalFormat</code> does <em>not</em> decide whether to
1229 * return a <code>Double</code> or a <code>Long</code> based on the
1230 * presence of a decimal separator in the source string. Doing so
1231 * would prevent integers that overflow the mantissa of a double,
1232 * such as <code>"-9,223,372,036,854,775,808.00"</code>, from being
1233 * parsed accurately.
1235 * Callers may use the <code>Number</code> methods
1236 * <code>doubleValue</code>, <code>longValue</code>, etc., to obtain
1237 * the type they want.
1238 * <li>If <code>isParseBigDecimal()</code> is true, values are returned
1239 * as <code>BigDecimal</code> objects. The values are the ones
1240 * constructed by {@link java.math.BigDecimal#BigDecimal(String)}
1241 * for corresponding strings in locale-independent format. The
1242 * special cases negative and positive infinity and NaN are returned
1243 * as <code>Double</code> instances holding the values of the
1244 * corresponding <code>Double</code> constants.
1247 * <code>DecimalFormat</code> parses all Unicode characters that represent
1248 * decimal digits, as defined by <code>Character.digit()</code>. In
1249 * addition, <code>DecimalFormat</code> also recognizes as digits the ten
1250 * consecutive characters starting with the localized zero digit defined in
1251 * the <code>DecimalFormatSymbols</code> object.
1253 * @param text the string to be parsed
1254 * @param pos A <code>ParsePosition</code> object with index and error
1255 * index information as described above.
1256 * @return the parsed value, or <code>null</code> if the parse fails
1257 * @exception NullPointerException if <code>text</code> or
1258 * <code>pos</code> is null.
1260 public Number parse(String text, ParsePosition pos) {
1262 if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) {
1263 pos.index = pos.index + symbols.getNaN().length();
1264 return new Double(Double.NaN);
1267 boolean[] status = new boolean[STATUS_LENGTH];
1268 if (!subparse(text, pos, positivePrefix, negativePrefix, digitList, false, status)) {
1272 // special case INFINITY
1273 if (status[STATUS_INFINITE]) {
1274 if (status[STATUS_POSITIVE] == (multiplier >= 0)) {
1275 return new Double(Double.POSITIVE_INFINITY);
1277 return new Double(Double.NEGATIVE_INFINITY);
1281 if (multiplier == 0) {
1282 if (digitList.isZero()) {
1283 return new Double(Double.NaN);
1284 } else if (status[STATUS_POSITIVE]) {
1285 return new Double(Double.POSITIVE_INFINITY);
1287 return new Double(Double.NEGATIVE_INFINITY);
1291 if (isParseBigDecimal()) {
1292 BigDecimal bigDecimalResult = digitList.getBigDecimal();
1294 if (multiplier != 1) {
1296 bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier());
1298 catch (ArithmeticException e) { // non-terminating decimal expansion
1299 bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier(), roundingMode);
1303 if (!status[STATUS_POSITIVE]) {
1304 bigDecimalResult = bigDecimalResult.negate();
1306 return bigDecimalResult;
1308 boolean gotDouble = true;
1309 boolean gotLongMinimum = false;
1310 double doubleResult = 0.0;
1311 long longResult = 0;
1313 // Finally, have DigitList parse the digits into a value.
1314 if (digitList.fitsIntoLong(status[STATUS_POSITIVE], isParseIntegerOnly())) {
1316 longResult = digitList.getLong();
1317 if (longResult < 0) { // got Long.MIN_VALUE
1318 gotLongMinimum = true;
1321 doubleResult = digitList.getDouble();
1324 // Divide by multiplier. We have to be careful here not to do
1325 // unneeded conversions between double and long.
1326 if (multiplier != 1) {
1328 doubleResult /= multiplier;
1330 // Avoid converting to double if we can
1331 if (longResult % multiplier == 0) {
1332 longResult /= multiplier;
1334 doubleResult = ((double)longResult) / multiplier;
1340 if (!status[STATUS_POSITIVE] && !gotLongMinimum) {
1341 doubleResult = -doubleResult;
1342 longResult = -longResult;
1345 // At this point, if we divided the result by the multiplier, the
1346 // result may fit into a long. We check for this case and return
1347 // a long if possible.
1348 // We must do this AFTER applying the negative (if appropriate)
1349 // in order to handle the case of LONG_MIN; otherwise, if we do
1350 // this with a positive value -LONG_MIN, the double is > 0, but
1351 // the long is < 0. We also must retain a double in the case of
1352 // -0.0, which will compare as == to a long 0 cast to a double
1354 if (multiplier != 1 && gotDouble) {
1355 longResult = (long)doubleResult;
1356 gotDouble = ((doubleResult != (double)longResult) ||
1357 (doubleResult == 0.0 && 1/doubleResult < 0.0)) &&
1358 !isParseIntegerOnly();
1362 (Number)new Double(doubleResult) : (Number)new Long(longResult);
1367 * Return a BigInteger multiplier.
1369 private BigInteger getBigIntegerMultiplier() {
1370 if (bigIntegerMultiplier == null) {
1371 bigIntegerMultiplier = BigInteger.valueOf(multiplier);
1373 return bigIntegerMultiplier;
1375 private transient BigInteger bigIntegerMultiplier;
1378 * Return a BigDecimal multiplier.
1380 private BigDecimal getBigDecimalMultiplier() {
1381 if (bigDecimalMultiplier == null) {
1382 bigDecimalMultiplier = new BigDecimal(multiplier);
1384 return bigDecimalMultiplier;
1386 private transient BigDecimal bigDecimalMultiplier;
1388 private static final int STATUS_INFINITE = 0;
1389 private static final int STATUS_POSITIVE = 1;
1390 private static final int STATUS_LENGTH = 2;
1393 * Parse the given text into a number. The text is parsed beginning at
1394 * parsePosition, until an unparseable character is seen.
1395 * @param text The string to parse.
1396 * @param parsePosition The position at which to being parsing. Upon
1397 * return, the first unparseable character.
1398 * @param digits The DigitList to set to the parsed value.
1399 * @param isExponent If true, parse an exponent. This means no
1400 * infinite values and integer only.
1401 * @param status Upon return contains boolean status flags indicating
1402 * whether the value was infinite and whether it was positive.
1404 private final boolean subparse(String text, ParsePosition parsePosition,
1405 String positivePrefix, String negativePrefix,
1406 DigitList digits, boolean isExponent,
1408 int position = parsePosition.index;
1409 int oldStart = parsePosition.index;
1411 boolean gotPositive, gotNegative;
1413 // check for positivePrefix; take longest
1414 gotPositive = text.regionMatches(position, positivePrefix, 0,
1415 positivePrefix.length());
1416 gotNegative = text.regionMatches(position, negativePrefix, 0,
1417 negativePrefix.length());
1419 if (gotPositive && gotNegative) {
1420 if (positivePrefix.length() > negativePrefix.length()) {
1421 gotNegative = false;
1422 } else if (positivePrefix.length() < negativePrefix.length()) {
1423 gotPositive = false;
1428 position += positivePrefix.length();
1429 } else if (gotNegative) {
1430 position += negativePrefix.length();
1432 parsePosition.errorIndex = position;
1436 // process digits or Inf, find decimal position
1437 status[STATUS_INFINITE] = false;
1438 if (!isExponent && text.regionMatches(position,symbols.getInfinity(),0,
1439 symbols.getInfinity().length())) {
1440 position += symbols.getInfinity().length();
1441 status[STATUS_INFINITE] = true;
1443 // We now have a string of digits, possibly with grouping symbols,
1444 // and decimal points. We want to process these into a DigitList.
1445 // We don't want to put a bunch of leading zeros into the DigitList
1446 // though, so we keep track of the location of the decimal point,
1447 // put only significant digits into the DigitList, and adjust the
1448 // exponent as needed.
1450 digits.decimalAt = digits.count = 0;
1451 char zero = symbols.getZeroDigit();
1452 char decimal = isCurrencyFormat ?
1453 symbols.getMonetaryDecimalSeparator() :
1454 symbols.getDecimalSeparator();
1455 char grouping = symbols.getGroupingSeparator();
1456 String exponentString = symbols.getExponentSeparator();
1457 boolean sawDecimal = false;
1458 boolean sawExponent = false;
1459 boolean sawDigit = false;
1460 int exponent = 0; // Set to the exponent value, if any
1462 // We have to track digitCount ourselves, because digits.count will
1463 // pin when the maximum allowable digits is reached.
1467 for (; position < text.length(); ++position) {
1468 char ch = text.charAt(position);
1470 /* We recognize all digit ranges, not only the Latin digit range
1471 * '0'..'9'. We do so by using the Character.digit() method,
1472 * which converts a valid Unicode digit to the range 0..9.
1474 * The character 'ch' may be a digit. If so, place its value
1475 * from 0 to 9 in 'digit'. First try using the locale digit,
1476 * which may or MAY NOT be a standard Unicode digit range. If
1477 * this fails, try using the standard Unicode digit ranges by
1478 * calling Character.digit(). If this also fails, digit will
1479 * have a value outside the range 0..9.
1481 int digit = ch - zero;
1482 if (digit < 0 || digit > 9) {
1483 digit = Character.digit(ch, 10);
1487 // Cancel out backup setting (see grouping handler below)
1488 backup = -1; // Do this BEFORE continue statement below!!!
1491 // Handle leading zeros
1492 if (digits.count == 0) {
1493 // Ignore leading zeros in integer part of number.
1498 // If we have seen the decimal, but no significant
1499 // digits yet, then we account for leading zeros by
1500 // decrementing the digits.decimalAt into negative
1505 digits.append((char)(digit + '0'));
1507 } else if (digit > 0 && digit <= 9) { // [sic] digit==0 handled above
1510 digits.append((char)(digit + '0'));
1512 // Cancel out backup setting (see grouping handler below)
1514 } else if (!isExponent && ch == decimal) {
1515 // If we're only parsing integers, or if we ALREADY saw the
1516 // decimal, then don't parse this one.
1517 if (isParseIntegerOnly() || sawDecimal) {
1520 digits.decimalAt = digitCount; // Not digits.count!
1522 } else if (!isExponent && ch == grouping && isGroupingUsed()) {
1526 // Ignore grouping characters, if we are using them, but
1527 // require that they be followed by a digit. Otherwise
1528 // we backup and reprocess them.
1530 } else if (!isExponent && text.regionMatches(position, exponentString, 0, exponentString.length())
1532 // Process the exponent by recursively calling this method.
1533 ParsePosition pos = new ParsePosition(position + exponentString.length());
1534 boolean[] stat = new boolean[STATUS_LENGTH];
1535 DigitList exponentDigits = new DigitList();
1537 if (subparse(text, pos, "", Character.toString(symbols.getMinusSign()), exponentDigits, true, stat) &&
1538 exponentDigits.fitsIntoLong(stat[STATUS_POSITIVE], true)) {
1539 position = pos.index; // Advance past the exponent
1540 exponent = (int)exponentDigits.getLong();
1541 if (!stat[STATUS_POSITIVE]) {
1542 exponent = -exponent;
1546 break; // Whether we fail or succeed, we exit this loop
1557 // If there was no decimal point we have an integer
1559 digits.decimalAt = digitCount; // Not digits.count!
1562 // Adjust for exponent, if any
1563 digits.decimalAt += exponent;
1565 // If none of the text string was recognized. For example, parse
1566 // "x" with pattern "#0.00" (return index and error index both 0)
1567 // parse "$" with pattern "$#0.00". (return index 0 and error
1569 if (!sawDigit && digitCount == 0) {
1570 parsePosition.index = oldStart;
1571 parsePosition.errorIndex = oldStart;
1579 gotPositive = text.regionMatches(position,positiveSuffix,0,
1580 positiveSuffix.length());
1583 gotNegative = text.regionMatches(position,negativeSuffix,0,
1584 negativeSuffix.length());
1587 // if both match, take longest
1588 if (gotPositive && gotNegative) {
1589 if (positiveSuffix.length() > negativeSuffix.length()) {
1590 gotNegative = false;
1591 } else if (positiveSuffix.length() < negativeSuffix.length()) {
1592 gotPositive = false;
1596 // fail if neither or both
1597 if (gotPositive == gotNegative) {
1598 parsePosition.errorIndex = position;
1602 parsePosition.index = position +
1603 (gotPositive ? positiveSuffix.length() : negativeSuffix.length()); // mark success!
1605 parsePosition.index = position;
1608 status[STATUS_POSITIVE] = gotPositive;
1609 if (parsePosition.index == oldStart) {
1610 parsePosition.errorIndex = position;
1617 * Returns a copy of the decimal format symbols, which is generally not
1618 * changed by the programmer or user.
1619 * @return a copy of the desired DecimalFormatSymbols
1620 * @see java.text.DecimalFormatSymbols
1622 public DecimalFormatSymbols getDecimalFormatSymbols() {
1624 // don't allow multiple references
1625 return (DecimalFormatSymbols) symbols.clone();
1626 } catch (Exception foo) {
1627 return null; // should never happen
1633 * Sets the decimal format symbols, which is generally not changed
1634 * by the programmer or user.
1635 * @param newSymbols desired DecimalFormatSymbols
1636 * @see java.text.DecimalFormatSymbols
1638 public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
1640 // don't allow multiple references
1641 symbols = (DecimalFormatSymbols) newSymbols.clone();
1643 } catch (Exception foo) {
1644 // should never happen
1649 * Get the positive prefix.
1650 * <P>Examples: +123, $123, sFr123
1652 public String getPositivePrefix () {
1653 return positivePrefix;
1657 * Set the positive prefix.
1658 * <P>Examples: +123, $123, sFr123
1660 public void setPositivePrefix (String newValue) {
1661 positivePrefix = newValue;
1662 posPrefixPattern = null;
1663 positivePrefixFieldPositions = null;
1667 * Returns the FieldPositions of the fields in the prefix used for
1668 * positive numbers. This is not used if the user has explicitly set
1669 * a positive prefix via <code>setPositivePrefix</code>. This is
1672 * @return FieldPositions in positive prefix
1674 private FieldPosition[] getPositivePrefixFieldPositions() {
1675 if (positivePrefixFieldPositions == null) {
1676 if (posPrefixPattern != null) {
1677 positivePrefixFieldPositions = expandAffix(posPrefixPattern);
1680 positivePrefixFieldPositions = EmptyFieldPositionArray;
1683 return positivePrefixFieldPositions;
1687 * Get the negative prefix.
1688 * <P>Examples: -123, ($123) (with negative suffix), sFr-123
1690 public String getNegativePrefix () {
1691 return negativePrefix;
1695 * Set the negative prefix.
1696 * <P>Examples: -123, ($123) (with negative suffix), sFr-123
1698 public void setNegativePrefix (String newValue) {
1699 negativePrefix = newValue;
1700 negPrefixPattern = null;
1704 * Returns the FieldPositions of the fields in the prefix used for
1705 * negative numbers. This is not used if the user has explicitly set
1706 * a negative prefix via <code>setNegativePrefix</code>. This is
1709 * @return FieldPositions in positive prefix
1711 private FieldPosition[] getNegativePrefixFieldPositions() {
1712 if (negativePrefixFieldPositions == null) {
1713 if (negPrefixPattern != null) {
1714 negativePrefixFieldPositions = expandAffix(negPrefixPattern);
1717 negativePrefixFieldPositions = EmptyFieldPositionArray;
1720 return negativePrefixFieldPositions;
1724 * Get the positive suffix.
1727 public String getPositiveSuffix () {
1728 return positiveSuffix;
1732 * Set the positive suffix.
1735 public void setPositiveSuffix (String newValue) {
1736 positiveSuffix = newValue;
1737 posSuffixPattern = null;
1741 * Returns the FieldPositions of the fields in the suffix used for
1742 * positive numbers. This is not used if the user has explicitly set
1743 * a positive suffix via <code>setPositiveSuffix</code>. This is
1746 * @return FieldPositions in positive prefix
1748 private FieldPosition[] getPositiveSuffixFieldPositions() {
1749 if (positiveSuffixFieldPositions == null) {
1750 if (posSuffixPattern != null) {
1751 positiveSuffixFieldPositions = expandAffix(posSuffixPattern);
1754 positiveSuffixFieldPositions = EmptyFieldPositionArray;
1757 return positiveSuffixFieldPositions;
1761 * Get the negative suffix.
1762 * <P>Examples: -123%, ($123) (with positive suffixes)
1764 public String getNegativeSuffix () {
1765 return negativeSuffix;
1769 * Set the negative suffix.
1772 public void setNegativeSuffix (String newValue) {
1773 negativeSuffix = newValue;
1774 negSuffixPattern = null;
1778 * Returns the FieldPositions of the fields in the suffix used for
1779 * negative numbers. This is not used if the user has explicitly set
1780 * a negative suffix via <code>setNegativeSuffix</code>. This is
1783 * @return FieldPositions in positive prefix
1785 private FieldPosition[] getNegativeSuffixFieldPositions() {
1786 if (negativeSuffixFieldPositions == null) {
1787 if (negSuffixPattern != null) {
1788 negativeSuffixFieldPositions = expandAffix(negSuffixPattern);
1791 negativeSuffixFieldPositions = EmptyFieldPositionArray;
1794 return negativeSuffixFieldPositions;
1798 * Gets the multiplier for use in percent, per mille, and similar
1801 * @see #setMultiplier(int)
1803 public int getMultiplier () {
1808 * Sets the multiplier for use in percent, per mille, and similar
1810 * For a percent format, set the multiplier to 100 and the suffixes to
1811 * have '%' (for Arabic, use the Arabic percent sign).
1812 * For a per mille format, set the multiplier to 1000 and the suffixes to
1813 * have '\u2030'.
1815 * <P>Example: with multiplier 100, 1.23 is formatted as "123", and
1816 * "123" is parsed into 1.23.
1818 * @see #getMultiplier
1820 public void setMultiplier (int newValue) {
1821 multiplier = newValue;
1822 bigDecimalMultiplier = null;
1823 bigIntegerMultiplier = null;
1827 * Return the grouping size. Grouping size is the number of digits between
1828 * grouping separators in the integer portion of a number. For example,
1829 * in the number "123,456.78", the grouping size is 3.
1830 * @see #setGroupingSize
1831 * @see java.text.NumberFormat#isGroupingUsed
1832 * @see java.text.DecimalFormatSymbols#getGroupingSeparator
1834 public int getGroupingSize () {
1835 return groupingSize;
1839 * Set the grouping size. Grouping size is the number of digits between
1840 * grouping separators in the integer portion of a number. For example,
1841 * in the number "123,456.78", the grouping size is 3.
1843 * The value passed in is converted to a byte, which may lose information.
1844 * @see #getGroupingSize
1845 * @see java.text.NumberFormat#setGroupingUsed
1846 * @see java.text.DecimalFormatSymbols#setGroupingSeparator
1848 public void setGroupingSize (int newValue) {
1849 groupingSize = (byte)newValue;
1853 * Allows you to get the behavior of the decimal separator with integers.
1854 * (The decimal separator will always appear with decimals.)
1855 * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
1857 public boolean isDecimalSeparatorAlwaysShown() {
1858 return decimalSeparatorAlwaysShown;
1862 * Allows you to set the behavior of the decimal separator with integers.
1863 * (The decimal separator will always appear with decimals.)
1864 * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
1866 public void setDecimalSeparatorAlwaysShown(boolean newValue) {
1867 decimalSeparatorAlwaysShown = newValue;
1871 * Returns whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1872 * method returns <code>BigDecimal</code>. The default value is false.
1873 * @see #setParseBigDecimal
1876 public boolean isParseBigDecimal() {
1877 return parseBigDecimal;
1881 * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1882 * method returns <code>BigDecimal</code>.
1883 * @see #isParseBigDecimal
1886 public void setParseBigDecimal(boolean newValue) {
1887 parseBigDecimal = newValue;
1891 * Standard override; no change in semantics.
1893 public Object clone() {
1895 DecimalFormat other = (DecimalFormat) super.clone();
1896 other.symbols = (DecimalFormatSymbols) symbols.clone();
1897 other.digitList = (DigitList) digitList.clone();
1899 } catch (Exception e) {
1900 throw new InternalError();
1907 public boolean equals(Object obj)
1909 if (obj == null) return false;
1910 if (!super.equals(obj)) return false; // super does class check
1911 DecimalFormat other = (DecimalFormat) obj;
1912 return ((posPrefixPattern == other.posPrefixPattern &&
1913 positivePrefix.equals(other.positivePrefix))
1914 || (posPrefixPattern != null &&
1915 posPrefixPattern.equals(other.posPrefixPattern)))
1916 && ((posSuffixPattern == other.posSuffixPattern &&
1917 positiveSuffix.equals(other.positiveSuffix))
1918 || (posSuffixPattern != null &&
1919 posSuffixPattern.equals(other.posSuffixPattern)))
1920 && ((negPrefixPattern == other.negPrefixPattern &&
1921 negativePrefix.equals(other.negativePrefix))
1922 || (negPrefixPattern != null &&
1923 negPrefixPattern.equals(other.negPrefixPattern)))
1924 && ((negSuffixPattern == other.negSuffixPattern &&
1925 negativeSuffix.equals(other.negativeSuffix))
1926 || (negSuffixPattern != null &&
1927 negSuffixPattern.equals(other.negSuffixPattern)))
1928 && multiplier == other.multiplier
1929 && groupingSize == other.groupingSize
1930 && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown
1931 && parseBigDecimal == other.parseBigDecimal
1932 && useExponentialNotation == other.useExponentialNotation
1933 && (!useExponentialNotation ||
1934 minExponentDigits == other.minExponentDigits)
1935 && maximumIntegerDigits == other.maximumIntegerDigits
1936 && minimumIntegerDigits == other.minimumIntegerDigits
1937 && maximumFractionDigits == other.maximumFractionDigits
1938 && minimumFractionDigits == other.minimumFractionDigits
1939 && roundingMode == other.roundingMode
1940 && symbols.equals(other.symbols);
1944 * Overrides hashCode
1946 public int hashCode() {
1947 return super.hashCode() * 37 + positivePrefix.hashCode();
1948 // just enough fields for a reasonable distribution
1952 * Synthesizes a pattern string that represents the current state
1953 * of this Format object.
1954 * @see #applyPattern
1956 public String toPattern() {
1957 return toPattern( false );
1961 * Synthesizes a localized pattern string that represents the current
1962 * state of this Format object.
1963 * @see #applyPattern
1965 public String toLocalizedPattern() {
1966 return toPattern( true );
1970 * Expand the affix pattern strings into the expanded affix strings. If any
1971 * affix pattern string is null, do not expand it. This method should be
1972 * called any time the symbols or the affix patterns change in order to keep
1973 * the expanded affix strings up to date.
1975 private void expandAffixes() {
1976 // Reuse one StringBuffer for better performance
1977 StringBuffer buffer = new StringBuffer();
1978 if (posPrefixPattern != null) {
1979 positivePrefix = expandAffix(posPrefixPattern, buffer);
1980 positivePrefixFieldPositions = null;
1982 if (posSuffixPattern != null) {
1983 positiveSuffix = expandAffix(posSuffixPattern, buffer);
1984 positiveSuffixFieldPositions = null;
1986 if (negPrefixPattern != null) {
1987 negativePrefix = expandAffix(negPrefixPattern, buffer);
1988 negativePrefixFieldPositions = null;
1990 if (negSuffixPattern != null) {
1991 negativeSuffix = expandAffix(negSuffixPattern, buffer);
1992 negativeSuffixFieldPositions = null;
1997 * Expand an affix pattern into an affix string. All characters in the
1998 * pattern are literal unless prefixed by QUOTE. The following characters
1999 * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2000 * PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE +
2001 * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
2002 * currency code. Any other character after a QUOTE represents itself.
2003 * QUOTE must be followed by another character; QUOTE may not occur by
2004 * itself at the end of the pattern.
2006 * @param pattern the non-null, possibly empty pattern
2007 * @param buffer a scratch StringBuffer; its contents will be lost
2008 * @return the expanded equivalent of pattern
2010 private String expandAffix(String pattern, StringBuffer buffer) {
2011 buffer.setLength(0);
2012 for (int i=0; i<pattern.length(); ) {
2013 char c = pattern.charAt(i++);
2015 c = pattern.charAt(i++);
2018 if (i<pattern.length() &&
2019 pattern.charAt(i) == CURRENCY_SIGN) {
2021 buffer.append(symbols.getInternationalCurrencySymbol());
2023 buffer.append(symbols.getCurrencySymbol());
2026 case PATTERN_PERCENT:
2027 c = symbols.getPercent();
2029 case PATTERN_PER_MILLE:
2030 c = symbols.getPerMill();
2033 c = symbols.getMinusSign();
2039 return buffer.toString();
2043 * Expand an affix pattern into an array of FieldPositions describing
2044 * how the pattern would be expanded.
2045 * All characters in the
2046 * pattern are literal unless prefixed by QUOTE. The following characters
2047 * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2048 * PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE +
2049 * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
2050 * currency code. Any other character after a QUOTE represents itself.
2051 * QUOTE must be followed by another character; QUOTE may not occur by
2052 * itself at the end of the pattern.
2054 * @param pattern the non-null, possibly empty pattern
2055 * @return FieldPosition array of the resulting fields.
2057 private FieldPosition[] expandAffix(String pattern) {
2058 ArrayList positions = null;
2059 int stringIndex = 0;
2060 for (int i=0; i<pattern.length(); ) {
2061 char c = pattern.charAt(i++);
2064 Format.Field fieldID = null;
2065 c = pattern.charAt(i++);
2069 if (i<pattern.length() &&
2070 pattern.charAt(i) == CURRENCY_SIGN) {
2072 string = symbols.getInternationalCurrencySymbol();
2074 string = symbols.getCurrencySymbol();
2076 if (string.length() > 0) {
2077 if (positions == null) {
2078 positions = new ArrayList(2);
2080 FieldPosition fp = new FieldPosition(Field.CURRENCY);
2081 fp.setBeginIndex(stringIndex);
2082 fp.setEndIndex(stringIndex + string.length());
2084 stringIndex += string.length();
2087 case PATTERN_PERCENT:
2088 c = symbols.getPercent();
2090 fieldID = Field.PERCENT;
2092 case PATTERN_PER_MILLE:
2093 c = symbols.getPerMill();
2095 fieldID = Field.PERMILLE;
2098 c = symbols.getMinusSign();
2100 fieldID = Field.SIGN;
2103 if (fieldID != null) {
2104 if (positions == null) {
2105 positions = new ArrayList(2);
2107 FieldPosition fp = new FieldPosition(fieldID, field);
2108 fp.setBeginIndex(stringIndex);
2109 fp.setEndIndex(stringIndex + 1);
2115 if (positions != null) {
2116 return (FieldPosition[])positions.toArray(EmptyFieldPositionArray);
2118 return EmptyFieldPositionArray;
2122 * Appends an affix pattern to the given StringBuffer, quoting special
2123 * characters as needed. Uses the internal affix pattern, if that exists,
2124 * or the literal affix, if the internal affix pattern is null. The
2125 * appended string will generate the same affix pattern (or literal affix)
2126 * when passed to toPattern().
2128 * @param buffer the affix string is appended to this
2129 * @param affixPattern a pattern such as posPrefixPattern; may be null
2130 * @param expAffix a corresponding expanded affix, such as positivePrefix.
2131 * Ignored unless affixPattern is null. If affixPattern is null, then
2132 * expAffix is appended as a literal affix.
2133 * @param localized true if the appended pattern should contain localized
2134 * pattern characters; otherwise, non-localized pattern chars are appended
2136 private void appendAffix(StringBuffer buffer, String affixPattern,
2137 String expAffix, boolean localized) {
2138 if (affixPattern == null) {
2139 appendAffix(buffer, expAffix, localized);
2142 for (int pos=0; pos<affixPattern.length(); pos=i) {
2143 i = affixPattern.indexOf(QUOTE, pos);
2145 appendAffix(buffer, affixPattern.substring(pos), localized);
2149 appendAffix(buffer, affixPattern.substring(pos, i), localized);
2151 char c = affixPattern.charAt(++i);
2155 // Fall through and append another QUOTE below
2156 } else if (c == CURRENCY_SIGN &&
2157 i<affixPattern.length() &&
2158 affixPattern.charAt(i) == CURRENCY_SIGN) {
2161 // Fall through and append another CURRENCY_SIGN below
2162 } else if (localized) {
2164 case PATTERN_PERCENT:
2165 c = symbols.getPercent();
2167 case PATTERN_PER_MILLE:
2168 c = symbols.getPerMill();
2171 c = symbols.getMinusSign();
2181 * Append an affix to the given StringBuffer, using quotes if
2182 * there are special characters. Single quotes themselves must be
2183 * escaped in either case.
2185 private void appendAffix(StringBuffer buffer, String affix, boolean localized) {
2188 needQuote = affix.indexOf(symbols.getZeroDigit()) >= 0
2189 || affix.indexOf(symbols.getGroupingSeparator()) >= 0
2190 || affix.indexOf(symbols.getDecimalSeparator()) >= 0
2191 || affix.indexOf(symbols.getPercent()) >= 0
2192 || affix.indexOf(symbols.getPerMill()) >= 0
2193 || affix.indexOf(symbols.getDigit()) >= 0
2194 || affix.indexOf(symbols.getPatternSeparator()) >= 0
2195 || affix.indexOf(symbols.getMinusSign()) >= 0
2196 || affix.indexOf(CURRENCY_SIGN) >= 0;
2199 needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 0
2200 || affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 0
2201 || affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 0
2202 || affix.indexOf(PATTERN_PERCENT) >= 0
2203 || affix.indexOf(PATTERN_PER_MILLE) >= 0
2204 || affix.indexOf(PATTERN_DIGIT) >= 0
2205 || affix.indexOf(PATTERN_SEPARATOR) >= 0
2206 || affix.indexOf(PATTERN_MINUS) >= 0
2207 || affix.indexOf(CURRENCY_SIGN) >= 0;
2209 if (needQuote) buffer.append('\'');
2210 if (affix.indexOf('\'') < 0) buffer.append(affix);
2212 for (int j=0; j<affix.length(); ++j) {
2213 char c = affix.charAt(j);
2215 if (c == '\'') buffer.append(c);
2218 if (needQuote) buffer.append('\'');
2222 * Does the real work of generating a pattern. */
2223 private String toPattern(boolean localized) {
2224 StringBuffer result = new StringBuffer();
2225 for (int j = 1; j >= 0; --j) {
2227 appendAffix(result, posPrefixPattern, positivePrefix, localized);
2228 else appendAffix(result, negPrefixPattern, negativePrefix, localized);
2230 int digitCount = useExponentialNotation
2231 ? getMaximumIntegerDigits()
2232 : Math.max(groupingSize, getMinimumIntegerDigits())+1;
2233 for (i = digitCount; i > 0; --i) {
2234 if (i != digitCount && isGroupingUsed() && groupingSize != 0 &&
2235 i % groupingSize == 0) {
2236 result.append(localized ? symbols.getGroupingSeparator() :
2237 PATTERN_GROUPING_SEPARATOR);
2239 result.append(i <= getMinimumIntegerDigits()
2240 ? (localized ? symbols.getZeroDigit() : PATTERN_ZERO_DIGIT)
2241 : (localized ? symbols.getDigit() : PATTERN_DIGIT));
2243 if (getMaximumFractionDigits() > 0 || decimalSeparatorAlwaysShown)
2244 result.append(localized ? symbols.getDecimalSeparator() :
2245 PATTERN_DECIMAL_SEPARATOR);
2246 for (i = 0; i < getMaximumFractionDigits(); ++i) {
2247 if (i < getMinimumFractionDigits()) {
2248 result.append(localized ? symbols.getZeroDigit() :
2249 PATTERN_ZERO_DIGIT);
2251 result.append(localized ? symbols.getDigit() :
2255 if (useExponentialNotation)
2257 result.append(localized ? symbols.getExponentSeparator() :
2259 for (i=0; i<minExponentDigits; ++i)
2260 result.append(localized ? symbols.getZeroDigit() :
2261 PATTERN_ZERO_DIGIT);
2264 appendAffix(result, posSuffixPattern, positiveSuffix, localized);
2265 if ((negSuffixPattern == posSuffixPattern && // n == p == null
2266 negativeSuffix.equals(positiveSuffix))
2267 || (negSuffixPattern != null &&
2268 negSuffixPattern.equals(posSuffixPattern))) {
2269 if ((negPrefixPattern != null && posPrefixPattern != null &&
2270 negPrefixPattern.equals("'-" + posPrefixPattern)) ||
2271 (negPrefixPattern == posPrefixPattern && // n == p == null
2272 negativePrefix.equals(symbols.getMinusSign() + positivePrefix)))
2275 result.append(localized ? symbols.getPatternSeparator() :
2277 } else appendAffix(result, negSuffixPattern, negativeSuffix, localized);
2279 return result.toString();
2283 * Apply the given pattern to this Format object. A pattern is a
2284 * short-hand specification for the various formatting properties.
2285 * These properties can also be changed individually through the
2286 * various setter methods.
2288 * There is no limit to integer digits set
2289 * by this routine, since that is the typical end-user desire;
2290 * use setMaximumInteger if you want to set a real value.
2291 * For negative numbers, use a second pattern, separated by a semicolon
2292 * <P>Example <code>"#,#00.0#"</code> -> 1,234.56
2293 * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
2294 * a maximum of 2 fraction digits.
2295 * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
2297 * <p>In negative patterns, the minimum and maximum counts are ignored;
2298 * these are presumed to be set in the positive pattern.
2300 * @exception NullPointerException if <code>pattern</code> is null
2301 * @exception IllegalArgumentException if the given pattern is invalid.
2303 public void applyPattern(String pattern) {
2304 applyPattern(pattern, false);
2308 * Apply the given pattern to this Format object. The pattern
2309 * is assumed to be in a localized notation. A pattern is a
2310 * short-hand specification for the various formatting properties.
2311 * These properties can also be changed individually through the
2312 * various setter methods.
2314 * There is no limit to integer digits set
2315 * by this routine, since that is the typical end-user desire;
2316 * use setMaximumInteger if you want to set a real value.
2317 * For negative numbers, use a second pattern, separated by a semicolon
2318 * <P>Example <code>"#,#00.0#"</code> -> 1,234.56
2319 * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
2320 * a maximum of 2 fraction digits.
2321 * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
2323 * <p>In negative patterns, the minimum and maximum counts are ignored;
2324 * these are presumed to be set in the positive pattern.
2326 * @exception NullPointerException if <code>pattern</code> is null
2327 * @exception IllegalArgumentException if the given pattern is invalid.
2329 public void applyLocalizedPattern(String pattern) {
2330 applyPattern(pattern, true);
2334 * Does the real work of applying a pattern.
2336 private void applyPattern(String pattern, boolean localized) {
2337 char zeroDigit = PATTERN_ZERO_DIGIT;
2338 char groupingSeparator = PATTERN_GROUPING_SEPARATOR;
2339 char decimalSeparator = PATTERN_DECIMAL_SEPARATOR;
2340 char percent = PATTERN_PERCENT;
2341 char perMill = PATTERN_PER_MILLE;
2342 char digit = PATTERN_DIGIT;
2343 char separator = PATTERN_SEPARATOR;
2344 String exponent = PATTERN_EXPONENT;
2345 char minus = PATTERN_MINUS;
2347 zeroDigit = symbols.getZeroDigit();
2348 groupingSeparator = symbols.getGroupingSeparator();
2349 decimalSeparator = symbols.getDecimalSeparator();
2350 percent = symbols.getPercent();
2351 perMill = symbols.getPerMill();
2352 digit = symbols.getDigit();
2353 separator = symbols.getPatternSeparator();
2354 exponent = symbols.getExponentSeparator();
2355 minus = symbols.getMinusSign();
2357 boolean gotNegative = false;
2358 decimalSeparatorAlwaysShown = false;
2359 isCurrencyFormat = false;
2360 useExponentialNotation = false;
2362 // Two variables are used to record the subrange of the pattern
2363 // occupied by phase 1. This is used during the processing of the
2364 // second pattern (the one representing negative numbers) to ensure
2365 // that no deviation exists in phase 1 between the two patterns.
2366 int phaseOneStart = 0;
2367 int phaseOneLength = 0;
2370 for (int j = 1; j >= 0 && start < pattern.length(); --j) {
2371 boolean inQuote = false;
2372 StringBuffer prefix = new StringBuffer();
2373 StringBuffer suffix = new StringBuffer();
2374 int decimalPos = -1;
2376 int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0;
2377 byte groupingCount = -1;
2379 // The phase ranges from 0 to 2. Phase 0 is the prefix. Phase 1 is
2380 // the section of the pattern with digits, decimal separator,
2381 // grouping characters. Phase 2 is the suffix. In phases 0 and 2,
2382 // percent, per mille, and currency symbols are recognized and
2383 // translated. The separation of the characters into phases is
2384 // strictly enforced; if phase 1 characters are to appear in the
2385 // suffix, for example, they must be quoted.
2388 // The affix is either the prefix or the suffix.
2389 StringBuffer affix = prefix;
2391 for (int pos = start; pos < pattern.length(); ++pos) {
2392 char ch = pattern.charAt(pos);
2396 // Process the prefix / suffix characters
2398 // A quote within quotes indicates either the closing
2399 // quote or two quotes, which is a quote literal. That
2400 // is, we have the second quote in 'do' or 'don''t'.
2402 if ((pos+1) < pattern.length() &&
2403 pattern.charAt(pos+1) == QUOTE) {
2405 affix.append("''"); // 'don''t'
2407 inQuote = false; // 'do'
2412 // Process unquoted characters seen in prefix or suffix
2416 ch == groupingSeparator ||
2417 ch == decimalSeparator) {
2420 phaseOneStart = pos;
2422 --pos; // Reprocess this character
2424 } else if (ch == CURRENCY_SIGN) {
2425 // Use lookahead to determine if the currency sign
2426 // is doubled or not.
2427 boolean doubled = (pos + 1) < pattern.length() &&
2428 pattern.charAt(pos + 1) == CURRENCY_SIGN;
2429 if (doubled) { // Skip over the doubled character
2432 isCurrencyFormat = true;
2433 affix.append(doubled ? "'\u00A4\u00A4" : "'\u00A4");
2435 } else if (ch == QUOTE) {
2436 // A quote outside quotes indicates either the
2437 // opening quote or two quotes, which is a quote
2438 // literal. That is, we have the first quote in 'do'
2441 if ((pos+1) < pattern.length() &&
2442 pattern.charAt(pos+1) == QUOTE) {
2444 affix.append("''"); // o''clock
2446 inQuote = true; // 'do'
2450 } else if (ch == separator) {
2451 // Don't allow separators before we see digit
2452 // characters of phase 1, and don't allow separators
2453 // in the second pattern (j == 0).
2454 if (phase == 0 || j == 0) {
2455 throw new IllegalArgumentException("Unquoted special character '" +
2456 ch + "' in pattern \"" + pattern + '"');
2459 pos = pattern.length();
2463 // Next handle characters which are appended directly.
2464 else if (ch == percent) {
2465 if (multiplier != 1) {
2466 throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +
2472 } else if (ch == perMill) {
2473 if (multiplier != 1) {
2474 throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +
2478 affix.append("'\u2030");
2480 } else if (ch == minus) {
2485 // Note that if we are within quotes, or if this is an
2486 // unquoted, non-special character, then we usually fall
2492 // Phase one must be identical in the two sub-patterns. We
2493 // enforce this by doing a direct comparison. While
2494 // processing the first sub-pattern, we just record its
2495 // length. While processing the second, we compare
2500 if (--phaseOneLength == 0) {
2507 // Process the digits, decimal, and grouping characters. We
2508 // record five pieces of information. We expect the digits
2509 // to occur in the pattern ####0000.####, and we record the
2510 // number of left digits, zero (central) digits, and right
2511 // digits. The position of the last grouping character is
2512 // recorded (should be somewhere within the first two blocks
2513 // of characters), as is the position of the decimal point,
2514 // if any (should be in the zero digits). If there is no
2515 // decimal point, then there should be no right digits.
2517 if (zeroDigitCount > 0) {
2522 if (groupingCount >= 0 && decimalPos < 0) {
2525 } else if (ch == zeroDigit) {
2526 if (digitRightCount > 0) {
2527 throw new IllegalArgumentException("Unexpected '0' in pattern \"" +
2531 if (groupingCount >= 0 && decimalPos < 0) {
2534 } else if (ch == groupingSeparator) {
2536 } else if (ch == decimalSeparator) {
2537 if (decimalPos >= 0) {
2538 throw new IllegalArgumentException("Multiple decimal separators in pattern \"" +
2541 decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
2542 } else if (pattern.regionMatches(pos, exponent, 0, exponent.length())){
2543 if (useExponentialNotation) {
2544 throw new IllegalArgumentException("Multiple exponential " +
2545 "symbols in pattern \"" + pattern + '"');
2547 useExponentialNotation = true;
2548 minExponentDigits = 0;
2550 // Use lookahead to parse out the exponential part
2551 // of the pattern, then jump into phase 2.
2552 pos = pos+exponent.length();
2553 while (pos < pattern.length() &&
2554 pattern.charAt(pos) == zeroDigit) {
2555 ++minExponentDigits;
2560 if ((digitLeftCount + zeroDigitCount) < 1 ||
2561 minExponentDigits < 1) {
2562 throw new IllegalArgumentException("Malformed exponential " +
2563 "pattern \"" + pattern + '"');
2566 // Transition to phase 2
2582 // Handle patterns with no '0' pattern character. These patterns
2583 // are legal, but must be interpreted. "##.###" -> "#0.###".
2584 // ".###" -> ".0##".
2585 /* We allow patterns of the form "####" to produce a zeroDigitCount
2586 * of zero (got that?); although this seems like it might make it
2587 * possible for format() to produce empty strings, format() checks
2588 * for this condition and outputs a zero digit in this situation.
2589 * Having a zeroDigitCount of zero yields a minimum integer digits
2590 * of zero, which allows proper round-trip patterns. That is, we
2591 * don't want "#" to become "#0" when toPattern() is called (even
2592 * though that's what it really is, semantically).
2594 if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {
2595 // Handle "###.###" and "###." and ".###"
2597 if (n == 0) { // Handle ".###"
2600 digitRightCount = digitLeftCount - n;
2601 digitLeftCount = n - 1;
2605 // Do syntax checking on the digits.
2606 if ((decimalPos < 0 && digitRightCount > 0) ||
2607 (decimalPos >= 0 && (decimalPos < digitLeftCount ||
2608 decimalPos > (digitLeftCount + zeroDigitCount))) ||
2609 groupingCount == 0 || inQuote) {
2610 throw new IllegalArgumentException("Malformed pattern \"" +
2615 posPrefixPattern = prefix.toString();
2616 posSuffixPattern = suffix.toString();
2617 negPrefixPattern = posPrefixPattern; // assume these for now
2618 negSuffixPattern = posSuffixPattern;
2619 int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
2620 /* The effectiveDecimalPos is the position the decimal is at or
2621 * would be at if there is no decimal. Note that if decimalPos<0,
2622 * then digitTotalCount == digitLeftCount + zeroDigitCount.
2624 int effectiveDecimalPos = decimalPos >= 0 ?
2625 decimalPos : digitTotalCount;
2626 setMinimumIntegerDigits(effectiveDecimalPos - digitLeftCount);
2627 setMaximumIntegerDigits(useExponentialNotation ?
2628 digitLeftCount + getMinimumIntegerDigits() :
2629 MAXIMUM_INTEGER_DIGITS);
2630 setMaximumFractionDigits(decimalPos >= 0 ?
2631 (digitTotalCount - decimalPos) : 0);
2632 setMinimumFractionDigits(decimalPos >= 0 ?
2633 (digitLeftCount + zeroDigitCount - decimalPos) : 0);
2634 setGroupingUsed(groupingCount > 0);
2635 this.groupingSize = (groupingCount > 0) ? groupingCount : 0;
2636 this.multiplier = multiplier;
2637 setDecimalSeparatorAlwaysShown(decimalPos == 0 ||
2638 decimalPos == digitTotalCount);
2640 negPrefixPattern = prefix.toString();
2641 negSuffixPattern = suffix.toString();
2646 if (pattern.length() == 0) {
2647 posPrefixPattern = posSuffixPattern = "";
2648 setMinimumIntegerDigits(0);
2649 setMaximumIntegerDigits(MAXIMUM_INTEGER_DIGITS);
2650 setMinimumFractionDigits(0);
2651 setMaximumFractionDigits(MAXIMUM_FRACTION_DIGITS);
2654 // If there was no negative pattern, or if the negative pattern is
2655 // identical to the positive pattern, then prepend the minus sign to
2656 // the positive pattern to form the negative pattern.
2658 (negPrefixPattern.equals(posPrefixPattern)
2659 && negSuffixPattern.equals(posSuffixPattern))) {
2660 negSuffixPattern = posSuffixPattern;
2661 negPrefixPattern = "'-" + posPrefixPattern;
2668 * Sets the maximum number of digits allowed in the integer portion of a
2670 * For formatting numbers other than <code>BigInteger</code> and
2671 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2672 * 309 is used. Negative input values are replaced with 0.
2673 * @see NumberFormat#setMaximumIntegerDigits
2675 public void setMaximumIntegerDigits(int newValue) {
2676 maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
2677 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2678 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
2679 if (minimumIntegerDigits > maximumIntegerDigits) {
2680 minimumIntegerDigits = maximumIntegerDigits;
2681 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2682 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
2687 * Sets the minimum number of digits allowed in the integer portion of a
2689 * For formatting numbers other than <code>BigInteger</code> and
2690 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2691 * 309 is used. Negative input values are replaced with 0.
2692 * @see NumberFormat#setMinimumIntegerDigits
2694 public void setMinimumIntegerDigits(int newValue) {
2695 minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
2696 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2697 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
2698 if (minimumIntegerDigits > maximumIntegerDigits) {
2699 maximumIntegerDigits = minimumIntegerDigits;
2700 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2701 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
2706 * Sets the maximum number of digits allowed in the fraction portion of a
2708 * For formatting numbers other than <code>BigInteger</code> and
2709 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2710 * 340 is used. Negative input values are replaced with 0.
2711 * @see NumberFormat#setMaximumFractionDigits
2713 public void setMaximumFractionDigits(int newValue) {
2714 maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
2715 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2716 DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
2717 if (minimumFractionDigits > maximumFractionDigits) {
2718 minimumFractionDigits = maximumFractionDigits;
2719 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2720 DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
2725 * Sets the minimum number of digits allowed in the fraction portion of a
2727 * For formatting numbers other than <code>BigInteger</code> and
2728 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2729 * 340 is used. Negative input values are replaced with 0.
2730 * @see NumberFormat#setMinimumFractionDigits
2732 public void setMinimumFractionDigits(int newValue) {
2733 minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
2734 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2735 DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
2736 if (minimumFractionDigits > maximumFractionDigits) {
2737 maximumFractionDigits = minimumFractionDigits;
2738 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2739 DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
2744 * Gets the maximum number of digits allowed in the integer portion of a
2746 * For formatting numbers other than <code>BigInteger</code> and
2747 * <code>BigDecimal</code> objects, the lower of the return value and
2749 * @see #setMaximumIntegerDigits
2751 public int getMaximumIntegerDigits() {
2752 return maximumIntegerDigits;
2756 * Gets the minimum number of digits allowed in the integer portion of a
2758 * For formatting numbers other than <code>BigInteger</code> and
2759 * <code>BigDecimal</code> objects, the lower of the return value and
2761 * @see #setMinimumIntegerDigits
2763 public int getMinimumIntegerDigits() {
2764 return minimumIntegerDigits;
2768 * Gets the maximum number of digits allowed in the fraction portion of a
2770 * For formatting numbers other than <code>BigInteger</code> and
2771 * <code>BigDecimal</code> objects, the lower of the return value and
2773 * @see #setMaximumFractionDigits
2775 public int getMaximumFractionDigits() {
2776 return maximumFractionDigits;
2780 * Gets the minimum number of digits allowed in the fraction portion of a
2782 * For formatting numbers other than <code>BigInteger</code> and
2783 * <code>BigDecimal</code> objects, the lower of the return value and
2785 * @see #setMinimumFractionDigits
2787 public int getMinimumFractionDigits() {
2788 return minimumFractionDigits;
2792 * Gets the currency used by this decimal format when formatting
2794 * The currency is obtained by calling
2795 * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency}
2796 * on this number format's symbols.
2798 * @return the currency used by this decimal format, or <code>null</code>
2801 public Currency getCurrency() {
2802 return symbols.getCurrency();
2806 * Sets the currency used by this number format when formatting
2807 * currency values. This does not update the minimum or maximum
2808 * number of fraction digits used by the number format.
2809 * The currency is set by calling
2810 * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency}
2811 * on this number format's symbols.
2813 * @param currency the new currency to be used by this decimal format
2814 * @exception NullPointerException if <code>currency</code> is null
2817 public void setCurrency(Currency currency) {
2818 if (currency != symbols.getCurrency()) {
2819 symbols.setCurrency(currency);
2820 if (isCurrencyFormat) {
2827 * Gets the {@link java.math.RoundingMode} used in this DecimalFormat.
2829 * @return The <code>RoundingMode</code> used for this DecimalFormat.
2830 * @see #setRoundingMode(RoundingMode)
2833 public RoundingMode getRoundingMode() {
2834 return roundingMode;
2838 * Sets the {@link java.math.RoundingMode} used in this DecimalFormat.
2840 * @param roundingMode The <code>RoundingMode</code> to be used
2841 * @see #getRoundingMode()
2842 * @exception NullPointerException if <code>roundingMode</code> is null.
2845 public void setRoundingMode(RoundingMode roundingMode) {
2846 if (roundingMode == null) {
2847 throw new NullPointerException();
2850 this.roundingMode = roundingMode;
2851 digitList.setRoundingMode(roundingMode);
2855 * Adjusts the minimum and maximum fraction digits to values that
2856 * are reasonable for the currency's default fraction digits.
2858 void adjustForCurrencyDefaultFractionDigits() {
2859 Currency currency = symbols.getCurrency();
2860 if (currency == null) {
2862 currency = Currency.getInstance(symbols.getInternationalCurrencySymbol());
2863 } catch (IllegalArgumentException e) {
2866 if (currency != null) {
2867 int digits = currency.getDefaultFractionDigits();
2869 int oldMinDigits = getMinimumFractionDigits();
2870 // Common patterns are "#.##", "#.00", "#".
2871 // Try to adjust all of them in a reasonable way.
2872 if (oldMinDigits == getMaximumFractionDigits()) {
2873 setMinimumFractionDigits(digits);
2874 setMaximumFractionDigits(digits);
2876 setMinimumFractionDigits(Math.min(digits, oldMinDigits));
2877 setMaximumFractionDigits(digits);
2884 * Reads the default serializable fields from the stream and performs
2885 * validations and adjustments for older serialized versions. The
2886 * validations and adjustments are:
2889 * Verify that the superclass's digit count fields correctly reflect
2890 * the limits imposed on formatting numbers other than
2891 * <code>BigInteger</code> and <code>BigDecimal</code> objects. These
2892 * limits are stored in the superclass for serialization compatibility
2893 * with older versions, while the limits for <code>BigInteger</code> and
2894 * <code>BigDecimal</code> objects are kept in this class.
2895 * If, in the superclass, the minimum or maximum integer digit count is
2896 * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or
2897 * maximum fraction digit count is larger than
2898 * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid
2899 * and this method throws an <code>InvalidObjectException</code>.
2901 * If <code>serialVersionOnStream</code> is less than 4, initialize
2902 * <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN
2903 * RoundingMode.HALF_EVEN}. This field is new with version 4.
2905 * If <code>serialVersionOnStream</code> is less than 3, then call
2906 * the setters for the minimum and maximum integer and fraction digits with
2907 * the values of the corresponding superclass getters to initialize the
2908 * fields in this class. The fields in this class are new with version 3.
2910 * If <code>serialVersionOnStream</code> is less than 1, indicating that
2911 * the stream was written by JDK 1.1, initialize
2912 * <code>useExponentialNotation</code>
2913 * to false, since it was not present in JDK 1.1.
2915 * Set <code>serialVersionOnStream</code> to the maximum allowed value so
2916 * that default serialization will work properly if this object is streamed
2920 * <p>Stream versions older than 2 will not have the affix pattern variables
2921 * <code>posPrefixPattern</code> etc. As a result, they will be initialized
2922 * to <code>null</code>, which means the affix strings will be taken as
2923 * literal values. This is exactly what we want, since that corresponds to
2924 * the pre-version-2 behavior.
2926 private void readObject(ObjectInputStream stream)
2927 throws IOException, ClassNotFoundException
2929 stream.defaultReadObject();
2930 digitList = new DigitList();
2932 if (serialVersionOnStream < 4) {
2933 setRoundingMode(RoundingMode.HALF_EVEN);
2935 // We only need to check the maximum counts because NumberFormat
2936 // .readObject has already ensured that the maximum is greater than the
2938 if (super.getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS ||
2939 super.getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {
2940 throw new InvalidObjectException("Digit count out of range");
2942 if (serialVersionOnStream < 3) {
2943 setMaximumIntegerDigits(super.getMaximumIntegerDigits());
2944 setMinimumIntegerDigits(super.getMinimumIntegerDigits());
2945 setMaximumFractionDigits(super.getMaximumFractionDigits());
2946 setMinimumFractionDigits(super.getMinimumFractionDigits());
2948 if (serialVersionOnStream < 1) {
2949 // Didn't have exponential fields
2950 useExponentialNotation = false;
2952 serialVersionOnStream = currentSerialVersion;
2955 //----------------------------------------------------------------------
2956 // INSTANCE VARIABLES
2957 //----------------------------------------------------------------------
2959 private transient DigitList digitList = new DigitList();
2962 * The symbol used as a prefix when formatting positive numbers, e.g. "+".
2965 * @see #getPositivePrefix
2967 private String positivePrefix = "";
2970 * The symbol used as a suffix when formatting positive numbers.
2971 * This is often an empty string.
2974 * @see #getPositiveSuffix
2976 private String positiveSuffix = "";
2979 * The symbol used as a prefix when formatting negative numbers, e.g. "-".
2982 * @see #getNegativePrefix
2984 private String negativePrefix = "-";
2987 * The symbol used as a suffix when formatting negative numbers.
2988 * This is often an empty string.
2991 * @see #getNegativeSuffix
2993 private String negativeSuffix = "";
2996 * The prefix pattern for non-negative numbers. This variable corresponds
2997 * to <code>positivePrefix</code>.
2999 * <p>This pattern is expanded by the method <code>expandAffix()</code> to
3000 * <code>positivePrefix</code> to update the latter to reflect changes in
3001 * <code>symbols</code>. If this variable is <code>null</code> then
3002 * <code>positivePrefix</code> is taken as a literal value that does not
3003 * change when <code>symbols</code> changes. This variable is always
3004 * <code>null</code> for <code>DecimalFormat</code> objects older than
3005 * stream version 2 restored from stream.
3010 private String posPrefixPattern;
3013 * The suffix pattern for non-negative numbers. This variable corresponds
3014 * to <code>positiveSuffix</code>. This variable is analogous to
3015 * <code>posPrefixPattern</code>; see that variable for further
3021 private String posSuffixPattern;
3024 * The prefix pattern for negative numbers. This variable corresponds
3025 * to <code>negativePrefix</code>. This variable is analogous to
3026 * <code>posPrefixPattern</code>; see that variable for further
3032 private String negPrefixPattern;
3035 * The suffix pattern for negative numbers. This variable corresponds
3036 * to <code>negativeSuffix</code>. This variable is analogous to
3037 * <code>posPrefixPattern</code>; see that variable for further
3043 private String negSuffixPattern;
3046 * The multiplier for use in percent, per mille, etc.
3049 * @see #getMultiplier
3051 private int multiplier = 1;
3054 * The number of digits between grouping separators in the integer
3055 * portion of a number. Must be greater than 0 if
3056 * <code>NumberFormat.groupingUsed</code> is true.
3059 * @see #getGroupingSize
3060 * @see java.text.NumberFormat#isGroupingUsed
3062 private byte groupingSize = 3; // invariant, > 0 if useThousands
3065 * If true, forces the decimal separator to always appear in a formatted
3066 * number, even if the fractional part of the number is zero.
3069 * @see #isDecimalSeparatorAlwaysShown
3071 private boolean decimalSeparatorAlwaysShown = false;
3074 * If true, parse returns BigDecimal wherever possible.
3077 * @see #isParseBigDecimal
3080 private boolean parseBigDecimal = false;
3084 * True if this object represents a currency format. This determines
3085 * whether the monetary decimal separator is used instead of the normal one.
3087 private transient boolean isCurrencyFormat = false;
3090 * The <code>DecimalFormatSymbols</code> object used by this format.
3091 * It contains the symbols used to format numbers, e.g. the grouping separator,
3092 * decimal separator, and so on.
3095 * @see #setDecimalFormatSymbols
3096 * @see java.text.DecimalFormatSymbols
3098 private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols();
3101 * True to force the use of exponential (i.e. scientific) notation when formatting
3107 private boolean useExponentialNotation; // Newly persistent in the Java 2 platform v.1.2
3110 * FieldPositions describing the positive prefix String. This is
3111 * lazily created. Use <code>getPositivePrefixFieldPositions</code>
3114 private transient FieldPosition[] positivePrefixFieldPositions;
3117 * FieldPositions describing the positive suffix String. This is
3118 * lazily created. Use <code>getPositiveSuffixFieldPositions</code>
3121 private transient FieldPosition[] positiveSuffixFieldPositions;
3124 * FieldPositions describing the negative prefix String. This is
3125 * lazily created. Use <code>getNegativePrefixFieldPositions</code>
3128 private transient FieldPosition[] negativePrefixFieldPositions;
3131 * FieldPositions describing the negative suffix String. This is
3132 * lazily created. Use <code>getNegativeSuffixFieldPositions</code>
3135 private transient FieldPosition[] negativeSuffixFieldPositions;
3138 * The minimum number of digits used to display the exponent when a number is
3139 * formatted in exponential notation. This field is ignored if
3140 * <code>useExponentialNotation</code> is not true.
3145 private byte minExponentDigits; // Newly persistent in the Java 2 platform v.1.2
3148 * The maximum number of digits allowed in the integer portion of a
3149 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3150 * <code>maximumIntegerDigits</code> must be greater than or equal to
3151 * <code>minimumIntegerDigits</code>.
3154 * @see #getMaximumIntegerDigits
3157 private int maximumIntegerDigits = super.getMaximumIntegerDigits();
3160 * The minimum number of digits allowed in the integer portion of a
3161 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3162 * <code>minimumIntegerDigits</code> must be less than or equal to
3163 * <code>maximumIntegerDigits</code>.
3166 * @see #getMinimumIntegerDigits
3169 private int minimumIntegerDigits = super.getMinimumIntegerDigits();
3172 * The maximum number of digits allowed in the fractional portion of a
3173 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3174 * <code>maximumFractionDigits</code> must be greater than or equal to
3175 * <code>minimumFractionDigits</code>.
3178 * @see #getMaximumFractionDigits
3181 private int maximumFractionDigits = super.getMaximumFractionDigits();
3184 * The minimum number of digits allowed in the fractional portion of a
3185 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3186 * <code>minimumFractionDigits</code> must be less than or equal to
3187 * <code>maximumFractionDigits</code>.
3190 * @see #getMinimumFractionDigits
3193 private int minimumFractionDigits = super.getMinimumFractionDigits();
3196 * The {@link java.math.RoundingMode} used in this DecimalFormat.
3201 private RoundingMode roundingMode = RoundingMode.HALF_EVEN;
3203 //----------------------------------------------------------------------
3205 static final int currentSerialVersion = 4;
3208 * The internal serial version which says which version was written.
3209 * Possible values are:
3211 * <li><b>0</b> (default): versions before the Java 2 platform v1.2
3212 * <li><b>1</b>: version for 1.2, which includes the two new fields
3213 * <code>useExponentialNotation</code> and
3214 * <code>minExponentDigits</code>.
3215 * <li><b>2</b>: version for 1.3 and later, which adds four new fields:
3216 * <code>posPrefixPattern</code>, <code>posSuffixPattern</code>,
3217 * <code>negPrefixPattern</code>, and <code>negSuffixPattern</code>.
3218 * <li><b>3</b>: version for 1.5 and later, which adds five new fields:
3219 * <code>maximumIntegerDigits</code>,
3220 * <code>minimumIntegerDigits</code>,
3221 * <code>maximumFractionDigits</code>,
3222 * <code>minimumFractionDigits</code>, and
3223 * <code>parseBigDecimal</code>.
3224 * <li><b>4</b>: version for 1.6 and later, which adds one new field:
3225 * <code>roundingMode</code>.
3230 private int serialVersionOnStream = currentSerialVersion;
3232 //----------------------------------------------------------------------
3234 //----------------------------------------------------------------------
3236 // Constants for characters used in programmatic (unlocalized) patterns.
3237 private static final char PATTERN_ZERO_DIGIT = '0';
3238 private static final char PATTERN_GROUPING_SEPARATOR = ',';
3239 private static final char PATTERN_DECIMAL_SEPARATOR = '.';
3240 private static final char PATTERN_PER_MILLE = '\u2030';
3241 private static final char PATTERN_PERCENT = '%';
3242 private static final char PATTERN_DIGIT = '#';
3243 private static final char PATTERN_SEPARATOR = ';';
3244 private static final String PATTERN_EXPONENT = "E";
3245 private static final char PATTERN_MINUS = '-';
3248 * The CURRENCY_SIGN is the standard Unicode symbol for currency. It
3249 * is used in patterns and substituted with either the currency symbol,
3250 * or if it is doubled, with the international currency symbol. If the
3251 * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
3252 * replaced with the monetary decimal separator.
3254 * The CURRENCY_SIGN is not localized.
3256 private static final char CURRENCY_SIGN = '\u00A4';
3258 private static final char QUOTE = '\'';
3260 private static FieldPosition[] EmptyFieldPositionArray = new FieldPosition[0];
3262 // Upper limit on integer and fraction digits for a Java double
3263 static final int DOUBLE_INTEGER_DIGITS = 309;
3264 static final int DOUBLE_FRACTION_DIGITS = 340;
3266 // Upper limit on integer and fraction digits for BigDecimal and BigInteger
3267 static final int MAXIMUM_INTEGER_DIGITS = Integer.MAX_VALUE;
3268 static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE;
3270 // Proclaim JDK 1.1 serial compatibility.
3271 static final long serialVersionUID = 864413376551465018L;
3274 * Cache to hold the NumberPattern of a Locale.
3276 private static final ConcurrentMap<Locale, String> cachedLocaleData
3277 = new ConcurrentHashMap<Locale, String>(3);