Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
What I'd like is a method to convert a double to a string which rounds using the half-up method. I.e. if the decimal to be rounded is a 5, it always rounds up the previous number. This is the standard method of rounding most people expect in most situations. I also would like only significant digits to be displayed. That is there should not be any trailing zeroes. I know one method of doing t...
Can I do it with System.out.print? Thank you.
Using DecimalFormat gives no parse exception when using this kind of number: 123hello which is obviously not really a number, and converts to 123.0 value. How can I avoid this kind of behaviour? As a side note hello123 does give an exception, which is correct. Thanks, Marcel
What is the easiest and correct way to convert a String number with commas (for example: 835,111.2) to a Double instance. Thanks, Rod
I'm trying to read some BigDecimal values from the string. Let's say I have this String: "1,000,000,000.999999999999999" and I want to get a BigDecimal out of it. What is the way to do it? First of all, I don't like the solutions using string replaces (replacing commas etc.). I think there should be some neat formatter to do that job for me. I've found a DecimalFormatter class, however as it ...
I am using the following DecimalFormat pattern: // Use ThreadLocal to ensure thread safety. private static final ThreadLocal <NumberFormat> numberFormat = new ThreadLocal <NumberFormat>() { @Override protected NumberFormat initialValue() { return new DecimalFormat("#,##0.00"); } }; This performs the following conversions: 1 -> 1.00 1.1 -> 1.10 1.12 -&...
I would like to replace "." by "," in a String/double that I want to write to a file. Using the following Java code double myDouble = myObject.getDoubleMethod(); // returns 38.1882352941176 System.out.println(myDouble); String myDoubleString = "" + myDouble; System.out.println(myDoubleString); myDoubleString.replace(".", ","); System.out.println(myDoubleString); myDoubleString.replace('.',...
How do I convert scientific notation to regular int For example: 1.23E2 I would like to convert it to 123 Thanks.
I want to format 3 digit floats in Java so they line up vertically such that they look like: 123.45 99 23.2 45 When I use DecimalFormat class, I get close, but I want to insert spaces when the item has 1 or 2 digits. My code: DecimalFormat formatter = new java.text.DecimalFormat("####.##"); float [] floats = [123.45, 99.0, 23.2, 45.0]; for(int i=0; i<floats.length; i++) { float ...
while retrieving the value it is giving in the exponential format for big numbers. while (cells.hasNext ()) { HSSFCell cell = cells.next (); System.out.println ("Cell No.: " + cell.getCellNum ()); /* * Now we will get the cell type and display the values * accordingly. */ switch (cell.getCellType ()) { case HSSFCell.CELL_TYPE_NUMERIC : { // cell type numeric. System.out.println ("N...
May I know how I can escape a string to be passed into decimal format? // currencySymbolPrefix can be any string. NumberFormat numberFormat = new DecimalFormat(currencySymbolPrefix + "#,##0.00"); How can I escape currencySymbolPrefix, so that it may contains any characters including '#', and will not be interpreted as one of the pattern. Please do not suggest NumberFormat numberFormat = ne...
I'm trying to count trailing zeros of numbers that are resulted from factorials (meaning that the numbers get quite large). Following code takes a number, compute the factorial of the number, and count the trailing zeros. However, when the number is about as large as 25!, numZeros don't work. public static void main(String[] args) { BufferedReader br = new BufferedReader(new InputStreamRea...
Can any one give me some predefined methods or user defined methods to convert string numbers(example : 123455) to comma separated integer value (example : 1,23,455). Thanks in advance, sathish
String p="1,234"; Double d=Double.valueOf(p); System.out.println(d); return a error. what the besy way to get 1.234 ? better than: p=p.replaceAll(",","."); thanks a lot :)
I am writing a JSF (ICEfaces) application using resource bundles to handle internationalisation. The application nicely applies the (default) Dutch "nl" locale for the resource bundle but fails to apply the same locale on formatting floating point numbers, even if I explicitly set the locale for a page using <f:view locale="nl">. How do I make floating point numbers follow the current l...
Java uses period in decimals, e.g. 1/2 = 0.5 Is there any way to make it use comma instead, as in 1/2 = 0,5? And not to use comma for thousands (as in one hundred thousand = 100,000) but use space instead (100 000)? When it comes to output I suppose I could use all sorts of string format functions, but the problem is input (JTable). Some columns require Double format so users must enter som...
float per = (num / (float)totbrwdbksint) * 100; i m getting the value of per as say 29.475342 . i want it to round off upto two decimal places only.like 29.48 .how to achieve this?
I need to format decimal numbers with patterns in J2ME just like java DecimalFormat. I see an option to port Format/NumberFormat/DecimalFormat. Can you suggest ready to use implementation or library? Thanks!
Well, I am attempting to read a text file that looks like this: FTFFFTTFFTFT 3054 FTFFFTTFFTFT 4674 FTFTFFTTTFTF ... etc And when I am reading it, everything compiles and works wonderfully, putting everything into arrays like this: studentID[0] = 3054 studentID[1] = 4674 ... etc studentAnswers[0] = FTFFFTTFFTFT studentAnswers[1] = FTFTFFTTTFTF However, if the studentID has a leading or t...
How can I format Floats in Java so that the float component is displayed only if it's not zero? For example: 123.45 -> 123.45 99.0 -> 99 23.2 -> 23.2 45.0 -> 45 Edit: I forgot to mention - I'm still on Java 1.4 - sorry!
I get a java.lang.NumberFormatException: For input string: "1.7023484830876092" trimming the string to 1.70234, does solve the problem, but before slicing the string myself I'm wondering whether its possible to use some java methods to leverage the capacity of the target object. kind regards, jeroen.
   /*
    * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    *
    * This code is free software; you can redistribute it and/or modify it
    * under the terms of the GNU General Public License version 2 only, as
    * published by the Free Software Foundation.  Sun designates this
    * particular file as subject to the "Classpath" exception as provided
    * by Sun in the LICENSE file that accompanied this code.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   * CA 95054 USA or visit www.sun.com if you need additional information or
   * have any questions.
   */
  
  /*
   * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
   * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
   *
   *   The original version of this source code and documentation is copyrighted
   * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
   * materials are provided under terms of a License Agreement between Taligent
   * and Sun. This technology is protected by multiple US and International
   * patents. This notice and attribution to Taligent may not be removed.
   *   Taligent is a registered trademark of Taligent, Inc.
   *
   */
  
  package java.text;
  
  import java.util.Locale;
DecimalFormat is a concrete subclass of NumberFormat that formats decimal numbers. It has a variety of features designed to make it possible to parse and format numbers in any locale, including support for Western, Arabic, and Indic digits. It also supports different kinds of numbers, including integers (123), fixed-point numbers (123.4), scientific notation (1.23E4), percentages (12%), and currency amounts ($123). All of these can be localized.

To obtain a NumberFormat for a specific locale, including the default locale, call one of NumberFormat's factory methods, such as getInstance(). In general, do not call the DecimalFormat constructors directly, since the NumberFormat factory methods may return subclasses other than DecimalFormat. If you need to customize the format object, do something like this:

 NumberFormat f = NumberFormat.getInstance(loc);
 if (f instanceof DecimalFormat) {
     ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
 }
 

A DecimalFormat comprises a pattern and a set of symbols. The pattern may be set directly using applyPattern(), or indirectly using the API methods. The symbols are stored in a DecimalFormatSymbols object. When using the NumberFormat factory methods, the pattern and symbols are read from localized ResourceBundles.

Patterns

DecimalFormat patterns have the following syntax:
 Pattern:
         PositivePattern
         PositivePattern ; NegativePattern
 PositivePattern:
         Prefixopt Number Suffixopt
 NegativePattern:
         Prefixopt Number Suffixopt
 Prefix:
         any Unicode characters except \uFFFE, \uFFFF, and special characters
 Suffix:
         any Unicode characters except \uFFFE, \uFFFF, and special characters
 Number:
         Integer Exponentopt
         Integer . Fraction Exponentopt
 Integer:
         MinimumInteger
         #
         # Integer
         # , Integer
 MinimumInteger:
         0
         0 MinimumInteger
         0 , MinimumInteger
 Fraction:
         MinimumFractionopt OptionalFractionopt
 MinimumFraction:
         0 MinimumFractionopt
 OptionalFraction:
         # OptionalFractionopt
 Exponent:
         E MinimumExponent
 MinimumExponent:
         0 MinimumExponentopt
 

A DecimalFormat pattern contains a positive and negative subpattern, for example, "#,##0.00;(#,##0.00)". Each subpattern has a prefix, numeric part, and suffix. The negative subpattern is optional; if absent, then the positive subpattern prefixed with the localized minus sign ('-' in most locales) is used as the negative subpattern. That is, "0.00" alone is equivalent to "0.00;-0.00". If there is an explicit negative subpattern, it serves only to specify the negative prefix and suffix; the number of digits, minimal digits, and other characteristics are all the same as the positive pattern. That means that "#,##0.0#;(#)" produces precisely the same behavior as "#,##0.0#;(#,##0.0#)".

The prefixes, suffixes, and various symbols used for infinity, digits, thousands separators, decimal separators, etc. may be set to arbitrary values, and they will appear properly during formatting. However, care must be taken that the symbols and strings do not conflict, or parsing will be unreliable. For example, either the positive and negative prefixes or the suffixes must be distinct for DecimalFormat.parse() to be able to distinguish positive from negative values. (If they are identical, then DecimalFormat will behave as if no negative subpattern was specified.) Another example is that the decimal separator and thousands separator should be distinct characters, or parsing will be impossible.

The grouping separator is commonly used for thousands, but in some countries it separates ten-thousands. The grouping size is a constant number of digits between the grouping characters, such as 3 for 100,000,000 or 4 for 1,0000,0000. If you supply a pattern with multiple grouping characters, the interval between the last one and the end of the integer is the one that is used. So "#,##,###,####" == "######,####" == "##,####,####".

Special Pattern Characters

Many characters in a pattern are taken literally; they are matched during parsing and output unchanged during formatting. Special characters, on the other hand, stand for other characters, strings, or classes of characters. They must be quoted, unless noted otherwise, if they are to appear in the prefix or suffix as literals.

The characters listed here are used in non-localized patterns. Localized patterns use the corresponding characters taken from this formatter's DecimalFormatSymbols object instead, and these characters lose their special status. Two exceptions are the currency sign and quote, which are not localized.

Symbol Location Localized? Meaning
0 Number Yes Digit
# Number Yes Digit, zero shows as absent
. Number Yes Decimal separator or monetary decimal separator
- Number Yes Minus sign
, Number Yes Grouping separator
E Number Yes Separates mantissa and exponent in scientific notation. Need not be quoted in prefix or suffix.
; Subpattern boundary Yes Separates positive and negative subpatterns
% Prefix or suffix Yes Multiply by 100 and show as percentage
\u2030 Prefix or suffix Yes Multiply by 1000 and show as per mille value
¤ (\u00A4) Prefix or suffix No Currency sign, replaced by currency symbol. If doubled, replaced by international currency symbol. If present in a pattern, the monetary decimal separator is used instead of the decimal separator.
' Prefix or suffix No Used to quote special characters in a prefix or suffix, for example, "'#'#" formats 123 to "#123". To create a single quote itself, use two in a row: "# o''clock".

Scientific Notation

Numbers in scientific notation are expressed as the product of a mantissa and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3. The mantissa is often in the range 1.0 <= x < 10.0, but it need not be. DecimalFormat can be instructed to format and parse scientific notation only via a pattern; there is currently no factory method that creates a scientific notation format. In a pattern, the exponent character immediately followed by one or more digit characters indicates scientific notation. Example: "0.###E0" formats the number 1234 as "1.234E3".

  • The number of digit characters after the exponent character gives the minimum exponent digit count. There is no maximum. Negative exponents are formatted using the localized minus sign, not the prefix and suffix from the pattern. This allows patterns such as "0.###E0 m/s".
  • The minimum and maximum number of integer digits are interpreted together:
    • If the maximum number of integer digits is greater than their minimum number and greater than 1, it forces the exponent to be a multiple of the maximum number of integer digits, and the minimum number of integer digits to be interpreted as 1. The most common use of this is to generate engineering notation, in which the exponent is a multiple of three, e.g., "##0.#####E0". Using this pattern, the number 12345 formats to "12.345E3", and 123456 formats to "123.456E3".
    • Otherwise, the minimum number of integer digits is achieved by adjusting the exponent. Example: 0.00123 formatted with "00.###E0" yields "12.3E-4".
  • The number of significant digits in the mantissa is the sum of the minimum integer and maximum fraction digits, and is unaffected by the maximum integer digits. For example, 12345 formatted with "##0.##E0" is "12.3E3". To show all digits, set the significant digits count to zero. The number of significant digits does not affect parsing.
  • Exponential patterns may not contain grouping separators.

Rounding

DecimalFormat provides rounding modes defined in java.math.RoundingMode for formatting. By default, it uses RoundingMode.HALF_EVEN.

Digits

For formatting, DecimalFormat uses the ten consecutive characters starting with the localized zero digit defined in the DecimalFormatSymbols object as digits. For parsing, these digits as well as all Unicode decimal digits, as defined by Character.digit, are recognized.

Special Values

NaN is formatted as a string, which typically has a single character \uFFFD. This string is determined by the DecimalFormatSymbols object. This is the only value for which the prefixes and suffixes are not used.

Infinity is formatted as a string, which typically has a single character \u221E, with the positive or negative prefixes and suffixes applied. The infinity string is determined by the DecimalFormatSymbols object.

Negative zero ("-0") parses to

  • BigDecimal(0) if isParseBigDecimal() is true,
  • Long(0) if isParseBigDecimal() is false and isParseIntegerOnly() is true,
  • Double(-0.0) if both isParseBigDecimal() and isParseIntegerOnly() are false.

Synchronization

Decimal formats are generally not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

Example

 // Print out a number using the localized number, integer, currency,
 // and percent format for each locale
 Locale[] locales = NumberFormat.getAvailableLocales();
 double myNumber = -1234.56;
 NumberFormat form;
 for (int j=0; j<4; ++j) {
     System.out.println("FORMAT");
     for (int i = 0; i < locales.length; ++i) {
         if (locales[i].getCountry().length() == 0) {
            continue; // Skip language-only locales
         }
         System.out.print(locales[i].getDisplayName());
         switch (j) {
         case 0:
             form = NumberFormat.getInstance(locales[i]); break;
         case 1:
             form = NumberFormat.getIntegerInstance(locales[i]); break;
         case 2:
             form = NumberFormat.getCurrencyInstance(locales[i]); break;
         default:
             form = NumberFormat.getPercentInstance(locales[i]); break;
         }
         if (form instanceof DecimalFormat) {
             System.out.print(": " + ((DecimalFormat) form).toPattern());
         }
         System.out.print(" -> " + form.format(myNumber));
         try {
             System.out.println(" -> " + form.parse(form.format(myNumber)));
         } catch (ParseException e) {}
     }
 }
 

Author(s):
Mark Davis
Alan Liu
See also:
Java Tutorial
NumberFormat
DecimalFormatSymbols
ParsePosition
 
 public class DecimalFormat extends NumberFormat {

    
Creates a DecimalFormat using the default pattern and symbols for the default locale. This is a convenient way to obtain a DecimalFormat when internationalization is not the main concern.

To obtain standard formats for a given locale, use the factory methods on NumberFormat such as getNumberInstance. These factories will return the most appropriate sub-class of NumberFormat for a given locale.

 
     public DecimalFormat() {
         Locale def = Locale.getDefault();
         // try to get the pattern from the cache
         String pattern = (String.get(def);
         if (pattern == null) {  /* cache miss */
             // Get the pattern for the default locale.
             ResourceBundle rb = LocaleData.getNumberFormatData(def);
             String[] all = rb.getStringArray("NumberPatterns");
             pattern = all[0];
             /* update cache */
             .put(defpattern);
         }
 
         // Always applyPattern after the symbols are set
         this. = new DecimalFormatSymbols(def);
         applyPattern(patternfalse);
     }


    
Creates a DecimalFormat using the given pattern and the symbols for the default locale. This is a convenient way to obtain a DecimalFormat when internationalization is not the main concern.

To obtain standard formats for a given locale, use the factory methods on NumberFormat such as getNumberInstance. These factories will return the most appropriate sub-class of NumberFormat for a given locale.

 
     public DecimalFormat(String pattern) {
         // Always applyPattern after the symbols are set
         this. = new DecimalFormatSymbols(Locale.getDefault());
         applyPattern(patternfalse);
     }


    
Creates a DecimalFormat using the given pattern and symbols. Use this constructor when you need to completely customize the behavior of the format.

To obtain standard formats for a given locale, use the factory methods on NumberFormat such as getInstance or getCurrencyInstance. If you need only minor adjustments to a standard format, you can modify the format returned by a NumberFormat factory method.

Parameters:
pattern a non-localized pattern string
symbols the set of symbols to be used
Throws:
java.lang.NullPointerException if any of the given arguments is null
java.lang.IllegalArgumentException if the given pattern is invalid
See also:
NumberFormat.getInstance()
NumberFormat.getNumberInstance()
NumberFormat.getCurrencyInstance()
NumberFormat.getPercentInstance()
DecimalFormatSymbols
 
     public DecimalFormat (String patternDecimalFormatSymbols symbols) {
         // Always applyPattern after the symbols are set
         this. = (DecimalFormatSymbols)symbols.clone();
         applyPattern(patternfalse);
     }
 
 
     // Overrides
     
Formats a number and appends the resulting text to the given string buffer. The number can be of any subclass of java.lang.Number.

This implementation uses the maximum precision permitted.

Parameters:
number the number to format
toAppendTo the StringBuffer to which the formatted text is to be appended
pos On input: an alignment field, if desired. On output: the offsets of the alignment field.
Returns:
the value passed in as toAppendTo
Throws:
java.lang.IllegalArgumentException if number is null or not an instance of Number.
java.lang.NullPointerException if toAppendTo or pos is null
java.lang.ArithmeticException if rounding is needed with rounding mode being set to RoundingMode.UNNECESSARY
See also:
FieldPosition
 
     public final StringBuffer format(Object number,
                                      StringBuffer toAppendTo,
                                      FieldPosition pos) {
         if (number instanceof Long || number instanceof Integer ||
                    number instanceof Short || number instanceof Byte ||
                    number instanceof AtomicInteger ||
                    number instanceof AtomicLong ||
                    (number instanceof BigInteger &&
                     ((BigInteger)number).bitLength () < 64)) {
             return format(((Number)number).longValue(), toAppendTopos);
         } else if (number instanceof BigDecimal) {
             return format((BigDecimal)numbertoAppendTopos);
         } else if (number instanceof BigInteger) {
             return format((BigInteger)numbertoAppendTopos);
         } else if (number instanceof Number) {
             return format(((Number)number).doubleValue(), toAppendTopos);
         } else {
             throw new IllegalArgumentException("Cannot format given Object as a Number");
         }
     }

    
Formats a double to produce a string.

Parameters:
number The double to format
result where the text is to be appended
fieldPosition On input: an alignment field, if desired. On output: the offsets of the alignment field.
Returns:
The formatted number string
Throws:
java.lang.ArithmeticException if rounding is needed with rounding mode being set to RoundingMode.UNNECESSARY
See also:
FieldPosition
 
     public StringBuffer format(double numberStringBuffer result,
                                FieldPosition fieldPosition) {
         fieldPosition.setBeginIndex(0);
         fieldPosition.setEndIndex(0);
 
         return format(numberresultfieldPosition.getFieldDelegate());
     }

    
Formats a double to produce a string.

Parameters:
number The double to format
result where the text is to be appended
delegate notified of locations of sub fields
Returns:
The formatted number string
Throws:
java.lang.ArithmeticException if rounding is needed with rounding mode being set to RoundingMode.UNNECESSARY
 
     private StringBuffer format(double numberStringBuffer result,
                                 FieldDelegate delegate) {
         if (Double.isNaN(number) ||
            (Double.isInfinite(number) &&  == 0)) {
             int iFieldStart = result.length();
             result.append(.getNaN());
             delegate.formatted(..,
                                iFieldStartresult.length(), result);
             return result;
         }
 
         /* Detecting whether a double is negative is easy with the exception of
          * the value -0.0.  This is a double which has a zero mantissa (and
          * exponent), but a negative sign bit.  It is semantically distinct from
          * a zero with a positive sign bit, and this distinction is important
          * to certain kinds of computations.  However, it's a little tricky to
          * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0).  How then, you may
          * ask, does it behave distinctly from +0.0?  Well, 1/(-0.0) ==
          * -Infinity.  Proper detection of -0.0 is needed to deal with the
          * issues raised by bugs 4106658, 4106667, and 4147706.  Liu 7/6/98.
          */
         boolean isNegative = ((number < 0.0) || (number == 0.0 && 1/number < 0.0)) ^ ( < 0);
 
         if ( != 1) {
             number *= ;
         }
 
         if (Double.isInfinite(number)) {
             if (isNegative) {
                 append(resultdelegate,
                        getNegativePrefixFieldPositions(), .);
             } else {
                 append(resultdelegate,
                        getPositivePrefixFieldPositions(), .);
             }
 
             int iFieldStart = result.length();
             result.append(.getInfinity());
             delegate.formatted(..,
                                iFieldStartresult.length(), result);
 
             if (isNegative) {
                 append(resultdelegate,
                        getNegativeSuffixFieldPositions(), .);
             } else {
                 append(resultdelegate,
                        getPositiveSuffixFieldPositions(), .);
             }
 
             return result;
         }
 
         if (isNegative) {
             number = -number;
         }
 
         // at this point we are guaranteed a nonnegative finite number.
         assert(number >= 0 && !Double.isInfinite(number));
 
         synchronized() {
             int maxIntDigits = super.getMaximumIntegerDigits();
             int minIntDigits = super.getMinimumIntegerDigits();
             int maxFraDigits = super.getMaximumFractionDigits();
             int minFraDigits = super.getMinimumFractionDigits();
 
             .set(isNegativenumber ?
                           maxIntDigits + maxFraDigits : maxFraDigits,
                           !);
             return subformat(resultdelegateisNegativefalse,
                        maxIntDigitsminIntDigitsmaxFraDigitsminFraDigits);
         }
     }

    
Format a long to produce a string.

Parameters:
number The long to format
result where the text is to be appended
fieldPosition On input: an alignment field, if desired. On output: the offsets of the alignment field.
Returns:
The formatted number string
Throws:
java.lang.ArithmeticException if rounding is needed with rounding mode being set to RoundingMode.UNNECESSARY
See also:
FieldPosition
 
     public StringBuffer format(long numberStringBuffer result,
                                FieldPosition fieldPosition) {
         fieldPosition.setBeginIndex(0);
         fieldPosition.setEndIndex(0);
 
         return format(numberresultfieldPosition.getFieldDelegate());
     }

    
Format a long to produce a string.

Parameters:
number The long to format
result where the text is to be appended
delegate notified of locations of sub fields
Returns:
The formatted number string
Throws:
java.lang.ArithmeticException if rounding is needed with rounding mode being set to RoundingMode.UNNECESSARY
See also:
FieldPosition
 
     private StringBuffer format(long numberStringBuffer result,
                                FieldDelegate delegate) {
         boolean isNegative = (number < 0);
         if (isNegative) {
             number = -number;
         }
 
         // In general, long values always represent real finite numbers, so
         // we don't have to check for +/- Infinity or NaN.  However, there
         // is one case we have to be careful of:  The multiplier can push
         // a number near MIN_VALUE or MAX_VALUE outside the legal range.  We
         // check for this before multiplying, and if it happens we use
         // BigInteger instead.
         boolean useBigInteger = false;
         if (number < 0) { // This can only happen if number == Long.MIN_VALUE.
             if ( != 0) {
                 useBigInteger = true;
             }
         } else if ( != 1 &&  != 0) {
             long cutoff = . / ;
             if (cutoff < 0) {
                 cutoff = -cutoff;
             }
             useBigInteger = (number > cutoff);
         }
 
         if (useBigInteger) {
             if (isNegative) {
                 number = -number;
             }
             BigInteger bigIntegerValue = BigInteger.valueOf(number);
             return format(bigIntegerValueresultdelegatetrue);
         }
 
         number *= ;
         if (number == 0) {
             isNegative = false;
         } else {
             if ( < 0) {
                 number = -number;
                 isNegative = !isNegative;
             }
         }
 
         synchronized() {
             int maxIntDigits = super.getMaximumIntegerDigits();
             int minIntDigits = super.getMinimumIntegerDigits();
             int maxFraDigits = super.getMaximumFractionDigits();
             int minFraDigits = super.getMinimumFractionDigits();
 
             .set(isNegativenumber,
                       ? maxIntDigits + maxFraDigits : 0);
 
             return subformat(resultdelegateisNegativetrue,
                        maxIntDigitsminIntDigitsmaxFraDigitsminFraDigits);
         }
     }

    
Formats a BigDecimal to produce a string.

Parameters:
number The BigDecimal to format
result where the text is to be appended
fieldPosition On input: an alignment field, if desired. On output: the offsets of the alignment field.
Returns:
The formatted number string
Throws:
java.lang.ArithmeticException if rounding is needed with rounding mode being set to RoundingMode.UNNECESSARY
See also:
FieldPosition
 
     private StringBuffer format(BigDecimal numberStringBuffer result,
                                 FieldPosition fieldPosition) {
         fieldPosition.setBeginIndex(0);
         fieldPosition.setEndIndex(0);
         return format(numberresultfieldPosition.getFieldDelegate());
     }

    
Formats a BigDecimal to produce a string.

Parameters:
number The BigDecimal to format
result where the text is to be appended
delegate notified of locations of sub fields
Returns:
The formatted number string
Throws:
java.lang.ArithmeticException if rounding is needed with rounding mode being set to RoundingMode.UNNECESSARY
 
     private StringBuffer format(BigDecimal numberStringBuffer result,
                                 FieldDelegate delegate) {
         if ( != 1) {
             number = number.multiply(getBigDecimalMultiplier());
         }
         boolean isNegative = number.signum() == -1;
         if (isNegative) {
             number = number.negate();
         }
 
         synchronized() {
             int maxIntDigits = getMaximumIntegerDigits();
             int minIntDigits = getMinimumIntegerDigits();
             int maxFraDigits = getMaximumFractionDigits();
             int minFraDigits = getMinimumFractionDigits();
             int maximumDigits = maxIntDigits + maxFraDigits;
 
             .set(isNegativenumber ?
                 ((maximumDigits < 0) ? . : maximumDigits) :
                 maxFraDigits, !);
 
             return subformat(resultdelegateisNegativefalse,
                 maxIntDigitsminIntDigitsmaxFraDigitsminFraDigits);
         }
     }

    
Format a BigInteger to produce a string.

Parameters:
number The BigInteger to format
result where the text is to be appended
fieldPosition On input: an alignment field, if desired. On output: the offsets of the alignment field.
Returns:
The formatted number string
Throws:
java.lang.ArithmeticException if rounding is needed with rounding mode being set to RoundingMode.UNNECESSARY
See also:
FieldPosition
 
     private StringBuffer format(BigInteger numberStringBuffer result,
                                FieldPosition fieldPosition) {
         fieldPosition.setBeginIndex(0);
         fieldPosition.setEndIndex(0);
 
         return format(numberresultfieldPosition.getFieldDelegate(), false);
     }

    
Format a BigInteger to produce a string.

Parameters:
number The BigInteger to format
result where the text is to be appended
delegate notified of locations of sub fields
Returns:
The formatted number string
Throws:
java.lang.ArithmeticException if rounding is needed with rounding mode being set to RoundingMode.UNNECESSARY
See also:
FieldPosition
 
     private StringBuffer format(BigInteger numberStringBuffer result,
                                FieldDelegate delegateboolean formatLong) {
         if ( != 1) {
             number = number.multiply(getBigIntegerMultiplier());
         }
         boolean isNegative = number.signum() == -1;
         if (isNegative) {
             number = number.negate();
         }
 
         synchronized() {
             int maxIntDigitsminIntDigitsmaxFraDigitsminFraDigitsmaximumDigits;
             if (formatLong) {
                 maxIntDigits = super.getMaximumIntegerDigits();
                 minIntDigits = super.getMinimumIntegerDigits();
                 maxFraDigits = super.getMaximumFractionDigits();
                 minFraDigits = super.getMinimumFractionDigits();
                 maximumDigits = maxIntDigits + maxFraDigits;
             } else {
                 maxIntDigits = getMaximumIntegerDigits();
                 minIntDigits = getMinimumIntegerDigits();
                 maxFraDigits = getMaximumFractionDigits();
                 minFraDigits = getMinimumFractionDigits();
                 maximumDigits = maxIntDigits + maxFraDigits;
                 if (maximumDigits < 0) {
                     maximumDigits = .;
                 }
             }
 
             .set(isNegativenumber,
                            ? maximumDigits : 0);
 
             return subformat(resultdelegateisNegativetrue,
                 maxIntDigitsminIntDigitsmaxFraDigitsminFraDigits);
         }
     }

    
Formats an Object producing an AttributedCharacterIterator. You can use the returned AttributedCharacterIterator to build the resulting String, as well as to determine information about the resulting String.

Each attribute key of the AttributedCharacterIterator will be of type NumberFormat.Field, with the attribute value being the same as the attribute key.

Parameters:
obj The object to format
Returns:
AttributedCharacterIterator describing the formatted value.
Throws:
java.lang.NullPointerException if obj is null.
java.lang.IllegalArgumentException when the Format cannot format the given object.
java.lang.ArithmeticException if rounding is needed with rounding mode being set to RoundingMode.UNNECESSARY
Since:
1.4
 
         CharacterIteratorFieldDelegate delegate =
                          new CharacterIteratorFieldDelegate();
         StringBuffer sb = new StringBuffer();
 
         if (obj instanceof Double || obj instanceof Float) {
             format(((Number)obj).doubleValue(), sbdelegate);
         } else if (obj instanceof Long || obj instanceof Integer ||
                    obj instanceof Short || obj instanceof Byte ||
                    obj instanceof AtomicInteger || obj instanceof AtomicLong) {
             format(((Number)obj).longValue(), sbdelegate);
         } else if (obj instanceof BigDecimal) {
             format((BigDecimal)objsbdelegate);
         } else if (obj instanceof BigInteger) {
             format((BigInteger)objsbdelegatefalse);
         } else if (obj == null) {
             throw new NullPointerException(
                 "formatToCharacterIterator must be passed non-null object");
         } else {
             throw new IllegalArgumentException(
                 "Cannot format given Object as a Number");
         }
         return delegate.getIterator(sb.toString());
     }

    
Complete the formatting of a finite number. On entry, the digitList must be filled in with the correct digits.
 
     private StringBuffer subformat(StringBuffer resultFieldDelegate delegate,
                                    boolean isNegativeboolean isInteger,
                                    int maxIntDigitsint minIntDigits,
                                    int maxFraDigitsint minFraDigits) {
         // NOTE: This isn't required anymore because DigitList takes care of this.
         //
         //  // The negative of the exponent represents the number of leading
         //  // zeros between the decimal and the first non-zero digit, for
         //  // a value < 0.1 (e.g., for 0.00123, -fExponent == 2).  If this
         //  // is more than the maximum fraction digits, then we have an underflow
         //  // for the printed representation.  We recognize this here and set
         //  // the DigitList representation to zero in this situation.
         //
         //  if (-digitList.decimalAt >= getMaximumFractionDigits())
         //  {
         //      digitList.count = 0;
         //  }
 
         char zero = .getZeroDigit();
         int zeroDelta = zero - '0'// '0' is the DigitList representation of zero
         char grouping = .getGroupingSeparator();
         char decimal =  ?
             .getMonetaryDecimalSeparator() :
             .getDecimalSeparator();
 
         /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
          * format as zero.  This allows sensible computations and preserves
          * relations such as signum(1/x) = signum(x), where x is +Infinity or
          * -Infinity.  Prior to this fix, we always formatted zero values as if
          * they were positive.  Liu 7/6/98.
          */
         if (.isZero()) {
             . = 0; // Normalize
         }
 
         if (isNegative) {
             append(resultdelegate,
                    getNegativePrefixFieldPositions(), .);
         } else {
             append(resultdelegate,
                    getPositivePrefixFieldPositions(), .);
         }
 
         if () {
             int iFieldStart = result.length();
             int iFieldEnd = -1;
             int fFieldStart = -1;
 
             // Minimum integer digits are handled in exponential format by
             // adjusting the exponent.  For example, 0.01234 with 3 minimum
             // integer digits is "123.4E-4".
 
             // Maximum integer digits are interpreted as indicating the
             // repeating range.  This is useful for engineering notation, in
             // which the exponent is restricted to a multiple of 3.  For
             // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
             // If maximum integer digits are > 1 and are larger than
             // minimum integer digits, then minimum integer digits are
             // ignored.
             int exponent = .;
             int repeat = maxIntDigits;
             int minimumIntegerDigits = minIntDigits;
             if (repeat > 1 && repeat > minIntDigits) {
                 // A repeating range is defined; adjust to it as follows.
                 // If repeat == 3, we have 6,5,4=>3; 3,2,1=>0; 0,-1,-2=>-3;
                 // -3,-4,-5=>-6, etc. This takes into account that the
                 // exponent we have here is off by one from what we expect;
                 // it is for the format 0.MMMMMx10^n.
                 if (exponent >= 1) {
                     exponent = ((exponent - 1) / repeat) * repeat;
                 } else {
                     // integer division rounds towards 0
                     exponent = ((exponent - repeat) / repeat) * repeat;
                 }
                 minimumIntegerDigits = 1;
             } else {
                 // No repeating range is defined; use minimum integer digits.
                 exponent -= minimumIntegerDigits;
             }
 
             // We now output a minimum number of digits, and more if there
             // are more digits, up to the maximum number of digits.  We
             // place the decimal point after the "integer" digits, which
             // are the first (decimalAt - exponent) digits.
             int minimumDigits = minIntDigits + minFraDigits;
             if (minimumDigits < 0) {    // overflow?
                 minimumDigits = .;
             }
 
             // The number of integer digits is handled specially if the number
             // is zero, since then there may be no digits.
             int integerDigits = .isZero() ? minimumIntegerDigits :
                     . - exponent;
             if (minimumDigits < integerDigits) {
                 minimumDigits = integerDigits;
             }
             int totalDigits = .;
             if (minimumDigits > totalDigits) {
                 totalDigits = minimumDigits;
             }
             boolean addedDecimalSeparator = false;
 
             for (int i=0; i<totalDigits; ++i) {
                 if (i == integerDigits) {
                     // Record field information for caller.
                     iFieldEnd = result.length();
 
                     result.append(decimal);
                     addedDecimalSeparator = true;
 
                     // Record field information for caller.
                     fFieldStart = result.length();
                 }
                 result.append((i < .) ?
                               (char)(.[i] + zeroDelta) :
                               zero);
             }
 
             if ( && totalDigits == integerDigits) {
                 // Record field information for caller.
                 iFieldEnd = result.length();
 
                 result.append(decimal);
                 addedDecimalSeparator = true;
 
                 // Record field information for caller.
                 fFieldStart = result.length();
             }
 
             // Record field information
             if (iFieldEnd == -1) {
                 iFieldEnd = result.length();
             }
             delegate.formatted(..,
                                iFieldStartiFieldEndresult);
             if (addedDecimalSeparator) {
                 delegate.formatted(.,
                                   .,
                                   iFieldEndfFieldStartresult);
            }
            if (fFieldStart == -1) {
                fFieldStart = result.length();
            }
            delegate.formatted(..,
                               fFieldStartresult.length(), result);
            // The exponent is output using the pattern-specified minimum
            // exponent digits.  There is no maximum limit to the exponent
            // digits, since truncating the exponent would result in an
            // unacceptable inaccuracy.
            int fieldStart = result.length();
            result.append(.getExponentSeparator());
            delegate.formatted(..,
                               fieldStartresult.length(), result);
            // For zero values, we force the exponent to zero.  We
            // must do this here, and not earlier, because the value
            // is used to determine integer digit count above.
            if (.isZero()) {
                exponent = 0;
            }
            boolean negativeExponent = exponent < 0;
            if (negativeExponent) {
                exponent = -exponent;
                fieldStart = result.length();
                result.append(.getMinusSign());
                delegate.formatted(..,
                                   fieldStartresult.length(), result);
            }
            .set(negativeExponentexponent);
            int eFieldStart = result.length();
            for (int i=.i<; ++i) {
                result.append(zero);
            }
            for (int i=0; i<.; ++i) {
                result.append((i < .) ?
                          (char)(.[i] + zeroDelta) : zero);
            }
            delegate.formatted(..eFieldStart,
                               result.length(), result);
        } else {
            int iFieldStart = result.length();
            // Output the integer portion.  Here 'count' is the total
            // number of integer digits we will display, including both
            // leading zeros required to satisfy getMinimumIntegerDigits,
            // and actual digits present in the number.
            int count = minIntDigits;
            int digitIndex = 0; // Index into digitList.fDigits[]
            if (. > 0 && count < .) {
                count = .;
            }
            // Handle the case where getMaximumIntegerDigits() is smaller
            // than the real number of integer digits.  If this is so, we
            // output the least significant max integer digits.  For example,
            // the value 1997 printed with 2 max integer digits is just "97".
            if (count > maxIntDigits) {
                count = maxIntDigits;
                digitIndex = . - count;
            }
            int sizeBeforeIntegerPart = result.length();
            for (int i=count-1; i>=0; --i) {
                if (i < . && digitIndex < .) {
                    // Output a real digit
                    result.append((char)(.[digitIndex++] + zeroDelta));
                } else {
                    // Output a leading zero
                    result.append(zero);
                }
                // Output grouping separator if necessary.  Don't output a
                // grouping separator if i==0 though; that's at the end of
                // the integer part.
                if (isGroupingUsed() && i>0 && ( != 0) &&
                    (i %  == 0)) {
                    int gStart = result.length();
                    result.append(grouping);
                    delegate.formatted(.,
                                       .gStart,
                                       result.length(), result);
                }
            }
            // Determine whether or not there are any printable fractional
            // digits.  If we've used up the digits we know there aren't.
            boolean fractionPresent = (minFraDigits > 0) ||
                (!isInteger && digitIndex < .);
            // If there is no fraction present, and we haven't printed any
            // integer digits, then print a zero.  Otherwise we won't print
            // _any_ digits, and we won't be able to parse this string.
            if (!fractionPresent && result.length() == sizeBeforeIntegerPart) {
                result.append(zero);
            }
            delegate.formatted(..,
                               iFieldStartresult.length(), result);
            // Output the decimal separator if we always do so.
            int sStart = result.length();
            if ( || fractionPresent) {
                result.append(decimal);
            }
            if (sStart != result.length()) {
                delegate.formatted(.,
                                   .,
                                   sStartresult.length(), result);
            }
            int fFieldStart = result.length();
            for (int i=0; i < maxFraDigits; ++i) {
                // Here is where we escape from the loop.  We escape if we've
                // output the maximum fraction digits (specified in the for
                // expression above).
                // We also stop when we've output the minimum digits and either:
                // we have an integer, so there is no fractional stuff to
                // display, or we're out of significant digits.
                if (i >= minFraDigits &&
                    (isInteger || digitIndex >= .)) {
                    break;
                }
                // Output leading fractional zeros. These are zeros that come
                // after the decimal but before any significant digits. These
                // are only output if abs(number being formatted) < 1.0.
                if (-1-i > (.-1)) {
                    result.append(zero);
                    continue;
                }
                // Output a digit, if we have any precision left, or a
                // zero if we don't.  We don't want to output noise digits.
                if (!isInteger && digitIndex < .) {
                    result.append((char)(.[digitIndex++] + zeroDelta));
                } else {
                    result.append(zero);
                }
            }
            // Record field information for caller.
            delegate.formatted(..,
                               fFieldStartresult.length(), result);
        }
        if (isNegative) {
            append(resultdelegate,
                   getNegativeSuffixFieldPositions(), .);
        }
        else {
            append(resultdelegate,
                   getPositiveSuffixFieldPositions(), .);
        }
        return result;
    }

    
Appends the String string to result. delegate is notified of all the FieldPositions in positions.

If one of the FieldPositions in positions identifies a SIGN attribute, it is mapped to signAttribute. This is used to map the SIGN attribute to the EXPONENT attribute as necessary.

This is used by subformat to add the prefix/suffix.

    private void append(StringBuffer resultString string,
                        FieldDelegate delegate,
                        FieldPosition[] positions,
                        Format.Field signAttribute) {
        int start = result.length();
        if (string.length() > 0) {
            result.append(string);
            for (int counter = 0, max = positions.lengthcounter < max;
                 counter++) {
                FieldPosition fp = positions[counter];
                Format.Field attribute = fp.getFieldAttribute();
                if (attribute == .) {
                    attribute = signAttribute;
                }
                delegate.formatted(attributeattribute,
                                   start + fp.getBeginIndex(),
                                   start + fp.getEndIndex(), result);
            }
        }
    }

    
Parses text from a string to produce a Number.

The method attempts to parse text starting at the index given by pos. If parsing succeeds, then the index of pos is updated to the index after the last character used (parsing does not necessarily use all characters up to the end of the string), and the parsed number is returned. The updated pos can be used to indicate the starting point for the next call to this method. If an error occurs, then the index of pos is not changed, the error index of pos is set to the index of the character where the error occurred, and null is returned.

The subclass returned depends on the value of isParseBigDecimal() as well as on the string being parsed.

  • If isParseBigDecimal() is false (the default), most integer values are returned as Long objects, no matter how they are written: "17" and "17.000" both parse to Long(17). Values that cannot fit into a Long are returned as Doubles. This includes values with a fractional part, infinite values, NaN, and the value -0.0. DecimalFormat does not decide whether to return a Double or a Long based on the presence of a decimal separator in the source string. Doing so would prevent integers that overflow the mantissa of a double, such as "-9,223,372,036,854,775,808.00", from being parsed accurately.

    Callers may use the Number methods doubleValue, longValue, etc., to obtain the type they want.

  • If isParseBigDecimal() is true, values are returned as BigDecimal objects. The values are the ones constructed by java.math.BigDecimal.(java.lang.String) for corresponding strings in locale-independent format. The special cases negative and positive infinity and NaN are returned as Double instances holding the values of the corresponding Double constants.

DecimalFormat parses all Unicode characters that represent decimal digits, as defined by Character.digit(). In addition, DecimalFormat also recognizes as digits the ten consecutive characters starting with the localized zero digit defined in the DecimalFormatSymbols object.

Parameters:
text the string to be parsed
pos A ParsePosition object with index and error index information as described above.
Returns:
the parsed value, or null if the parse fails
Throws:
java.lang.NullPointerException if text or pos is null.
    public Number parse(String textParsePosition pos) {
        // special case NaN
        if (text.regionMatches(pos.index.getNaN(), 0, .getNaN().length())) {
            pos.index = pos.index + .getNaN().length();
            return new Double(.);
        }
        boolean[] status = new boolean[];
        if (!subparse(textposfalsestatus)) {
            return null;
        }
        // special case INFINITY
        if (status[]) {
            if (status[] == ( >= 0)) {
                return new Double(.);
            } else {
                return new Double(.);
            }
        }
        if ( == 0) {
            if (.isZero()) {
                return new Double(.);
            } else if (status[]) {
                return new Double(.);
            } else {
                return new Double(.);
            }
        }
        if (isParseBigDecimal()) {
            BigDecimal bigDecimalResult = .getBigDecimal();
            if ( != 1) {
                try {
                    bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier());
                }
                catch (ArithmeticException e) {  // non-terminating decimal expansion
                    bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier(), );
                }
            }
            if (!status[]) {
                bigDecimalResult = bigDecimalResult.negate();
            }
            return bigDecimalResult;
        } else {
            boolean gotDouble = true;
            boolean gotLongMinimum = false;
            double  doubleResult = 0.0;
            long    longResult = 0;
            // Finally, have DigitList parse the digits into a value.
            if (.fitsIntoLong(status[], isParseIntegerOnly())) {
                gotDouble = false;
                longResult = .getLong();
                if (longResult < 0) {  // got Long.MIN_VALUE
                    gotLongMinimum = true;
                }
            } else {
                doubleResult = .getDouble();
            }
            // Divide by multiplier. We have to be careful here not to do
            // unneeded conversions between double and long.
            if ( != 1) {
                if (gotDouble) {
                    doubleResult /= ;
                } else {
                    // Avoid converting to double if we can
                    if (longResult %  == 0) {
                        longResult /= ;
                    } else {
                        doubleResult = ((double)longResult) / ;
                        gotDouble = true;
                    }
                }
            }
            if (!status[] && !gotLongMinimum) {
                doubleResult = -doubleResult;
                longResult = -longResult;
            }
            // At this point, if we divided the result by the multiplier, the
            // result may fit into a long.  We check for this case and return
            // a long if possible.
            // We must do this AFTER applying the negative (if appropriate)
            // in order to handle the case of LONG_MIN; otherwise, if we do
            // this with a positive value -LONG_MIN, the double is > 0, but
            // the long is < 0. We also must retain a double in the case of
            // -0.0, which will compare as == to a long 0 cast to a double
            // (bug 4162852).
            if ( != 1 && gotDouble) {
                longResult = (long)doubleResult;
                gotDouble = ((doubleResult != (double)longResult) ||
                            (doubleResult == 0.0 && 1/doubleResult < 0.0)) &&
                            !isParseIntegerOnly();
            }
            return gotDouble ?
                (Number)new Double(doubleResult) : (Number)new Long(longResult);
        }
    }

    
Return a BigInteger multiplier.
        if ( == null) {
             = BigInteger.valueOf();
        }
        return ;
    }
    private transient BigInteger bigIntegerMultiplier;

    
Return a BigDecimal multiplier.
        if ( == null) {
             = new BigDecimal();
        }
        return ;
    }
    private transient BigDecimal bigDecimalMultiplier;
    private static final int STATUS_INFINITE = 0;
    private static final int STATUS_POSITIVE = 1;
    private static final int STATUS_LENGTH   = 2;

    
Parse the given text into a number. The text is parsed beginning at parsePosition, until an unparseable character is seen.

Parameters:
text The string to parse.
parsePosition The position at which to being parsing. Upon return, the first unparseable character.
digits The DigitList to set to the parsed value.
isExponent If true, parse an exponent. This means no infinite values and integer only.
status Upon return contains boolean status flags indicating whether the value was infinite and whether it was positive.
    private final boolean subparse(String textParsePosition parsePosition,
                   String positivePrefixString negativePrefix,
                   DigitList digitsboolean isExponent,
                   boolean status[]) {
        int position = parsePosition.index;
        int oldStart = parsePosition.index;
        int backup;
        boolean gotPositivegotNegative;
        // check for positivePrefix; take longest
        gotPositive = text.regionMatches(positionpositivePrefix, 0,
                                         positivePrefix.length());
        gotNegative = text.regionMatches(positionnegativePrefix, 0,
                                         negativePrefix.length());
        if (gotPositive && gotNegative) {
            if (positivePrefix.length() > negativePrefix.length()) {
                gotNegative = false;
            } else if (positivePrefix.length() < negativePrefix.length()) {
                gotPositive = false;
            }
        }
        if (gotPositive) {
            position += positivePrefix.length();
        } else if (gotNegative) {
            position += negativePrefix.length();
        } else {
            parsePosition.errorIndex = position;
            return false;
        }
        // process digits or Inf, find decimal position
        status[] = false;
        if (!isExponent && text.regionMatches(position,.getInfinity(),0,
                          .getInfinity().length())) {
            position += .getInfinity().length();
            status[] = true;
        } else {
            // We now have a string of digits, possibly with grouping symbols,
            // and decimal points.  We want to process these into a DigitList.
            // We don't want to put a bunch of leading zeros into the DigitList
            // though, so we keep track of the location of the decimal point,
            // put only significant digits into the DigitList, and adjust the
            // exponent as needed.
            digits.decimalAt = digits.count = 0;
            char zero = .getZeroDigit();
            char decimal =  ?
                .getMonetaryDecimalSeparator() :
                .getDecimalSeparator();
            char grouping = .getGroupingSeparator();
            String exponentString = .getExponentSeparator();
            boolean sawDecimal = false;
            boolean sawExponent = false;
            boolean sawDigit = false;
            int exponent = 0; // Set to the exponent value, if any
            // We have to track digitCount ourselves, because digits.count will
            // pin when the maximum allowable digits is reached.
            int digitCount = 0;
            backup = -1;
            for (; position < text.length(); ++position) {
                char ch = text.charAt(position);
                /* We recognize all digit ranges, not only the Latin digit range
                 * '0'..'9'.  We do so by using the Character.digit() method,
                 * which converts a valid Unicode digit to the range 0..9.
                 *
                 * The character 'ch' may be a digit.  If so, place its value
                 * from 0 to 9 in 'digit'.  First try using the locale digit,
                 * which may or MAY NOT be a standard Unicode digit range.  If
                 * this fails, try using the standard Unicode digit ranges by
                 * calling Character.digit().  If this also fails, digit will
                 * have a value outside the range 0..9.
                 */
                int digit = ch - zero;
                if (digit < 0 || digit > 9) {
                    digit = Character.digit(ch, 10);
                }
                if (digit == 0) {
                    // Cancel out backup setting (see grouping handler below)
                    backup = -1; // Do this BEFORE continue statement below!!!
                    sawDigit = true;
                    // Handle leading zeros
                    if (digits.count == 0) {
                        // Ignore leading zeros in integer part of number.
                        if (!sawDecimal) {
                            continue;
                        }
                        // If we have seen the decimal, but no significant
                        // digits yet, then we account for leading zeros by
                        // decrementing the digits.decimalAt into negative
                        // values.
                        --digits.decimalAt;
                    } else {
                        ++digitCount;
                        digits.append((char)(digit + '0'));
                    }
                } else if (digit > 0 && digit <= 9) { // [sic] digit==0 handled above
                    sawDigit = true;
                    ++digitCount;
                    digits.append((char)(digit + '0'));
                    // Cancel out backup setting (see grouping handler below)
                    backup = -1;
                } else if (!isExponent && ch == decimal) {
                    // If we're only parsing integers, or if we ALREADY saw the
                    // decimal, then don't parse this one.
                    if (isParseIntegerOnly() || sawDecimal) {
                        break;
                    }
                    digits.decimalAt = digitCount// Not digits.count!
                    sawDecimal = true;
                } else if (!isExponent && ch == grouping && isGroupingUsed()) {
                    if (sawDecimal) {
                        break;
                    }
                    // Ignore grouping characters, if we are using them, but
                    // require that they be followed by a digit.  Otherwise
                    // we backup and reprocess them.
                    backup = position;
                } else if (!isExponent && text.regionMatches(positionexponentString, 0, exponentString.length())
                             && !sawExponent) {
                    // Process the exponent by recursively calling this method.
                     ParsePosition pos = new ParsePosition(position + exponentString.length());
                    boolean[] stat = new boolean[];
                    DigitList exponentDigits = new DigitList();
                    if (subparse(textpos"", Character.toString(.getMinusSign()), exponentDigitstruestat) &&
                        exponentDigits.fitsIntoLong(stat[], true)) {
                        position = pos.index// Advance past the exponent
                        exponent = (int)exponentDigits.getLong();
                        if (!stat[]) {
                            exponent = -exponent;
                        }
                        sawExponent = true;
                    }
                    break// Whether we fail or succeed, we exit this loop
                }
                else {
                    break;
                }
            }
            if (backup != -1) {
                position = backup;
            }
            // If there was no decimal point we have an integer
            if (!sawDecimal) {
                digits.decimalAt = digitCount// Not digits.count!
            }
            // Adjust for exponent, if any
            digits.decimalAt += exponent;
            // If none of the text string was recognized.  For example, parse
            // "x" with pattern "#0.00" (return index and error index both 0)
            // parse "$" with pattern "$#0.00". (return index 0 and error
            // index 1).
            if (!sawDigit && digitCount == 0) {
                parsePosition.index = oldStart;
                parsePosition.errorIndex = oldStart;
                return false;
            }
        }
        // check for suffix
        if (!isExponent) {
            if (gotPositive) {
                gotPositive = text.regionMatches(position,,0,
                                                 .length());
            }
            if (gotNegative) {
                gotNegative = text.regionMatches(position,,0,
                                                 .length());
            }
        // if both match, take longest
        if (gotPositive && gotNegative) {
            if (.length() > .length()) {
                gotNegative = false;
            } else if (.length() < .length()) {
                gotPositive = false;
            }
        }
        // fail if neither or both
        if (gotPositive == gotNegative) {
            parsePosition.errorIndex = position;
            return false;
        }
        parsePosition.index = position +
            (gotPositive ? .length() : .length()); // mark success!
        } else {
            parsePosition.index = position;
        }
        status[] = gotPositive;
        if (parsePosition.index == oldStart) {
            parsePosition.errorIndex = position;
            return false;
        }
        return true;
    }

    
Returns a copy of the decimal format symbols, which is generally not changed by the programmer or user.

Returns:
a copy of the desired DecimalFormatSymbols
See also:
DecimalFormatSymbols
        try {
            // don't allow multiple references
            return (DecimalFormatSymbols.clone();
        } catch (Exception foo) {
            return null// should never happen
        }
    }


    
Sets the decimal format symbols, which is generally not changed by the programmer or user.

Parameters:
newSymbols desired DecimalFormatSymbols
See also:
DecimalFormatSymbols
    public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
        try {
            // don't allow multiple references
             = (DecimalFormatSymbolsnewSymbols.clone();
            expandAffixes();
        } catch (Exception foo) {
            // should never happen
        }
    }

    
Get the positive prefix.

Examples: +123, $123, sFr123

    public String getPositivePrefix () {
        return ;
    }

    
Set the positive prefix.

Examples: +123, $123, sFr123

    public void setPositivePrefix (String newValue) {
         = newValue;
         = null;
         = null;
    }

    
Returns the FieldPositions of the fields in the prefix used for positive numbers. This is not used if the user has explicitly set a positive prefix via setPositivePrefix. This is lazily created.

Returns:
FieldPositions in positive prefix
        if ( == null) {
            if ( != null) {
                 = expandAffix();
            }
            else {
                 = ;
            }
        }
        return ;
    }

    
Get the negative prefix.

Examples: -123, ($123) (with negative suffix), sFr-123

    public String getNegativePrefix () {
        return ;
    }

    
Set the negative prefix.

Examples: -123, ($123) (with negative suffix), sFr-123

    public void setNegativePrefix (String newValue) {
         = newValue;
         = null;
    }

    
Returns the FieldPositions of the fields in the prefix used for negative numbers. This is not used if the user has explicitly set a negative prefix via setNegativePrefix. This is lazily created.

Returns:
FieldPositions in positive prefix
        if ( == null) {
            if ( != null) {
                 = expandAffix();
            }
            else {
                 = ;
            }
        }
        return ;
    }

    
Get the positive suffix.

Example: 123%

    public String getPositiveSuffix () {
        return ;
    }

    
Set the positive suffix.

Example: 123%

    public void setPositiveSuffix (String newValue) {
         = newValue;
         = null;
    }

    
Returns the FieldPositions of the fields in the suffix used for positive numbers. This is not used if the user has explicitly set a positive suffix via setPositiveSuffix. This is lazily created.

Returns:
FieldPositions in positive prefix
        if ( == null) {
            if ( != null) {
                 = expandAffix();
            }
            else {
                 = ;
            }
        }
        return ;
    }

    
Get the negative suffix.

Examples: -123%, ($123) (with positive suffixes)

    public String getNegativeSuffix () {
        return ;
    }

    
Set the negative suffix.

Examples: 123%

    public void setNegativeSuffix (String newValue) {
         = newValue;
         = null;
    }

    
Returns the FieldPositions of the fields in the suffix used for negative numbers. This is not used if the user has explicitly set a negative suffix via setNegativeSuffix. This is lazily created.

Returns:
FieldPositions in positive prefix
        if ( == null) {
            if ( != null) {
                 = expandAffix();
            }
            else {
                 = ;
            }
        }
        return ;
    }

    
Gets the multiplier for use in percent, per mille, and similar formats.

    public int getMultiplier () {
        return ;
    }

    
Sets the multiplier for use in percent, per mille, and similar formats. For a percent format, set the multiplier to 100 and the suffixes to have '%' (for Arabic, use the Arabic percent sign). For a per mille format, set the multiplier to 1000 and the suffixes to have '\u2030'.

Example: with multiplier 100, 1.23 is formatted as "123", and "123" is parsed into 1.23.

See also:
getMultiplier()
    public void setMultiplier (int newValue) {
         = newValue;
         = null;
         = null;
    }

    
Return the grouping size. Grouping size is the number of digits between grouping separators in the integer portion of a number. For example, in the number "123,456.78", the grouping size is 3.

    public int getGroupingSize () {
        return ;
    }

    
Set the grouping size. Grouping size is the number of digits between grouping separators in the integer portion of a number. For example, in the number "123,456.78", the grouping size is 3.
The value passed in is converted to a byte, which may lose information.

    public void setGroupingSize (int newValue) {
         = (byte)newValue;
    }

    
Allows you to get the behavior of the decimal separator with integers. (The decimal separator will always appear with decimals.)

Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345

    public boolean isDecimalSeparatorAlwaysShown() {
        return ;
    }

    
Allows you to set the behavior of the decimal separator with integers. (The decimal separator will always appear with decimals.)

Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345

    public void setDecimalSeparatorAlwaysShown(boolean newValue) {
         = newValue;
    }

    
Returns whether the parse(java.lang.String,java.text.ParsePosition) method returns BigDecimal. The default value is false.

Since:
1.5
See also:
setParseBigDecimal(boolean)
    public boolean isParseBigDecimal() {
        return ;
    }

    
Sets whether the parse(java.lang.String,java.text.ParsePosition) method returns BigDecimal.

Since:
1.5
See also:
isParseBigDecimal()
    public void setParseBigDecimal(boolean newValue) {
         = newValue;
    }

    
Standard override; no change in semantics.
    public Object clone() {
        try {
            DecimalFormat other = (DecimalFormatsuper.clone();
            other.symbols = (DecimalFormatSymbols.clone();
            other.digitList = (DigitList.clone();
            return other;
        } catch (Exception e) {
            throw new InternalError();
        }
    }

    
Overrides equals
    public boolean equals(Object obj)
    {
        if (obj == nullreturn false;
        if (!super.equals(obj)) return false// super does class check
        DecimalFormat other = (DecimalFormatobj;
        return (( == other.posPrefixPattern &&
                 .equals(other.positivePrefix))
                || ( != null &&
                    .equals(other.posPrefixPattern)))
            && (( == other.posSuffixPattern &&
                 .equals(other.positiveSuffix))
                || ( != null &&
                    .equals(other.posSuffixPattern)))
            && (( == other.negPrefixPattern &&
                 .equals(other.negativePrefix))
                || ( != null &&
                    .equals(other.negPrefixPattern)))
            && (( == other.negSuffixPattern &&
                 .equals(other.negativeSuffix))
                || ( != null &&
                    .equals(other.negSuffixPattern)))
            &&  == other.multiplier
            &&  == other.groupingSize
            &&  == other.decimalSeparatorAlwaysShown
            &&  == other.parseBigDecimal
            &&  == other.useExponentialNotation
            && (! ||
                 == other.minExponentDigits)
            &&  == other.maximumIntegerDigits
            &&  == other.minimumIntegerDigits
            &&  == other.maximumFractionDigits
            &&  == other.minimumFractionDigits
            &&  == other.roundingMode
            && .equals(other.symbols);
    }

    
Overrides hashCode
    public int hashCode() {
        return super.hashCode() * 37 + .hashCode();
        // just enough fields for a reasonable distribution
    }

    
Synthesizes a pattern string that represents the current state of this Format object.

    public String toPattern() {
        return toPatternfalse );
    }

    
Synthesizes a localized pattern string that represents the current state of this Format object.

    public String toLocalizedPattern() {
        return toPatterntrue );
    }

    
Expand the affix pattern strings into the expanded affix strings. If any affix pattern string is null, do not expand it. This method should be called any time the symbols or the affix patterns change in order to keep the expanded affix strings up to date.
    private void expandAffixes() {
        // Reuse one StringBuffer for better performance
        StringBuffer buffer = new StringBuffer();
        if ( != null) {
             = expandAffix(buffer);
             = null;
        }
        if ( != null) {
             = expandAffix(buffer);
             = null;
        }
        if ( != null) {
             = expandAffix(buffer);
             = null;
        }
        if ( != null) {
             = expandAffix(buffer);
             = null;
        }
    }

    
Expand an affix pattern into an affix string. All characters in the pattern are literal unless prefixed by QUOTE. The following characters after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE, PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE + CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217 currency code. Any other character after a QUOTE represents itself. QUOTE must be followed by another character; QUOTE may not occur by itself at the end of the pattern.

Parameters:
pattern the non-null, possibly empty pattern
buffer a scratch StringBuffer; its contents will be lost
Returns:
the expanded equivalent of pattern
    private String expandAffix(String patternStringBuffer buffer) {
        buffer.setLength(0);
        for (int i=0; i<pattern.length(); ) {
            char c = pattern.charAt(i++);
            if (c == ) {
                c = pattern.charAt(i++);
                switch (c) {
                case :
                    if (i<pattern.length() &&
                        pattern.charAt(i) == ) {
                        ++i;
                        buffer.append(.getInternationalCurrencySymbol());
                    } else {
                        buffer.append(.getCurrencySymbol());
                    }
                    continue;
                case :
                    c = .getPercent();
                    break;
                case :
                    c = .getPerMill();
                    break;
                case :
                    c = .getMinusSign();
                    break;
                }
            }
            buffer.append(c);
        }
        return buffer.toString();
    }

    
Expand an affix pattern into an array of FieldPositions describing how the pattern would be expanded. All characters in the pattern are literal unless prefixed by QUOTE. The following characters after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE, PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE + CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217 currency code. Any other character after a QUOTE represents itself. QUOTE must be followed by another character; QUOTE may not occur by itself at the end of the pattern.

Parameters:
pattern the non-null, possibly empty pattern
Returns:
FieldPosition array of the resulting fields.
    private FieldPosition[] expandAffix(String pattern) {
        ArrayList positions = null;
        int stringIndex = 0;
        for (int i=0; i<pattern.length(); ) {
            char c = pattern.charAt(i++);
            if (c == ) {
                int field = -1;
                Format.Field fieldID = null;
                c = pattern.charAt(i++);
                switch (c) {
                case :
                    String string;
                    if (i<pattern.length() &&
                        pattern.charAt(i) == ) {
                        ++i;
                        string = .getInternationalCurrencySymbol();
                    } else {
                        string = .getCurrencySymbol();
                    }
                    if (string.length() > 0) {
                        if (positions == null) {
                            positions = new ArrayList(2);
                        }
                        FieldPosition fp = new FieldPosition(.);
                        fp.setBeginIndex(stringIndex);
                        fp.setEndIndex(stringIndex + string.length());
                        positions.add(fp);
                        stringIndex += string.length();
                    }
                    continue;
                case :
                    c = .getPercent();
                    field = -1;
                    fieldID = .;
                    break;
                case :
                    c = .getPerMill();
                    field = -1;
                    fieldID = .;
                    break;
                case :
                    c = .getMinusSign();
                    field = -1;
                    fieldID = .;
                    break;
                }
                if (fieldID != null) {
                    if (positions == null) {
                        positions = new ArrayList(2);
                    }
                    FieldPosition fp = new FieldPosition(fieldIDfield);
                    fp.setBeginIndex(stringIndex);
                    fp.setEndIndex(stringIndex + 1);
                    positions.add(fp);
                }
            }
            stringIndex++;
        }
        if (positions != null) {
            return (FieldPosition[])positions.toArray();
        }
        return ;
    }

    
Appends an affix pattern to the given StringBuffer, quoting special characters as needed. Uses the internal affix pattern, if that exists, or the literal affix, if the internal affix pattern is null. The appended string will generate the same affix pattern (or literal affix) when passed to toPattern().

Parameters:
buffer the affix string is appended to this
affixPattern a pattern such as posPrefixPattern; may be null
expAffix a corresponding expanded affix, such as positivePrefix. Ignored unless affixPattern is null. If affixPattern is null, then expAffix is appended as a literal affix.
localized true if the appended pattern should contain localized pattern characters; otherwise, non-localized pattern chars are appended
    private void appendAffix(StringBuffer bufferString affixPattern,
                             String expAffixboolean localized) {
        if (affixPattern == null) {
            appendAffix(bufferexpAffixlocalized);
        } else {
            int i;
            for (int pos=0; pos<affixPattern.length(); pos=i) {
                i = affixPattern.indexOf(pos);
                if (i < 0) {
                    appendAffix(bufferaffixPattern.substring(pos), localized);
                    break;
                }
                if (i > pos) {
                    appendAffix(bufferaffixPattern.substring(posi), localized);
                }
                char c = affixPattern.charAt(++i);
                ++i;
                if (c == ) {
                    buffer.append(c);
                    // Fall through and append another QUOTE below
                } else if (c ==  &&
                           i<affixPattern.length() &&
                           affixPattern.charAt(i) == ) {
                    ++i;
                    buffer.append(c);
                    // Fall through and append another CURRENCY_SIGN below
                } else if (localized) {
                    switch (c) {
                    case :
                        c = .getPercent();
                        break;
                    case :
                        c = .getPerMill();
                        break;
                    case :
                        c = .getMinusSign();
                        break;
                    }
                }
                buffer.append(c);
            }
        }
    }

    
Append an affix to the given StringBuffer, using quotes if there are special characters. Single quotes themselves must be escaped in either case.
    private void appendAffix(StringBuffer bufferString affixboolean localized) {
        boolean needQuote;
        if (localized) {
            needQuote = affix.indexOf(.getZeroDigit()) >= 0
                || affix.indexOf(.getGroupingSeparator()) >= 0
                || affix.indexOf(.getDecimalSeparator()) >= 0
                || affix.indexOf(.getPercent()) >= 0
                || affix.indexOf(.getPerMill()) >= 0
                || affix.indexOf(.getDigit()) >= 0
                || affix.indexOf(.getPatternSeparator()) >= 0
                || affix.indexOf(.getMinusSign()) >= 0
                || affix.indexOf() >= 0;
        }
        else {
            needQuote = affix.indexOf() >= 0
                || affix.indexOf() >= 0
                || affix.indexOf() >= 0
                || affix.indexOf() >= 0
                || affix.indexOf() >= 0
                || affix.indexOf() >= 0
                || affix.indexOf() >= 0
                || affix.indexOf() >= 0
                || affix.indexOf() >= 0;
        }
        if (needQuotebuffer.append('\'');
        if (affix.indexOf('\'') < 0) buffer.append(affix);
        else {
            for (int j=0; j<affix.length(); ++j) {
                char c = affix.charAt(j);
                buffer.append(c);
                if (c == '\''buffer.append(c);
            }
        }
        if (needQuotebuffer.append('\'');
    }

    
Does the real work of generating a pattern.
    private String toPattern(boolean localized) {
        StringBuffer result = new StringBuffer();
        for (int j = 1; j >= 0; --j) {
            if (j == 1)
                appendAffix(resultlocalized);
            else appendAffix(resultlocalized);
            int i;
            int digitCount = 
                        ? getMaximumIntegerDigits()
                        : Math.max(getMinimumIntegerDigits())+1;
            for (i = digitCounti > 0; --i) {
                if (i != digitCount && isGroupingUsed() &&  != 0 &&
                    i %  == 0) {
                    result.append(localized ? .getGroupingSeparator() :
                                  );
                }
                result.append(i <= getMinimumIntegerDigits()
                    ? (localized ? .getZeroDigit() : )
                    : (localized ? .getDigit() : ));
            }
            if (getMaximumFractionDigits() > 0 || )
                result.append(localized ? .getDecimalSeparator() :
                              );
            for (i = 0; i < getMaximumFractionDigits(); ++i) {
                if (i < getMinimumFractionDigits()) {
                    result.append(localized ? .getZeroDigit() :
                                  );
                } else {
                    result.append(localized ? .getDigit() :
                                  );
                }
            }
        if ()
        {
            result.append(localized ? .getExponentSeparator() :
                  );
        for (i=0; i<; ++i)
                    result.append(localized ? .getZeroDigit() :
                                  );
        }
            if (j == 1) {
                appendAffix(resultlocalized);
                if (( ==  && // n == p == null
                     .equals())
                    || ( != null &&
                        .equals())) {
                    if (( != null &&  != null &&
                         .equals("'-" + )) ||
                        ( ==  && // n == p == null
                         .equals(.getMinusSign() + )))
                        break;
                }
                result.append(localized ? .getPatternSeparator() :
                              );
            } else appendAffix(resultlocalized);
        }
        return result.toString();
    }

    
Apply the given pattern to this Format object. A pattern is a short-hand specification for the various formatting properties. These properties can also be changed individually through the various setter methods.

There is no limit to integer digits set by this routine, since that is the typical end-user desire; use setMaximumInteger if you want to set a real value. For negative numbers, use a second pattern, separated by a semicolon

Example "#,#00.0#" -> 1,234.56

This means a minimum of 2 integer digits, 1 fraction digit, and a maximum of 2 fraction digits.

Example: "#,#00.0#;(#,#00.0#)" for negatives in parentheses.

In negative patterns, the minimum and maximum counts are ignored; these are presumed to be set in the positive pattern.

Throws:
java.lang.NullPointerException if pattern is null
java.lang.IllegalArgumentException if the given pattern is invalid.
    public void applyPattern(String pattern) {
        applyPattern(patternfalse);
    }

    
Apply the given pattern to this Format object. The pattern is assumed to be in a localized notation. A pattern is a short-hand specification for the various formatting properties. These properties can also be changed individually through the various setter methods.

There is no limit to integer digits set by this routine, since that is the typical end-user desire; use setMaximumInteger if you want to set a real value. For negative numbers, use a second pattern, separated by a semicolon

Example "#,#00.0#" -> 1,234.56

This means a minimum of 2 integer digits, 1 fraction digit, and a maximum of 2 fraction digits.

Example: "#,#00.0#;(#,#00.0#)" for negatives in parentheses.

In negative patterns, the minimum and maximum counts are ignored; these are presumed to be set in the positive pattern.

Throws:
java.lang.NullPointerException if pattern is null
java.lang.IllegalArgumentException if the given pattern is invalid.
    public void applyLocalizedPattern(String pattern) {
        applyPattern(patterntrue);
    }

    
Does the real work of applying a pattern.
    private void applyPattern(String patternboolean localized) {
        char zeroDigit         = ;
        char groupingSeparator = ;
        char decimalSeparator  = ;
        char percent           = ;
        char perMill           = ;
        char digit             = ;
        char separator         = ;
        String exponent          = ;
        char minus             = ;
        if (localized) {
            zeroDigit         = .getZeroDigit();
            groupingSeparator = .getGroupingSeparator();
            decimalSeparator  = .getDecimalSeparator();
            percent           = .getPercent();
            perMill           = .getPerMill();
            digit             = .getDigit();
            separator         = .getPatternSeparator();
            exponent          = .getExponentSeparator();
            minus             = .getMinusSign();
        }
        boolean gotNegative = false;
         = false;
         = false;
         = false;
        // Two variables are used to record the subrange of the pattern
        // occupied by phase 1.  This is used during the processing of the
        // second pattern (the one representing negative numbers) to ensure
        // that no deviation exists in phase 1 between the two patterns.
        int phaseOneStart = 0;
        int phaseOneLength = 0;
        int start = 0;
        for (int j = 1; j >= 0 && start < pattern.length(); --j) {
            boolean inQuote = false;
            StringBuffer prefix = new StringBuffer();
            StringBuffer suffix = new StringBuffer();
            int decimalPos = -1;
            int multiplier = 1;
            int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0;
            byte groupingCount = -1;
            // The phase ranges from 0 to 2.  Phase 0 is the prefix.  Phase 1 is
            // the section of the pattern with digits, decimal separator,
            // grouping characters.  Phase 2 is the suffix.  In phases 0 and 2,
            // percent, per mille, and currency symbols are recognized and
            // translated.  The separation of the characters into phases is
            // strictly enforced; if phase 1 characters are to appear in the
            // suffix, for example, they must be quoted.
            int phase = 0;
            // The affix is either the prefix or the suffix.
            StringBuffer affix = prefix;
            for (int pos = startpos < pattern.length(); ++pos) {
                char ch = pattern.charAt(pos);
                switch (phase) {
                case 0:
                case 2:
                    // Process the prefix / suffix characters
                    if (inQuote) {
                        // A quote within quotes indicates either the closing
                        // quote or two quotes, which is a quote literal. That
                        // is, we have the second quote in 'do' or 'don''t'.
                        if (ch == ) {
                            if ((pos+1) < pattern.length() &&
                                pattern.charAt(pos+1) == ) {
                                ++pos;
                                affix.append("''"); // 'don''t'
                            } else {
                                inQuote = false// 'do'
                            }
                            continue;
                        }
                    } else {
                        // Process unquoted characters seen in prefix or suffix
                        // phase.
                        if (ch == digit ||
                            ch == zeroDigit ||
                            ch == groupingSeparator ||
                            ch == decimalSeparator) {
                            phase = 1;
                            if (j == 1) {
                                phaseOneStart = pos;
                            }
                            --pos// Reprocess this character
                            continue;
                        } else if (ch == ) {
                            // Use lookahead to determine if the currency sign
                            // is doubled or not.
                            boolean doubled = (pos + 1) < pattern.length() &&
                                pattern.charAt(pos + 1) == ;
                            if (doubled) { // Skip over the doubled character
                             ++pos;
                            }
                             = true;
                            affix.append(doubled ? "'\u00A4\u00A4" : "'\u00A4");
                            continue;
                        } else if (ch == ) {
                            // A quote outside quotes indicates either the
                            // opening quote or two quotes, which is a quote
                            // literal. That is, we have the first quote in 'do'
                            // or o''clock.
                            if (ch == ) {
                                if ((pos+1) < pattern.length() &&
                                    pattern.charAt(pos+1) == ) {
                                    ++pos;
                                    affix.append("''"); // o''clock
                                } else {
                                    inQuote = true// 'do'
                                }
                                continue;
                            }
                        } else if (ch == separator) {
                            // Don't allow separators before we see digit
                            // characters of phase 1, and don't allow separators
                            // in the second pattern (j == 0).
                            if (phase == 0 || j == 0) {
                                throw new IllegalArgumentException("Unquoted special character '" +
                                    ch + "' in pattern \"" + pattern + '"');
                            }
                            start = pos + 1;
                            pos = pattern.length();
                            continue;
                        }
                        // Next handle characters which are appended directly.
                        else if (ch == percent) {
                            if (multiplier != 1) {
                                throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +
                                    pattern + '"');
                            }
                            multiplier = 100;
                            affix.append("'%");
                            continue;
                        } else if (ch == perMill) {
                            if (multiplier != 1) {
                                throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +
                                    pattern + '"');
                            }
                            multiplier = 1000;
                            affix.append("'\u2030");
                            continue;
                        } else if (ch == minus) {
                            affix.append("'-");
                            continue;
                        }
                    }
                    // Note that if we are within quotes, or if this is an
                    // unquoted, non-special character, then we usually fall
                    // through to here.
                    affix.append(ch);
                    break;
                case 1:
                    // Phase one must be identical in the two sub-patterns. We
                    // enforce this by doing a direct comparison. While
                    // processing the first sub-pattern, we just record its
                    // length. While processing the second, we compare
                    // characters.
                    if (j == 1) {
                        ++phaseOneLength;
                    } else {
                        if (--phaseOneLength == 0) {
                            phase = 2;
                            affix = suffix;
                        }
                        continue;
                    }
                    // Process the digits, decimal, and grouping characters. We
                    // record five pieces of information. We expect the digits
                    // to occur in the pattern ####0000.####, and we record the
                    // number of left digits, zero (central) digits, and right
                    // digits. The position of the last grouping character is
                    // recorded (should be somewhere within the first two blocks
                    // of characters), as is the position of the decimal point,
                    // if any (should be in the zero digits). If there is no
                    // decimal point, then there should be no right digits.
                    if (ch == digit) {
                        if (zeroDigitCount > 0) {
                            ++digitRightCount;
                        } else {
                            ++digitLeftCount;
                        }
                        if (groupingCount >= 0 && decimalPos < 0) {
                            ++groupingCount;
                        }
                    } else if (ch == zeroDigit) {
                        if (digitRightCount > 0) {
                            throw new IllegalArgumentException("Unexpected '0' in pattern \"" +
                                pattern + '"');
                        }
                        ++zeroDigitCount;
                        if (groupingCount >= 0 && decimalPos < 0) {
                            ++groupingCount;
                        }
                    } else if (ch == groupingSeparator) {
                        groupingCount = 0;
                    } else if (ch == decimalSeparator) {
                        if (decimalPos >= 0) {
                            throw new IllegalArgumentException("Multiple decimal separators in pattern \"" +
                                pattern + '"');
                        }
                        decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
                    } else if (pattern.regionMatches(posexponent, 0, exponent.length())){
                        if () {
                            throw new IllegalArgumentException("Multiple exponential " +
                                "symbols in pattern \"" + pattern + '"');
                        }
                         = true;
                         = 0;
                        // Use lookahead to parse out the exponential part
                        // of the pattern, then jump into phase 2.
                        pos = pos+exponent.length();
                         while (pos < pattern.length() &&
                               pattern.charAt(pos) == zeroDigit) {
                            ++;
                            ++phaseOneLength;
                            ++pos;
                        }
                        if ((digitLeftCount + zeroDigitCount) < 1 ||
                             < 1) {
                            throw new IllegalArgumentException("Malformed exponential " +
                                "pattern \"" + pattern + '"');
                        }
                        // Transition to phase 2
                        phase = 2;
                        affix = suffix;
                        --pos;
                        continue;
                    } else {
                        phase = 2;
                        affix = suffix;
                        --pos;
                        --phaseOneLength;
                        continue;
                    }
                    break;
                }
            }
            // Handle patterns with no '0' pattern character. These patterns
            // are legal, but must be interpreted.  "##.###" -> "#0.###".
            // ".###" -> ".0##".
            /* We allow patterns of the form "####" to produce a zeroDigitCount
             * of zero (got that?); although this seems like it might make it
             * possible for format() to produce empty strings, format() checks
             * for this condition and outputs a zero digit in this situation.
             * Having a zeroDigitCount of zero yields a minimum integer digits
             * of zero, which allows proper round-trip patterns.  That is, we
             * don't want "#" to become "#0" when toPattern() is called (even
             * though that's what it really is, semantically).
             */
            if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {
                // Handle "###.###" and "###." and ".###"
                int n = decimalPos;
                if (n == 0) { // Handle ".###"
                    ++n;
                }
                digitRightCount = digitLeftCount - n;
                digitLeftCount = n - 1;
                zeroDigitCount = 1;
            }
            // Do syntax checking on the digits.
            if ((decimalPos < 0 && digitRightCount > 0) ||
                (decimalPos >= 0 && (decimalPos < digitLeftCount ||
                 decimalPos > (digitLeftCount + zeroDigitCount))) ||
                 groupingCount == 0 || inQuote) {
                throw new IllegalArgumentException("Malformed pattern \"" +
                    pattern + '"');
            }
            if (j == 1) {
                 = prefix.toString();
                 = suffix.toString();
                 = ;   // assume these for now
                 = ;
                int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
                /* The effectiveDecimalPos is the position the decimal is at or
                 * would be at if there is no decimal. Note that if decimalPos<0,
                 * then digitTotalCount == digitLeftCount + zeroDigitCount.
                 */
                int effectiveDecimalPos = decimalPos >= 0 ?
                    decimalPos : digitTotalCount;
                setMinimumIntegerDigits(effectiveDecimalPos - digitLeftCount);
                setMaximumIntegerDigits( ?
                    digitLeftCount + getMinimumIntegerDigits() :
                    );
                setMaximumFractionDigits(decimalPos >= 0 ?
                    (digitTotalCount - decimalPos) : 0);
                setMinimumFractionDigits(decimalPos >= 0 ?
                    (digitLeftCount + zeroDigitCount - decimalPos) : 0);
                setGroupingUsed(groupingCount > 0);
                this. = (groupingCount > 0) ? groupingCount : 0;
                this. = multiplier;
                setDecimalSeparatorAlwaysShown(decimalPos == 0 ||
                    decimalPos == digitTotalCount);
            } else {
                 = prefix.toString();
                 = suffix.toString();
                gotNegative = true;
            }
        }
        if (pattern.length() == 0) {
             =  = "";
            setMinimumIntegerDigits(0);
            setMinimumFractionDigits(0);
        }
        // If there was no negative pattern, or if the negative pattern is
        // identical to the positive pattern, then prepend the minus sign to
        // the positive pattern to form the negative pattern.
        if (!gotNegative ||
            (.equals()
             && .equals())) {
             = ;
             = "'-" + ;
        }
        expandAffixes();
    }

    
Sets the maximum number of digits allowed in the integer portion of a number. For formatting numbers other than BigInteger and BigDecimal objects, the lower of newValue and 309 is used. Negative input values are replaced with 0.

    public void setMaximumIntegerDigits(int newValue) {
         = Math.min(Math.max(0, newValue), );
             : );
        if ( > ) {
             = ;
                 : );
        }
    }

    
Sets the minimum number of digits allowed in the integer portion of a number. For formatting numbers other than BigInteger and BigDecimal objects, the lower of newValue and 309 is used. Negative input values are replaced with 0.

    public void setMinimumIntegerDigits(int newValue) {
         = Math.min(Math.max(0, newValue), );
             : );
        if ( > ) {
             = ;
                 : );
        }
    }

    
Sets the maximum number of digits allowed in the fraction portion of a number. For formatting numbers other than BigInteger and BigDecimal objects, the lower of newValue and 340 is used. Negative input values are replaced with 0.

    public void setMaximumFractionDigits(int newValue) {
         = Math.min(Math.max(0, newValue), );
                 : );
        }
    }

    
Sets the minimum number of digits allowed in the fraction portion of a number. For formatting numbers other than BigInteger and BigDecimal objects, the lower of newValue and 340 is used. Negative input values are replaced with 0.

    public void setMinimumFractionDigits(int newValue) {
         = Math.min(Math.max(0, newValue), );
                 : );
        }
    }

    
Gets the maximum number of digits allowed in the integer portion of a number. For formatting numbers other than BigInteger and BigDecimal objects, the lower of the return value and 309 is used.

    public int getMaximumIntegerDigits() {
        return ;
    }

    
Gets the minimum number of digits allowed in the integer portion of a number. For formatting numbers other than BigInteger and BigDecimal objects, the lower of the return value and 309 is used.

    public int getMinimumIntegerDigits() {
        return ;
    }

    
Gets the maximum number of digits allowed in the fraction portion of a number. For formatting numbers other than BigInteger and BigDecimal objects, the lower of the return value and 340 is used.

    public int getMaximumFractionDigits() {
        return ;
    }

    
Gets the minimum number of digits allowed in the fraction portion of a number. For formatting numbers other than BigInteger and BigDecimal objects, the lower of the return value and 340 is used.

    public int getMinimumFractionDigits() {
        return ;
    }

    
Gets the currency used by this decimal format when formatting currency values. The currency is obtained by calling DecimalFormatSymbols.getCurrency on this number format's symbols.

Returns:
the currency used by this decimal format, or null
Since:
1.4
    public Currency getCurrency() {
        return .getCurrency();
    }

    
Sets the currency used by this number format when formatting currency values. This does not update the minimum or maximum number of fraction digits used by the number format. The currency is set by calling DecimalFormatSymbols.setCurrency on this number format's symbols.

Parameters:
currency the new currency to be used by this decimal format
Throws:
java.lang.NullPointerException if currency is null
Since:
1.4
    public void setCurrency(Currency currency) {
        if (currency != .getCurrency()) {
            .setCurrency(currency);
            if () {
                expandAffixes();
            }
        }
    }

    
Gets the java.math.RoundingMode used in this DecimalFormat.

Returns:
The RoundingMode used for this DecimalFormat.
Since:
1.6
See also:
setRoundingMode(java.math.RoundingMode)
    public RoundingMode getRoundingMode() {
        return ;
    }

    
Sets the java.math.RoundingMode used in this DecimalFormat.

Parameters:
roundingMode The RoundingMode to be used
Throws:
java.lang.NullPointerException if roundingMode is null.
Since:
1.6
See also:
getRoundingMode()
    public void setRoundingMode(RoundingMode roundingMode) {
        if (roundingMode == null) {
            throw new NullPointerException();
        }
        this. = roundingMode;
        .setRoundingMode(roundingMode);
    }

    
Adjusts the minimum and maximum fraction digits to values that are reasonable for the currency's default fraction digits.
        Currency currency = .getCurrency();
        if (currency == null) {
            try {
                currency = Currency.getInstance(.getInternationalCurrencySymbol());
            } catch (IllegalArgumentException e) {
            }
        }
        if (currency != null) {
            int digits = currency.getDefaultFractionDigits();
            if (digits != -1) {
                int oldMinDigits = getMinimumFractionDigits();
                // Common patterns are "#.##", "#.00", "#".
                // Try to adjust all of them in a reasonable way.
                if (oldMinDigits == getMaximumFractionDigits()) {
                    setMinimumFractionDigits(digits);
                    setMaximumFractionDigits(digits);
                } else {
                    setMinimumFractionDigits(Math.min(digitsoldMinDigits));
                    setMaximumFractionDigits(digits);
                }
            }
        }
    }

    
Reads the default serializable fields from the stream and performs validations and adjustments for older serialized versions. The validations and adjustments are:
  1. Verify that the superclass's digit count fields correctly reflect the limits imposed on formatting numbers other than BigInteger and BigDecimal objects. These limits are stored in the superclass for serialization compatibility with older versions, while the limits for BigInteger and BigDecimal objects are kept in this class. If, in the superclass, the minimum or maximum integer digit count is larger than DOUBLE_INTEGER_DIGITS or if the minimum or maximum fraction digit count is larger than DOUBLE_FRACTION_DIGITS, then the stream data is invalid and this method throws an InvalidObjectException.
  2. If serialVersionOnStream is less than 4, initialize roundingMode to RoundingMode.HALF_EVEN. This field is new with version 4.
  3. If serialVersionOnStream is less than 3, then call the setters for the minimum and maximum integer and fraction digits with the values of the corresponding superclass getters to initialize the fields in this class. The fields in this class are new with version 3.
  4. If serialVersionOnStream is less than 1, indicating that the stream was written by JDK 1.1, initialize useExponentialNotation to false, since it was not present in JDK 1.1.
  5. Set serialVersionOnStream to the maximum allowed value so that default serialization will work properly if this object is streamed out again.

Stream versions older than 2 will not have the affix pattern variables posPrefixPattern etc. As a result, they will be initialized to null, which means the affix strings will be taken as literal values. This is exactly what we want, since that corresponds to the pre-version-2 behavior.

    private void readObject(ObjectInputStream stream)
         throws IOExceptionClassNotFoundException
    {
        stream.defaultReadObject();
         = new DigitList();
        if ( < 4) {
            setRoundingMode(.);
        }
        // We only need to check the maximum counts because NumberFormat
        // .readObject has already ensured that the maximum is greater than the
        // minimum count.
        if (super.getMaximumIntegerDigits() >  ||
            super.getMaximumFractionDigits() > ) {
            throw new InvalidObjectException("Digit count out of range");
        }
        if ( < 3) {
            setMaximumIntegerDigits(super.getMaximumIntegerDigits());
            setMinimumIntegerDigits(super.getMinimumIntegerDigits());
            setMaximumFractionDigits(super.getMaximumFractionDigits());
            setMinimumFractionDigits(super.getMinimumFractionDigits());
        }
        if ( < 1) {
            // Didn't have exponential fields
             = false;
        }
    }
    //----------------------------------------------------------------------
    // INSTANCE VARIABLES
    //----------------------------------------------------------------------
    private transient DigitList digitList = new DigitList();

    
The symbol used as a prefix when formatting positive numbers, e.g. "+".

See also:
getPositivePrefix()
Serial:
    private String  positivePrefix = "";

    
The symbol used as a suffix when formatting positive numbers. This is often an empty string.

See also:
getPositiveSuffix()
Serial:
    private String  positiveSuffix = "";

    
The symbol used as a prefix when formatting negative numbers, e.g. "-".

See also:
getNegativePrefix()
Serial:
    private String  negativePrefix = "-";

    
The symbol used as a suffix when formatting negative numbers. This is often an empty string.

See also:
getNegativeSuffix()
Serial:
    private String  negativeSuffix = "";

    
The prefix pattern for non-negative numbers. This variable corresponds to positivePrefix.

This pattern is expanded by the method expandAffix() to positivePrefix to update the latter to reflect changes in symbols. If this variable is null then positivePrefix is taken as a literal value that does not change when symbols changes. This variable is always null for DecimalFormat objects older than stream version 2 restored from stream.

Since:
1.3
Serial:
    private String posPrefixPattern;

    
The suffix pattern for non-negative numbers. This variable corresponds to positiveSuffix. This variable is analogous to posPrefixPattern; see that variable for further documentation.

Since:
1.3
Serial:
    private String posSuffixPattern;

    
The prefix pattern for negative numbers. This variable corresponds to negativePrefix. This variable is analogous to posPrefixPattern; see that variable for further documentation.

Since:
1.3
Serial:
    private String negPrefixPattern;

    
The suffix pattern for negative numbers. This variable corresponds to negativeSuffix. This variable is analogous to posPrefixPattern; see that variable for further documentation.

Since:
1.3
Serial:
    private String negSuffixPattern;

    
The multiplier for use in percent, per mille, etc.

See also:
getMultiplier()
Serial:
    private int     multiplier = 1;

    
The number of digits between grouping separators in the integer portion of a number. Must be greater than 0 if NumberFormat.groupingUsed is true.

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

    
If true, forces the decimal separator to always appear in a formatted number, even if the fractional part of the number is zero.

    private boolean decimalSeparatorAlwaysShown = false;

    
If true, parse returns BigDecimal wherever possible.

Since:
1.5
See also:
isParseBigDecimal()
Serial:
    private boolean parseBigDecimal = false;


    
True if this object represents a currency format. This determines whether the monetary decimal separator is used instead of the normal one.
    private transient boolean isCurrencyFormat = false;

    
The DecimalFormatSymbols object used by this format. It contains the symbols used to format numbers, e.g. the grouping separator, decimal separator, and so on.

    private DecimalFormatSymbols symbols = null// LIU new DecimalFormatSymbols();

    
True to force the use of exponential (i.e. scientific) notation when formatting numbers.

Since:
1.2
Serial:
    private boolean useExponentialNotation;  // Newly persistent in the Java 2 platform v.1.2

    
FieldPositions describing the positive prefix String. This is lazily created. Use getPositivePrefixFieldPositions when needed.
    private transient FieldPosition[] positivePrefixFieldPositions;

    
FieldPositions describing the positive suffix String. This is lazily created. Use getPositiveSuffixFieldPositions when needed.
    private transient FieldPosition[] positiveSuffixFieldPositions;

    
FieldPositions describing the negative prefix String. This is lazily created. Use getNegativePrefixFieldPositions when needed.
    private transient FieldPosition[] negativePrefixFieldPositions;

    
FieldPositions describing the negative suffix String. This is lazily created. Use getNegativeSuffixFieldPositions when needed.
    private transient FieldPosition[] negativeSuffixFieldPositions;

    
The minimum number of digits used to display the exponent when a number is formatted in exponential notation. This field is ignored if useExponentialNotation is not true.

Since:
1.2
Serial:
    private byte    minExponentDigits;       // Newly persistent in the Java 2 platform v.1.2

    
The maximum number of digits allowed in the integer portion of a BigInteger or BigDecimal number. maximumIntegerDigits must be greater than or equal to minimumIntegerDigits.

Since:
1.5
See also:
getMaximumIntegerDigits()
Serial:
    private int    maximumIntegerDigits = super.getMaximumIntegerDigits();

    
The minimum number of digits allowed in the integer portion of a BigInteger or BigDecimal number. minimumIntegerDigits must be less than or equal to maximumIntegerDigits.

Since:
1.5
See also:
getMinimumIntegerDigits()
Serial:
    private int    minimumIntegerDigits = super.getMinimumIntegerDigits();

    
The maximum number of digits allowed in the fractional portion of a BigInteger or BigDecimal number. maximumFractionDigits must be greater than or equal to minimumFractionDigits.

Since:
1.5
See also:
getMaximumFractionDigits()
Serial:
    private int    maximumFractionDigits = super.getMaximumFractionDigits();

    
The minimum number of digits allowed in the fractional portion of a BigInteger or BigDecimal number. minimumFractionDigits must be less than or equal to maximumFractionDigits.

Since:
1.5
See also:
getMinimumFractionDigits()
Serial:
    private int    minimumFractionDigits = super.getMinimumFractionDigits();

    
The java.math.RoundingMode used in this DecimalFormat.

Since:
1.6
Serial:
    //----------------------------------------------------------------------
    static final int currentSerialVersion = 4;

    
The internal serial version which says which version was written. Possible values are:
  • 0 (default): versions before the Java 2 platform v1.2
  • 1: version for 1.2, which includes the two new fields useExponentialNotation and minExponentDigits.
  • 2: version for 1.3 and later, which adds four new fields: posPrefixPattern, posSuffixPattern, negPrefixPattern, and negSuffixPattern.
  • 3: version for 1.5 and later, which adds five new fields: maximumIntegerDigits, minimumIntegerDigits, maximumFractionDigits, minimumFractionDigits, and parseBigDecimal.
  • 4: version for 1.6 and later, which adds one new field: roundingMode.

Since:
1.2
Serial:
    //----------------------------------------------------------------------
    // CONSTANTS
    //----------------------------------------------------------------------
    // Constants for characters used in programmatic (unlocalized) patterns.
    private static final char       PATTERN_ZERO_DIGIT         = '0';
    private static final char       PATTERN_GROUPING_SEPARATOR = ',';
    private static final char       PATTERN_DECIMAL_SEPARATOR  = '.';
    private static final char       PATTERN_PER_MILLE          = '\u2030';
    private static final char       PATTERN_PERCENT            = '%';
    private static final char       PATTERN_DIGIT              = '#';
    private static final char       PATTERN_SEPARATOR          = ';';
    private static final String     PATTERN_EXPONENT           = "E";
    private static final char       PATTERN_MINUS              = '-';

    
The CURRENCY_SIGN is the standard Unicode symbol for currency. It is used in patterns and substituted with either the currency symbol, or if it is doubled, with the international currency symbol. If the CURRENCY_SIGN is seen in a pattern, then the decimal separator is replaced with the monetary decimal separator. The CURRENCY_SIGN is not localized.
    private static final char       CURRENCY_SIGN = '\u00A4';
    private static final char       QUOTE = '\'';
    private static FieldPosition[] EmptyFieldPositionArray = new FieldPosition[0];
    // Upper limit on integer and fraction digits for a Java double
    static final int DOUBLE_INTEGER_DIGITS  = 309;
    static final int DOUBLE_FRACTION_DIGITS = 340;
    // Upper limit on integer and fraction digits for BigDecimal and BigInteger
    static final int MAXIMUM_INTEGER_DIGITS  = .;
    static final int MAXIMUM_FRACTION_DIGITS = .;
    // Proclaim JDK 1.1 serial compatibility.
    static final long serialVersionUID = 864413376551465018L;

    
Cache to hold the NumberPattern of a Locale.
    private static Hashtable cachedLocaleData = new Hashtable(3);
New to GrepCode? Check out our FAQ X