1 /*
2 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 /*
27 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
28 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
29 *
30 * The original version of this source code and documentation is copyrighted
31 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
32 * materials are provided under terms of a License Agreement between Taligent
33 * and Sun. This technology is protected by multiple US and International
34 * patents. This notice and attribution to Taligent may not be removed.
35 * Taligent is a registered trademark of Taligent, Inc.
36 *
37 */
38
39 package java.text;
40
41 import java.io.InvalidObjectException;
42 import java.io.IOException;
43 import java.io.ObjectInputStream;
44 import java.math.BigDecimal;
45 import java.math.BigInteger;
46 import java.math.RoundingMode;
47 import java.util.ArrayList;
48 import java.util.Currency;
49 import java.util.Locale;
50 import java.util.ResourceBundle;
51 import java.util.concurrent.ConcurrentHashMap;
52 import java.util.concurrent.ConcurrentMap;
53 import java.util.concurrent.atomic.AtomicInteger;
54 import java.util.concurrent.atomic.AtomicLong;
55 import sun.util.resources.LocaleData;
56
57 /**
58 * <code>DecimalFormat</code> is a concrete subclass of
59 * <code>NumberFormat</code> that formats decimal numbers. It has a variety of
60 * features designed to make it possible to parse and format numbers in any
61 * locale, including support for Western, Arabic, and Indic digits. It also
62 * supports different kinds of numbers, including integers (123), fixed-point
63 * numbers (123.4), scientific notation (1.23E4), percentages (12%), and
64 * currency amounts ($123). All of these can be localized.
65 *
66 * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the
67 * default locale, call one of <code>NumberFormat</code>'s factory methods, such
68 * as <code>getInstance()</code>. In general, do not call the
69 * <code>DecimalFormat</code> constructors directly, since the
70 * <code>NumberFormat</code> factory methods may return subclasses other than
71 * <code>DecimalFormat</code>. If you need to customize the format object, do
72 * something like this:
73 *
74 * <blockquote><pre>
75 * NumberFormat f = NumberFormat.getInstance(loc);
381 * Creates a DecimalFormat using the default pattern and symbols
382 * for the default locale. This is a convenient way to obtain a
383 * DecimalFormat when internationalization is not the main concern.
384 * <p>
385 * To obtain standard formats for a given locale, use the factory methods
386 * on NumberFormat such as getNumberInstance. These factories will
387 * return the most appropriate sub-class of NumberFormat for a given
388 * locale.
389 *
390 * @see java.text.NumberFormat#getInstance
391 * @see java.text.NumberFormat#getNumberInstance
392 * @see java.text.NumberFormat#getCurrencyInstance
393 * @see java.text.NumberFormat#getPercentInstance
394 */
395 public DecimalFormat() {
396 Locale def = Locale.getDefault(Locale.Category.FORMAT);
397 // try to get the pattern from the cache
398 String pattern = cachedLocaleData.get(def);
399 if (pattern == null) { /* cache miss */
400 // Get the pattern for the default locale.
401 ResourceBundle rb = LocaleData.getNumberFormatData(def);
402 String[] all = rb.getStringArray("NumberPatterns");
403 pattern = all[0];
404 /* update cache */
405 cachedLocaleData.putIfAbsent(def, pattern);
406 }
407
408 // Always applyPattern after the symbols are set
409 this.symbols = new DecimalFormatSymbols(def);
410 applyPattern(pattern, false);
411 }
412
413
414 /**
415 * Creates a DecimalFormat using the given pattern and the symbols
416 * for the default locale. This is a convenient way to obtain a
417 * DecimalFormat when internationalization is not the main concern.
418 * <p>
419 * To obtain standard formats for a given locale, use the factory methods
420 * on NumberFormat such as getNumberInstance. These factories will
421 * return the most appropriate sub-class of NumberFormat for a given
422 * locale.
423 *
424 * @param pattern A non-localized pattern string.
425 * @exception NullPointerException if <code>pattern</code> is null
426 * @exception IllegalArgumentException if the given pattern is invalid.
427 * @see java.text.NumberFormat#getInstance
428 * @see java.text.NumberFormat#getNumberInstance
429 * @see java.text.NumberFormat#getCurrencyInstance
430 * @see java.text.NumberFormat#getPercentInstance
431 */
432 public DecimalFormat(String pattern) {
433 // Always applyPattern after the symbols are set
434 this.symbols = new DecimalFormatSymbols(Locale.getDefault(Locale.Category.FORMAT));
435 applyPattern(pattern, false);
436 }
437
438
439 /**
440 * Creates a DecimalFormat using the given pattern and symbols.
441 * Use this constructor when you need to completely customize the
442 * behavior of the format.
443 * <p>
444 * To obtain standard formats for a given
445 * locale, use the factory methods on NumberFormat such as
446 * getInstance or getCurrencyInstance. If you need only minor adjustments
447 * to a standard format, you can modify the format returned by
448 * a NumberFormat factory method.
449 *
450 * @param pattern a non-localized pattern string
451 * @param symbols the set of symbols to be used
452 * @exception NullPointerException if any of the given arguments is null
453 * @exception IllegalArgumentException if the given pattern is invalid
454 * @see java.text.NumberFormat#getInstance
468 /**
469 * Formats a number and appends the resulting text to the given string
470 * buffer.
471 * The number can be of any subclass of {@link java.lang.Number}.
472 * <p>
473 * This implementation uses the maximum precision permitted.
474 * @param number the number to format
475 * @param toAppendTo the <code>StringBuffer</code> to which the formatted
476 * text is to be appended
477 * @param pos On input: an alignment field, if desired.
478 * On output: the offsets of the alignment field.
479 * @return the value passed in as <code>toAppendTo</code>
480 * @exception IllegalArgumentException if <code>number</code> is
481 * null or not an instance of <code>Number</code>.
482 * @exception NullPointerException if <code>toAppendTo</code> or
483 * <code>pos</code> is null
484 * @exception ArithmeticException if rounding is needed with rounding
485 * mode being set to RoundingMode.UNNECESSARY
486 * @see java.text.FieldPosition
487 */
488 public final StringBuffer format(Object number,
489 StringBuffer toAppendTo,
490 FieldPosition pos) {
491 if (number instanceof Long || number instanceof Integer ||
492 number instanceof Short || number instanceof Byte ||
493 number instanceof AtomicInteger ||
494 number instanceof AtomicLong ||
495 (number instanceof BigInteger &&
496 ((BigInteger)number).bitLength () < 64)) {
497 return format(((Number)number).longValue(), toAppendTo, pos);
498 } else if (number instanceof BigDecimal) {
499 return format((BigDecimal)number, toAppendTo, pos);
500 } else if (number instanceof BigInteger) {
501 return format((BigInteger)number, toAppendTo, pos);
502 } else if (number instanceof Number) {
503 return format(((Number)number).doubleValue(), toAppendTo, pos);
504 } else {
505 throw new IllegalArgumentException("Cannot format given Object as a Number");
506 }
507 }
508
509 /**
510 * Formats a double to produce a string.
511 * @param number The double to format
512 * @param result where the text is to be appended
513 * @param fieldPosition On input: an alignment field, if desired.
514 * On output: the offsets of the alignment field.
515 * @exception ArithmeticException if rounding is needed with rounding
516 * mode being set to RoundingMode.UNNECESSARY
517 * @return The formatted number string
518 * @see java.text.FieldPosition
519 */
520 public StringBuffer format(double number, StringBuffer result,
521 FieldPosition fieldPosition) {
522 fieldPosition.setBeginIndex(0);
523 fieldPosition.setEndIndex(0);
524
525 return format(number, result, fieldPosition.getFieldDelegate());
526 }
527
528 /**
529 * Formats a double to produce a string.
530 * @param number The double to format
531 * @param result where the text is to be appended
532 * @param delegate notified of locations of sub fields
533 * @exception ArithmeticException if rounding is needed with rounding
534 * mode being set to RoundingMode.UNNECESSARY
535 * @return The formatted number string
536 */
537 private StringBuffer format(double number, StringBuffer result,
538 FieldDelegate delegate) {
539 if (Double.isNaN(number) ||
601
602 digitList.set(isNegative, number, useExponentialNotation ?
603 maxIntDigits + maxFraDigits : maxFraDigits,
604 !useExponentialNotation);
605 return subformat(result, delegate, isNegative, false,
606 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
607 }
608 }
609
610 /**
611 * Format a long to produce a string.
612 * @param number The long to format
613 * @param result where the text is to be appended
614 * @param fieldPosition On input: an alignment field, if desired.
615 * On output: the offsets of the alignment field.
616 * @exception ArithmeticException if rounding is needed with rounding
617 * mode being set to RoundingMode.UNNECESSARY
618 * @return The formatted number string
619 * @see java.text.FieldPosition
620 */
621 public StringBuffer format(long number, StringBuffer result,
622 FieldPosition fieldPosition) {
623 fieldPosition.setBeginIndex(0);
624 fieldPosition.setEndIndex(0);
625
626 return format(number, result, fieldPosition.getFieldDelegate());
627 }
628
629 /**
630 * Format a long to produce a string.
631 * @param number The long to format
632 * @param result where the text is to be appended
633 * @param delegate notified of locations of sub fields
634 * @return The formatted number string
635 * @exception ArithmeticException if rounding is needed with rounding
636 * mode being set to RoundingMode.UNNECESSARY
637 * @see java.text.FieldPosition
638 */
639 private StringBuffer format(long number, StringBuffer result,
640 FieldDelegate delegate) {
815
816 /**
817 * Formats an Object producing an <code>AttributedCharacterIterator</code>.
818 * You can use the returned <code>AttributedCharacterIterator</code>
819 * to build the resulting String, as well as to determine information
820 * about the resulting String.
821 * <p>
822 * Each attribute key of the AttributedCharacterIterator will be of type
823 * <code>NumberFormat.Field</code>, with the attribute value being the
824 * same as the attribute key.
825 *
826 * @exception NullPointerException if obj is null.
827 * @exception IllegalArgumentException when the Format cannot format the
828 * given object.
829 * @exception ArithmeticException if rounding is needed with rounding
830 * mode being set to RoundingMode.UNNECESSARY
831 * @param obj The object to format
832 * @return AttributedCharacterIterator describing the formatted value.
833 * @since 1.4
834 */
835 public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
836 CharacterIteratorFieldDelegate delegate =
837 new CharacterIteratorFieldDelegate();
838 StringBuffer sb = new StringBuffer();
839
840 if (obj instanceof Double || obj instanceof Float) {
841 format(((Number)obj).doubleValue(), sb, delegate);
842 } else if (obj instanceof Long || obj instanceof Integer ||
843 obj instanceof Short || obj instanceof Byte ||
844 obj instanceof AtomicInteger || obj instanceof AtomicLong) {
845 format(((Number)obj).longValue(), sb, delegate);
846 } else if (obj instanceof BigDecimal) {
847 format((BigDecimal)obj, sb, delegate);
848 } else if (obj instanceof BigInteger) {
849 format((BigInteger)obj, sb, delegate, false);
850 } else if (obj == null) {
851 throw new NullPointerException(
852 "formatToCharacterIterator must be passed non-null object");
853 } else {
854 throw new IllegalArgumentException(
1240 * constructed by {@link java.math.BigDecimal#BigDecimal(String)}
1241 * for corresponding strings in locale-independent format. The
1242 * special cases negative and positive infinity and NaN are returned
1243 * as <code>Double</code> instances holding the values of the
1244 * corresponding <code>Double</code> constants.
1245 * </ul>
1246 * <p>
1247 * <code>DecimalFormat</code> parses all Unicode characters that represent
1248 * decimal digits, as defined by <code>Character.digit()</code>. In
1249 * addition, <code>DecimalFormat</code> also recognizes as digits the ten
1250 * consecutive characters starting with the localized zero digit defined in
1251 * the <code>DecimalFormatSymbols</code> object.
1252 *
1253 * @param text the string to be parsed
1254 * @param pos A <code>ParsePosition</code> object with index and error
1255 * index information as described above.
1256 * @return the parsed value, or <code>null</code> if the parse fails
1257 * @exception NullPointerException if <code>text</code> or
1258 * <code>pos</code> is null.
1259 */
1260 public Number parse(String text, ParsePosition pos) {
1261 // special case NaN
1262 if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) {
1263 pos.index = pos.index + symbols.getNaN().length();
1264 return new Double(Double.NaN);
1265 }
1266
1267 boolean[] status = new boolean[STATUS_LENGTH];
1268 if (!subparse(text, pos, positivePrefix, negativePrefix, digitList, false, status)) {
1269 return null;
1270 }
1271
1272 // special case INFINITY
1273 if (status[STATUS_INFINITE]) {
1274 if (status[STATUS_POSITIVE] == (multiplier >= 0)) {
1275 return new Double(Double.POSITIVE_INFINITY);
1276 } else {
1277 return new Double(Double.NEGATIVE_INFINITY);
1278 }
1279 }
1873 * @see #setParseBigDecimal
1874 * @since 1.5
1875 */
1876 public boolean isParseBigDecimal() {
1877 return parseBigDecimal;
1878 }
1879
1880 /**
1881 * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1882 * method returns <code>BigDecimal</code>.
1883 * @see #isParseBigDecimal
1884 * @since 1.5
1885 */
1886 public void setParseBigDecimal(boolean newValue) {
1887 parseBigDecimal = newValue;
1888 }
1889
1890 /**
1891 * Standard override; no change in semantics.
1892 */
1893 public Object clone() {
1894 DecimalFormat other = (DecimalFormat) super.clone();
1895 other.symbols = (DecimalFormatSymbols) symbols.clone();
1896 other.digitList = (DigitList) digitList.clone();
1897 return other;
1898 }
1899
1900 /**
1901 * Overrides equals
1902 */
1903 public boolean equals(Object obj)
1904 {
1905 if (obj == null) return false;
1906 if (!super.equals(obj)) return false; // super does class check
1907 DecimalFormat other = (DecimalFormat) obj;
1908 return ((posPrefixPattern == other.posPrefixPattern &&
1909 positivePrefix.equals(other.positivePrefix))
1910 || (posPrefixPattern != null &&
1911 posPrefixPattern.equals(other.posPrefixPattern)))
1912 && ((posSuffixPattern == other.posSuffixPattern &&
1913 positiveSuffix.equals(other.positiveSuffix))
1914 || (posSuffixPattern != null &&
1915 posSuffixPattern.equals(other.posSuffixPattern)))
1916 && ((negPrefixPattern == other.negPrefixPattern &&
1917 negativePrefix.equals(other.negativePrefix))
1918 || (negPrefixPattern != null &&
1919 negPrefixPattern.equals(other.negPrefixPattern)))
1920 && ((negSuffixPattern == other.negSuffixPattern &&
1921 negativeSuffix.equals(other.negativeSuffix))
1922 || (negSuffixPattern != null &&
1923 negSuffixPattern.equals(other.negSuffixPattern)))
1924 && multiplier == other.multiplier
1925 && groupingSize == other.groupingSize
1926 && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown
1927 && parseBigDecimal == other.parseBigDecimal
1928 && useExponentialNotation == other.useExponentialNotation
1929 && (!useExponentialNotation ||
1930 minExponentDigits == other.minExponentDigits)
1931 && maximumIntegerDigits == other.maximumIntegerDigits
1932 && minimumIntegerDigits == other.minimumIntegerDigits
1933 && maximumFractionDigits == other.maximumFractionDigits
1934 && minimumFractionDigits == other.minimumFractionDigits
1935 && roundingMode == other.roundingMode
1936 && symbols.equals(other.symbols);
1937 }
1938
1939 /**
1940 * Overrides hashCode
1941 */
1942 public int hashCode() {
1943 return super.hashCode() * 37 + positivePrefix.hashCode();
1944 // just enough fields for a reasonable distribution
1945 }
1946
1947 /**
1948 * Synthesizes a pattern string that represents the current state
1949 * of this Format object.
1950 * @see #applyPattern
1951 */
1952 public String toPattern() {
1953 return toPattern( false );
1954 }
1955
1956 /**
1957 * Synthesizes a localized pattern string that represents the current
1958 * state of this Format object.
1959 * @see #applyPattern
1960 */
1961 public String toLocalizedPattern() {
2651 // identical to the positive pattern, then prepend the minus sign to
2652 // the positive pattern to form the negative pattern.
2653 if (!gotNegative ||
2654 (negPrefixPattern.equals(posPrefixPattern)
2655 && negSuffixPattern.equals(posSuffixPattern))) {
2656 negSuffixPattern = posSuffixPattern;
2657 negPrefixPattern = "'-" + posPrefixPattern;
2658 }
2659
2660 expandAffixes();
2661 }
2662
2663 /**
2664 * Sets the maximum number of digits allowed in the integer portion of a
2665 * number.
2666 * For formatting numbers other than <code>BigInteger</code> and
2667 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2668 * 309 is used. Negative input values are replaced with 0.
2669 * @see NumberFormat#setMaximumIntegerDigits
2670 */
2671 public void setMaximumIntegerDigits(int newValue) {
2672 maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
2673 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2674 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
2675 if (minimumIntegerDigits > maximumIntegerDigits) {
2676 minimumIntegerDigits = maximumIntegerDigits;
2677 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2678 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
2679 }
2680 }
2681
2682 /**
2683 * Sets the minimum number of digits allowed in the integer portion of a
2684 * number.
2685 * For formatting numbers other than <code>BigInteger</code> and
2686 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2687 * 309 is used. Negative input values are replaced with 0.
2688 * @see NumberFormat#setMinimumIntegerDigits
2689 */
2690 public void setMinimumIntegerDigits(int newValue) {
2691 minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
2692 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2693 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
2694 if (minimumIntegerDigits > maximumIntegerDigits) {
2695 maximumIntegerDigits = minimumIntegerDigits;
2696 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2697 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
2698 }
2699 }
2700
2701 /**
2702 * Sets the maximum number of digits allowed in the fraction portion of a
2703 * number.
2704 * For formatting numbers other than <code>BigInteger</code> and
2705 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2706 * 340 is used. Negative input values are replaced with 0.
2707 * @see NumberFormat#setMaximumFractionDigits
2708 */
2709 public void setMaximumFractionDigits(int newValue) {
2710 maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
2711 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2712 DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
2713 if (minimumFractionDigits > maximumFractionDigits) {
2714 minimumFractionDigits = maximumFractionDigits;
2715 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2716 DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
2717 }
2718 }
2719
2720 /**
2721 * Sets the minimum number of digits allowed in the fraction portion of a
2722 * number.
2723 * For formatting numbers other than <code>BigInteger</code> and
2724 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2725 * 340 is used. Negative input values are replaced with 0.
2726 * @see NumberFormat#setMinimumFractionDigits
2727 */
2728 public void setMinimumFractionDigits(int newValue) {
2729 minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
2730 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2731 DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
2732 if (minimumFractionDigits > maximumFractionDigits) {
2733 maximumFractionDigits = minimumFractionDigits;
2734 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2735 DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
2736 }
2737 }
2738
2739 /**
2740 * Gets the maximum number of digits allowed in the integer portion of a
2741 * number.
2742 * For formatting numbers other than <code>BigInteger</code> and
2743 * <code>BigDecimal</code> objects, the lower of the return value and
2744 * 309 is used.
2745 * @see #setMaximumIntegerDigits
2746 */
2747 public int getMaximumIntegerDigits() {
2748 return maximumIntegerDigits;
2749 }
2750
2751 /**
2752 * Gets the minimum number of digits allowed in the integer portion of a
2753 * number.
2754 * For formatting numbers other than <code>BigInteger</code> and
2755 * <code>BigDecimal</code> objects, the lower of the return value and
2756 * 309 is used.
2757 * @see #setMinimumIntegerDigits
2758 */
2759 public int getMinimumIntegerDigits() {
2760 return minimumIntegerDigits;
2761 }
2762
2763 /**
2764 * Gets the maximum number of digits allowed in the fraction portion of a
2765 * number.
2766 * For formatting numbers other than <code>BigInteger</code> and
2767 * <code>BigDecimal</code> objects, the lower of the return value and
2768 * 340 is used.
2769 * @see #setMaximumFractionDigits
2770 */
2771 public int getMaximumFractionDigits() {
2772 return maximumFractionDigits;
2773 }
2774
2775 /**
2776 * Gets the minimum number of digits allowed in the fraction portion of a
2777 * number.
2778 * For formatting numbers other than <code>BigInteger</code> and
2779 * <code>BigDecimal</code> objects, the lower of the return value and
2780 * 340 is used.
2781 * @see #setMinimumFractionDigits
2782 */
2783 public int getMinimumFractionDigits() {
2784 return minimumFractionDigits;
2785 }
2786
2787 /**
2788 * Gets the currency used by this decimal format when formatting
2789 * currency values.
2790 * The currency is obtained by calling
2791 * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency}
2792 * on this number format's symbols.
2793 *
2794 * @return the currency used by this decimal format, or <code>null</code>
2795 * @since 1.4
2796 */
2797 public Currency getCurrency() {
2798 return symbols.getCurrency();
2799 }
2800
2801 /**
2802 * Sets the currency used by this number format when formatting
2803 * currency values. This does not update the minimum or maximum
2804 * number of fraction digits used by the number format.
2805 * The currency is set by calling
2806 * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency}
2807 * on this number format's symbols.
2808 *
2809 * @param currency the new currency to be used by this decimal format
2810 * @exception NullPointerException if <code>currency</code> is null
2811 * @since 1.4
2812 */
2813 public void setCurrency(Currency currency) {
2814 if (currency != symbols.getCurrency()) {
2815 symbols.setCurrency(currency);
2816 if (isCurrencyFormat) {
2817 expandAffixes();
2818 }
2819 }
2820 }
2821
2822 /**
2823 * Gets the {@link java.math.RoundingMode} used in this DecimalFormat.
2824 *
2825 * @return The <code>RoundingMode</code> used for this DecimalFormat.
2826 * @see #setRoundingMode(RoundingMode)
2827 * @since 1.6
2828 */
2829 public RoundingMode getRoundingMode() {
2830 return roundingMode;
2831 }
2832
2833 /**
2834 * Sets the {@link java.math.RoundingMode} used in this DecimalFormat.
2835 *
2836 * @param roundingMode The <code>RoundingMode</code> to be used
2837 * @see #getRoundingMode()
2838 * @exception NullPointerException if <code>roundingMode</code> is null.
2839 * @since 1.6
2840 */
2841 public void setRoundingMode(RoundingMode roundingMode) {
2842 if (roundingMode == null) {
2843 throw new NullPointerException();
2844 }
2845
2846 this.roundingMode = roundingMode;
2847 digitList.setRoundingMode(roundingMode);
2848 }
2849
2850 /**
2851 * Adjusts the minimum and maximum fraction digits to values that
2852 * are reasonable for the currency's default fraction digits.
2853 */
2854 void adjustForCurrencyDefaultFractionDigits() {
2855 Currency currency = symbols.getCurrency();
2856 if (currency == null) {
2857 try {
2858 currency = Currency.getInstance(symbols.getInternationalCurrencySymbol());
2859 } catch (IllegalArgumentException e) {
2860 }
2861 }
2862 if (currency != null) {
2863 int digits = currency.getDefaultFractionDigits();
2864 if (digits != -1) {
2865 int oldMinDigits = getMinimumFractionDigits();
2866 // Common patterns are "#.##", "#.00", "#".
2867 // Try to adjust all of them in a reasonable way.
2868 if (oldMinDigits == getMaximumFractionDigits()) {
2869 setMinimumFractionDigits(digits);
2870 setMaximumFractionDigits(digits);
2871 } else {
2872 setMinimumFractionDigits(Math.min(digits, oldMinDigits));
2873 setMaximumFractionDigits(digits);
2874 }
2875 }
2876 }
2877 }
2878
2879 /**
2880 * Reads the default serializable fields from the stream and performs
2881 * validations and adjustments for older serialized versions. The
2882 * validations and adjustments are:
2883 * <ol>
2884 * <li>
2885 * Verify that the superclass's digit count fields correctly reflect
2886 * the limits imposed on formatting numbers other than
2887 * <code>BigInteger</code> and <code>BigDecimal</code> objects. These
2888 * limits are stored in the superclass for serialization compatibility
2889 * with older versions, while the limits for <code>BigInteger</code> and
2890 * <code>BigDecimal</code> objects are kept in this class.
2891 * If, in the superclass, the minimum or maximum integer digit count is
2892 * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or
2893 * maximum fraction digit count is larger than
2894 * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid
2895 * and this method throws an <code>InvalidObjectException</code>.
2896 * <li>
2897 * If <code>serialVersionOnStream</code> is less than 4, initialize
2898 * <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN
2899 * RoundingMode.HALF_EVEN}. This field is new with version 4.
3253
3254 private static final char QUOTE = '\'';
3255
3256 private static FieldPosition[] EmptyFieldPositionArray = new FieldPosition[0];
3257
3258 // Upper limit on integer and fraction digits for a Java double
3259 static final int DOUBLE_INTEGER_DIGITS = 309;
3260 static final int DOUBLE_FRACTION_DIGITS = 340;
3261
3262 // Upper limit on integer and fraction digits for BigDecimal and BigInteger
3263 static final int MAXIMUM_INTEGER_DIGITS = Integer.MAX_VALUE;
3264 static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE;
3265
3266 // Proclaim JDK 1.1 serial compatibility.
3267 static final long serialVersionUID = 864413376551465018L;
3268
3269 /**
3270 * Cache to hold the NumberPattern of a Locale.
3271 */
3272 private static final ConcurrentMap<Locale, String> cachedLocaleData
3273 = new ConcurrentHashMap<Locale, String>(3);
3274 }
|
1 /*
2 * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 /*
27 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
28 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
29 *
30 * The original version of this source code and documentation is copyrighted
31 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
32 * materials are provided under terms of a License Agreement between Taligent
33 * and Sun. This technology is protected by multiple US and International
34 * patents. This notice and attribution to Taligent may not be removed.
35 * Taligent is a registered trademark of Taligent, Inc.
36 *
37 */
38
39 package java.text;
40
41 import java.io.IOException;
42 import java.io.InvalidObjectException;
43 import java.io.ObjectInputStream;
44 import java.math.BigDecimal;
45 import java.math.BigInteger;
46 import java.math.RoundingMode;
47 import java.text.spi.NumberFormatProvider;
48 import java.util.ArrayList;
49 import java.util.Currency;
50 import java.util.Locale;
51 import java.util.ResourceBundle;
52 import java.util.concurrent.ConcurrentHashMap;
53 import java.util.concurrent.ConcurrentMap;
54 import java.util.concurrent.atomic.AtomicInteger;
55 import java.util.concurrent.atomic.AtomicLong;
56 import sun.util.locale.provider.LocaleProviderAdapter;
57
58 /**
59 * <code>DecimalFormat</code> is a concrete subclass of
60 * <code>NumberFormat</code> that formats decimal numbers. It has a variety of
61 * features designed to make it possible to parse and format numbers in any
62 * locale, including support for Western, Arabic, and Indic digits. It also
63 * supports different kinds of numbers, including integers (123), fixed-point
64 * numbers (123.4), scientific notation (1.23E4), percentages (12%), and
65 * currency amounts ($123). All of these can be localized.
66 *
67 * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the
68 * default locale, call one of <code>NumberFormat</code>'s factory methods, such
69 * as <code>getInstance()</code>. In general, do not call the
70 * <code>DecimalFormat</code> constructors directly, since the
71 * <code>NumberFormat</code> factory methods may return subclasses other than
72 * <code>DecimalFormat</code>. If you need to customize the format object, do
73 * something like this:
74 *
75 * <blockquote><pre>
76 * NumberFormat f = NumberFormat.getInstance(loc);
382 * Creates a DecimalFormat using the default pattern and symbols
383 * for the default locale. This is a convenient way to obtain a
384 * DecimalFormat when internationalization is not the main concern.
385 * <p>
386 * To obtain standard formats for a given locale, use the factory methods
387 * on NumberFormat such as getNumberInstance. These factories will
388 * return the most appropriate sub-class of NumberFormat for a given
389 * locale.
390 *
391 * @see java.text.NumberFormat#getInstance
392 * @see java.text.NumberFormat#getNumberInstance
393 * @see java.text.NumberFormat#getCurrencyInstance
394 * @see java.text.NumberFormat#getPercentInstance
395 */
396 public DecimalFormat() {
397 Locale def = Locale.getDefault(Locale.Category.FORMAT);
398 // try to get the pattern from the cache
399 String pattern = cachedLocaleData.get(def);
400 if (pattern == null) { /* cache miss */
401 // Get the pattern for the default locale.
402 LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class, def);
403 switch (adapter.getAdapterType()) {
404 case HOST:
405 case SPI:
406 adapter = LocaleProviderAdapter.getResourceBundleBased();
407 break;
408 }
409 ResourceBundle rb = adapter.getLocaleData().getNumberFormatData(def);
410 String[] all = rb.getStringArray("NumberPatterns");
411 pattern = all[0];
412 /* update cache */
413 cachedLocaleData.putIfAbsent(def, pattern);
414 }
415
416 // Always applyPattern after the symbols are set
417 this.symbols = DecimalFormatSymbols.getInstance(def);
418 applyPattern(pattern, false);
419 }
420
421
422 /**
423 * Creates a DecimalFormat using the given pattern and the symbols
424 * for the default locale. This is a convenient way to obtain a
425 * DecimalFormat when internationalization is not the main concern.
426 * <p>
427 * To obtain standard formats for a given locale, use the factory methods
428 * on NumberFormat such as getNumberInstance. These factories will
429 * return the most appropriate sub-class of NumberFormat for a given
430 * locale.
431 *
432 * @param pattern A non-localized pattern string.
433 * @exception NullPointerException if <code>pattern</code> is null
434 * @exception IllegalArgumentException if the given pattern is invalid.
435 * @see java.text.NumberFormat#getInstance
436 * @see java.text.NumberFormat#getNumberInstance
437 * @see java.text.NumberFormat#getCurrencyInstance
438 * @see java.text.NumberFormat#getPercentInstance
439 */
440 public DecimalFormat(String pattern) {
441 // Always applyPattern after the symbols are set
442 this.symbols = DecimalFormatSymbols.getInstance(Locale.getDefault(Locale.Category.FORMAT));
443 applyPattern(pattern, false);
444 }
445
446
447 /**
448 * Creates a DecimalFormat using the given pattern and symbols.
449 * Use this constructor when you need to completely customize the
450 * behavior of the format.
451 * <p>
452 * To obtain standard formats for a given
453 * locale, use the factory methods on NumberFormat such as
454 * getInstance or getCurrencyInstance. If you need only minor adjustments
455 * to a standard format, you can modify the format returned by
456 * a NumberFormat factory method.
457 *
458 * @param pattern a non-localized pattern string
459 * @param symbols the set of symbols to be used
460 * @exception NullPointerException if any of the given arguments is null
461 * @exception IllegalArgumentException if the given pattern is invalid
462 * @see java.text.NumberFormat#getInstance
476 /**
477 * Formats a number and appends the resulting text to the given string
478 * buffer.
479 * The number can be of any subclass of {@link java.lang.Number}.
480 * <p>
481 * This implementation uses the maximum precision permitted.
482 * @param number the number to format
483 * @param toAppendTo the <code>StringBuffer</code> to which the formatted
484 * text is to be appended
485 * @param pos On input: an alignment field, if desired.
486 * On output: the offsets of the alignment field.
487 * @return the value passed in as <code>toAppendTo</code>
488 * @exception IllegalArgumentException if <code>number</code> is
489 * null or not an instance of <code>Number</code>.
490 * @exception NullPointerException if <code>toAppendTo</code> or
491 * <code>pos</code> is null
492 * @exception ArithmeticException if rounding is needed with rounding
493 * mode being set to RoundingMode.UNNECESSARY
494 * @see java.text.FieldPosition
495 */
496 @Override
497 public final StringBuffer format(Object number,
498 StringBuffer toAppendTo,
499 FieldPosition pos) {
500 if (number instanceof Long || number instanceof Integer ||
501 number instanceof Short || number instanceof Byte ||
502 number instanceof AtomicInteger ||
503 number instanceof AtomicLong ||
504 (number instanceof BigInteger &&
505 ((BigInteger)number).bitLength () < 64)) {
506 return format(((Number)number).longValue(), toAppendTo, pos);
507 } else if (number instanceof BigDecimal) {
508 return format((BigDecimal)number, toAppendTo, pos);
509 } else if (number instanceof BigInteger) {
510 return format((BigInteger)number, toAppendTo, pos);
511 } else if (number instanceof Number) {
512 return format(((Number)number).doubleValue(), toAppendTo, pos);
513 } else {
514 throw new IllegalArgumentException("Cannot format given Object as a Number");
515 }
516 }
517
518 /**
519 * Formats a double to produce a string.
520 * @param number The double to format
521 * @param result where the text is to be appended
522 * @param fieldPosition On input: an alignment field, if desired.
523 * On output: the offsets of the alignment field.
524 * @exception ArithmeticException if rounding is needed with rounding
525 * mode being set to RoundingMode.UNNECESSARY
526 * @return The formatted number string
527 * @see java.text.FieldPosition
528 */
529 @Override
530 public StringBuffer format(double number, StringBuffer result,
531 FieldPosition fieldPosition) {
532 fieldPosition.setBeginIndex(0);
533 fieldPosition.setEndIndex(0);
534
535 return format(number, result, fieldPosition.getFieldDelegate());
536 }
537
538 /**
539 * Formats a double to produce a string.
540 * @param number The double to format
541 * @param result where the text is to be appended
542 * @param delegate notified of locations of sub fields
543 * @exception ArithmeticException if rounding is needed with rounding
544 * mode being set to RoundingMode.UNNECESSARY
545 * @return The formatted number string
546 */
547 private StringBuffer format(double number, StringBuffer result,
548 FieldDelegate delegate) {
549 if (Double.isNaN(number) ||
611
612 digitList.set(isNegative, number, useExponentialNotation ?
613 maxIntDigits + maxFraDigits : maxFraDigits,
614 !useExponentialNotation);
615 return subformat(result, delegate, isNegative, false,
616 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
617 }
618 }
619
620 /**
621 * Format a long to produce a string.
622 * @param number The long to format
623 * @param result where the text is to be appended
624 * @param fieldPosition On input: an alignment field, if desired.
625 * On output: the offsets of the alignment field.
626 * @exception ArithmeticException if rounding is needed with rounding
627 * mode being set to RoundingMode.UNNECESSARY
628 * @return The formatted number string
629 * @see java.text.FieldPosition
630 */
631 @Override
632 public StringBuffer format(long number, StringBuffer result,
633 FieldPosition fieldPosition) {
634 fieldPosition.setBeginIndex(0);
635 fieldPosition.setEndIndex(0);
636
637 return format(number, result, fieldPosition.getFieldDelegate());
638 }
639
640 /**
641 * Format a long to produce a string.
642 * @param number The long to format
643 * @param result where the text is to be appended
644 * @param delegate notified of locations of sub fields
645 * @return The formatted number string
646 * @exception ArithmeticException if rounding is needed with rounding
647 * mode being set to RoundingMode.UNNECESSARY
648 * @see java.text.FieldPosition
649 */
650 private StringBuffer format(long number, StringBuffer result,
651 FieldDelegate delegate) {
826
827 /**
828 * Formats an Object producing an <code>AttributedCharacterIterator</code>.
829 * You can use the returned <code>AttributedCharacterIterator</code>
830 * to build the resulting String, as well as to determine information
831 * about the resulting String.
832 * <p>
833 * Each attribute key of the AttributedCharacterIterator will be of type
834 * <code>NumberFormat.Field</code>, with the attribute value being the
835 * same as the attribute key.
836 *
837 * @exception NullPointerException if obj is null.
838 * @exception IllegalArgumentException when the Format cannot format the
839 * given object.
840 * @exception ArithmeticException if rounding is needed with rounding
841 * mode being set to RoundingMode.UNNECESSARY
842 * @param obj The object to format
843 * @return AttributedCharacterIterator describing the formatted value.
844 * @since 1.4
845 */
846 @Override
847 public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
848 CharacterIteratorFieldDelegate delegate =
849 new CharacterIteratorFieldDelegate();
850 StringBuffer sb = new StringBuffer();
851
852 if (obj instanceof Double || obj instanceof Float) {
853 format(((Number)obj).doubleValue(), sb, delegate);
854 } else if (obj instanceof Long || obj instanceof Integer ||
855 obj instanceof Short || obj instanceof Byte ||
856 obj instanceof AtomicInteger || obj instanceof AtomicLong) {
857 format(((Number)obj).longValue(), sb, delegate);
858 } else if (obj instanceof BigDecimal) {
859 format((BigDecimal)obj, sb, delegate);
860 } else if (obj instanceof BigInteger) {
861 format((BigInteger)obj, sb, delegate, false);
862 } else if (obj == null) {
863 throw new NullPointerException(
864 "formatToCharacterIterator must be passed non-null object");
865 } else {
866 throw new IllegalArgumentException(
1252 * constructed by {@link java.math.BigDecimal#BigDecimal(String)}
1253 * for corresponding strings in locale-independent format. The
1254 * special cases negative and positive infinity and NaN are returned
1255 * as <code>Double</code> instances holding the values of the
1256 * corresponding <code>Double</code> constants.
1257 * </ul>
1258 * <p>
1259 * <code>DecimalFormat</code> parses all Unicode characters that represent
1260 * decimal digits, as defined by <code>Character.digit()</code>. In
1261 * addition, <code>DecimalFormat</code> also recognizes as digits the ten
1262 * consecutive characters starting with the localized zero digit defined in
1263 * the <code>DecimalFormatSymbols</code> object.
1264 *
1265 * @param text the string to be parsed
1266 * @param pos A <code>ParsePosition</code> object with index and error
1267 * index information as described above.
1268 * @return the parsed value, or <code>null</code> if the parse fails
1269 * @exception NullPointerException if <code>text</code> or
1270 * <code>pos</code> is null.
1271 */
1272 @Override
1273 public Number parse(String text, ParsePosition pos) {
1274 // special case NaN
1275 if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) {
1276 pos.index = pos.index + symbols.getNaN().length();
1277 return new Double(Double.NaN);
1278 }
1279
1280 boolean[] status = new boolean[STATUS_LENGTH];
1281 if (!subparse(text, pos, positivePrefix, negativePrefix, digitList, false, status)) {
1282 return null;
1283 }
1284
1285 // special case INFINITY
1286 if (status[STATUS_INFINITE]) {
1287 if (status[STATUS_POSITIVE] == (multiplier >= 0)) {
1288 return new Double(Double.POSITIVE_INFINITY);
1289 } else {
1290 return new Double(Double.NEGATIVE_INFINITY);
1291 }
1292 }
1886 * @see #setParseBigDecimal
1887 * @since 1.5
1888 */
1889 public boolean isParseBigDecimal() {
1890 return parseBigDecimal;
1891 }
1892
1893 /**
1894 * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1895 * method returns <code>BigDecimal</code>.
1896 * @see #isParseBigDecimal
1897 * @since 1.5
1898 */
1899 public void setParseBigDecimal(boolean newValue) {
1900 parseBigDecimal = newValue;
1901 }
1902
1903 /**
1904 * Standard override; no change in semantics.
1905 */
1906 @Override
1907 public Object clone() {
1908 DecimalFormat other = (DecimalFormat) super.clone();
1909 other.symbols = (DecimalFormatSymbols) symbols.clone();
1910 other.digitList = (DigitList) digitList.clone();
1911 return other;
1912 }
1913
1914 /**
1915 * Overrides equals
1916 */
1917 @Override
1918 public boolean equals(Object obj)
1919 {
1920 if (obj == null) return false;
1921 if (!super.equals(obj)) return false; // super does class check
1922 DecimalFormat other = (DecimalFormat) obj;
1923 return ((posPrefixPattern == other.posPrefixPattern &&
1924 positivePrefix.equals(other.positivePrefix))
1925 || (posPrefixPattern != null &&
1926 posPrefixPattern.equals(other.posPrefixPattern)))
1927 && ((posSuffixPattern == other.posSuffixPattern &&
1928 positiveSuffix.equals(other.positiveSuffix))
1929 || (posSuffixPattern != null &&
1930 posSuffixPattern.equals(other.posSuffixPattern)))
1931 && ((negPrefixPattern == other.negPrefixPattern &&
1932 negativePrefix.equals(other.negativePrefix))
1933 || (negPrefixPattern != null &&
1934 negPrefixPattern.equals(other.negPrefixPattern)))
1935 && ((negSuffixPattern == other.negSuffixPattern &&
1936 negativeSuffix.equals(other.negativeSuffix))
1937 || (negSuffixPattern != null &&
1938 negSuffixPattern.equals(other.negSuffixPattern)))
1939 && multiplier == other.multiplier
1940 && groupingSize == other.groupingSize
1941 && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown
1942 && parseBigDecimal == other.parseBigDecimal
1943 && useExponentialNotation == other.useExponentialNotation
1944 && (!useExponentialNotation ||
1945 minExponentDigits == other.minExponentDigits)
1946 && maximumIntegerDigits == other.maximumIntegerDigits
1947 && minimumIntegerDigits == other.minimumIntegerDigits
1948 && maximumFractionDigits == other.maximumFractionDigits
1949 && minimumFractionDigits == other.minimumFractionDigits
1950 && roundingMode == other.roundingMode
1951 && symbols.equals(other.symbols);
1952 }
1953
1954 /**
1955 * Overrides hashCode
1956 */
1957 @Override
1958 public int hashCode() {
1959 return super.hashCode() * 37 + positivePrefix.hashCode();
1960 // just enough fields for a reasonable distribution
1961 }
1962
1963 /**
1964 * Synthesizes a pattern string that represents the current state
1965 * of this Format object.
1966 * @see #applyPattern
1967 */
1968 public String toPattern() {
1969 return toPattern( false );
1970 }
1971
1972 /**
1973 * Synthesizes a localized pattern string that represents the current
1974 * state of this Format object.
1975 * @see #applyPattern
1976 */
1977 public String toLocalizedPattern() {
2667 // identical to the positive pattern, then prepend the minus sign to
2668 // the positive pattern to form the negative pattern.
2669 if (!gotNegative ||
2670 (negPrefixPattern.equals(posPrefixPattern)
2671 && negSuffixPattern.equals(posSuffixPattern))) {
2672 negSuffixPattern = posSuffixPattern;
2673 negPrefixPattern = "'-" + posPrefixPattern;
2674 }
2675
2676 expandAffixes();
2677 }
2678
2679 /**
2680 * Sets the maximum number of digits allowed in the integer portion of a
2681 * number.
2682 * For formatting numbers other than <code>BigInteger</code> and
2683 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2684 * 309 is used. Negative input values are replaced with 0.
2685 * @see NumberFormat#setMaximumIntegerDigits
2686 */
2687 @Override
2688 public void setMaximumIntegerDigits(int newValue) {
2689 maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
2690 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2691 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
2692 if (minimumIntegerDigits > maximumIntegerDigits) {
2693 minimumIntegerDigits = maximumIntegerDigits;
2694 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2695 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
2696 }
2697 }
2698
2699 /**
2700 * Sets the minimum number of digits allowed in the integer portion of a
2701 * number.
2702 * For formatting numbers other than <code>BigInteger</code> and
2703 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2704 * 309 is used. Negative input values are replaced with 0.
2705 * @see NumberFormat#setMinimumIntegerDigits
2706 */
2707 @Override
2708 public void setMinimumIntegerDigits(int newValue) {
2709 minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
2710 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2711 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
2712 if (minimumIntegerDigits > maximumIntegerDigits) {
2713 maximumIntegerDigits = minimumIntegerDigits;
2714 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2715 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
2716 }
2717 }
2718
2719 /**
2720 * Sets the maximum number of digits allowed in the fraction portion of a
2721 * number.
2722 * For formatting numbers other than <code>BigInteger</code> and
2723 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2724 * 340 is used. Negative input values are replaced with 0.
2725 * @see NumberFormat#setMaximumFractionDigits
2726 */
2727 @Override
2728 public void setMaximumFractionDigits(int newValue) {
2729 maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
2730 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2731 DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
2732 if (minimumFractionDigits > maximumFractionDigits) {
2733 minimumFractionDigits = maximumFractionDigits;
2734 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2735 DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
2736 }
2737 }
2738
2739 /**
2740 * Sets the minimum number of digits allowed in the fraction portion of a
2741 * number.
2742 * For formatting numbers other than <code>BigInteger</code> and
2743 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2744 * 340 is used. Negative input values are replaced with 0.
2745 * @see NumberFormat#setMinimumFractionDigits
2746 */
2747 @Override
2748 public void setMinimumFractionDigits(int newValue) {
2749 minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
2750 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2751 DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
2752 if (minimumFractionDigits > maximumFractionDigits) {
2753 maximumFractionDigits = minimumFractionDigits;
2754 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2755 DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
2756 }
2757 }
2758
2759 /**
2760 * Gets the maximum number of digits allowed in the integer portion of a
2761 * number.
2762 * For formatting numbers other than <code>BigInteger</code> and
2763 * <code>BigDecimal</code> objects, the lower of the return value and
2764 * 309 is used.
2765 * @see #setMaximumIntegerDigits
2766 */
2767 @Override
2768 public int getMaximumIntegerDigits() {
2769 return maximumIntegerDigits;
2770 }
2771
2772 /**
2773 * Gets the minimum number of digits allowed in the integer portion of a
2774 * number.
2775 * For formatting numbers other than <code>BigInteger</code> and
2776 * <code>BigDecimal</code> objects, the lower of the return value and
2777 * 309 is used.
2778 * @see #setMinimumIntegerDigits
2779 */
2780 @Override
2781 public int getMinimumIntegerDigits() {
2782 return minimumIntegerDigits;
2783 }
2784
2785 /**
2786 * Gets the maximum number of digits allowed in the fraction portion of a
2787 * number.
2788 * For formatting numbers other than <code>BigInteger</code> and
2789 * <code>BigDecimal</code> objects, the lower of the return value and
2790 * 340 is used.
2791 * @see #setMaximumFractionDigits
2792 */
2793 @Override
2794 public int getMaximumFractionDigits() {
2795 return maximumFractionDigits;
2796 }
2797
2798 /**
2799 * Gets the minimum number of digits allowed in the fraction portion of a
2800 * number.
2801 * For formatting numbers other than <code>BigInteger</code> and
2802 * <code>BigDecimal</code> objects, the lower of the return value and
2803 * 340 is used.
2804 * @see #setMinimumFractionDigits
2805 */
2806 @Override
2807 public int getMinimumFractionDigits() {
2808 return minimumFractionDigits;
2809 }
2810
2811 /**
2812 * Gets the currency used by this decimal format when formatting
2813 * currency values.
2814 * The currency is obtained by calling
2815 * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency}
2816 * on this number format's symbols.
2817 *
2818 * @return the currency used by this decimal format, or <code>null</code>
2819 * @since 1.4
2820 */
2821 @Override
2822 public Currency getCurrency() {
2823 return symbols.getCurrency();
2824 }
2825
2826 /**
2827 * Sets the currency used by this number format when formatting
2828 * currency values. This does not update the minimum or maximum
2829 * number of fraction digits used by the number format.
2830 * The currency is set by calling
2831 * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency}
2832 * on this number format's symbols.
2833 *
2834 * @param currency the new currency to be used by this decimal format
2835 * @exception NullPointerException if <code>currency</code> is null
2836 * @since 1.4
2837 */
2838 @Override
2839 public void setCurrency(Currency currency) {
2840 if (currency != symbols.getCurrency()) {
2841 symbols.setCurrency(currency);
2842 if (isCurrencyFormat) {
2843 expandAffixes();
2844 }
2845 }
2846 }
2847
2848 /**
2849 * Gets the {@link java.math.RoundingMode} used in this DecimalFormat.
2850 *
2851 * @return The <code>RoundingMode</code> used for this DecimalFormat.
2852 * @see #setRoundingMode(RoundingMode)
2853 * @since 1.6
2854 */
2855 @Override
2856 public RoundingMode getRoundingMode() {
2857 return roundingMode;
2858 }
2859
2860 /**
2861 * Sets the {@link java.math.RoundingMode} used in this DecimalFormat.
2862 *
2863 * @param roundingMode The <code>RoundingMode</code> to be used
2864 * @see #getRoundingMode()
2865 * @exception NullPointerException if <code>roundingMode</code> is null.
2866 * @since 1.6
2867 */
2868 @Override
2869 public void setRoundingMode(RoundingMode roundingMode) {
2870 if (roundingMode == null) {
2871 throw new NullPointerException();
2872 }
2873
2874 this.roundingMode = roundingMode;
2875 digitList.setRoundingMode(roundingMode);
2876 }
2877
2878 /**
2879 * Reads the default serializable fields from the stream and performs
2880 * validations and adjustments for older serialized versions. The
2881 * validations and adjustments are:
2882 * <ol>
2883 * <li>
2884 * Verify that the superclass's digit count fields correctly reflect
2885 * the limits imposed on formatting numbers other than
2886 * <code>BigInteger</code> and <code>BigDecimal</code> objects. These
2887 * limits are stored in the superclass for serialization compatibility
2888 * with older versions, while the limits for <code>BigInteger</code> and
2889 * <code>BigDecimal</code> objects are kept in this class.
2890 * If, in the superclass, the minimum or maximum integer digit count is
2891 * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or
2892 * maximum fraction digit count is larger than
2893 * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid
2894 * and this method throws an <code>InvalidObjectException</code>.
2895 * <li>
2896 * If <code>serialVersionOnStream</code> is less than 4, initialize
2897 * <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN
2898 * RoundingMode.HALF_EVEN}. This field is new with version 4.
3252
3253 private static final char QUOTE = '\'';
3254
3255 private static FieldPosition[] EmptyFieldPositionArray = new FieldPosition[0];
3256
3257 // Upper limit on integer and fraction digits for a Java double
3258 static final int DOUBLE_INTEGER_DIGITS = 309;
3259 static final int DOUBLE_FRACTION_DIGITS = 340;
3260
3261 // Upper limit on integer and fraction digits for BigDecimal and BigInteger
3262 static final int MAXIMUM_INTEGER_DIGITS = Integer.MAX_VALUE;
3263 static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE;
3264
3265 // Proclaim JDK 1.1 serial compatibility.
3266 static final long serialVersionUID = 864413376551465018L;
3267
3268 /**
3269 * Cache to hold the NumberPattern of a Locale.
3270 */
3271 private static final ConcurrentMap<Locale, String> cachedLocaleData
3272 = new ConcurrentHashMap<>(3);
3273 }
|