@Override
    public Number parse(String text, ParsePosition pos) {
        // special case NaN
        if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) {
            pos.index = pos.index + symbols.getNaN().length();
            return new Double(Double.NaN);
        }

        boolean[] status = new boolean[STATUS_LENGTH];
        if (!subparse(text, pos, positivePrefix, negativePrefix, digitList, false, status)) {
            return null;
        }

        // special case INFINITY
        if (status[STATUS_INFINITE]) {
            if (status[STATUS_POSITIVE] == (multiplier >= 0)) {
                return new Double(Double.POSITIVE_INFINITY);
            } else {
                return new Double(Double.NEGATIVE_INFINITY);
            }
        }

        if (multiplier == 0) {
            if (digitList.isZero()) {
                return new Double(Double.NaN);
            } else if (status[STATUS_POSITIVE]) {
                return new Double(Double.POSITIVE_INFINITY);
            } else {
                return new Double(Double.NEGATIVE_INFINITY);
            }
        }

        if (isParseBigDecimal()) {
            BigDecimal bigDecimalResult = digitList.getBigDecimal();

            if (multiplier != 1) {
                try {
                    bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier());
                }
                catch (ArithmeticException e) {  // non-terminating decimal expansion
                    bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier(), roundingMode);
                }
            }

            if (!status[STATUS_POSITIVE]) {
                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 (digitList.fitsIntoLong(status[STATUS_POSITIVE], isParseIntegerOnly())) {
                gotDouble = false;
                longResult = digitList.getLong();
                if (longResult < 0) {  // got Long.MIN_VALUE
                    gotLongMinimum = true;
                }
            } else {
                doubleResult = digitList.getDouble();
            }

            // Divide by multiplier. We have to be careful here not to do
            // unneeded conversions between double and long.
            if (multiplier != 1) {
                if (gotDouble) {
                    doubleResult /= multiplier;
                } else {
                    // Avoid converting to double if we can
                    if (longResult % multiplier == 0) {
                        longResult /= multiplier;
                    } else {
                        doubleResult = ((double)longResult) / multiplier;
                        gotDouble = true;
                    }
                }
            }

            if (!status[STATUS_POSITIVE] && !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 (multiplier != 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);
        }
    }
@ Override public Number parse ( String text , ParsePosition pos ) { if ( text . regionMatches ( pos . index , symbols . getNaN ( ) , 0 , symbols . getNaN ( ) . length ( ) ) ) { pos . index = pos . index + symbols . getNaN ( ) . length ( ) ; return new Double ( Double . NaN ) ; } boolean [ ] status = new boolean [ STATUS_LENGTH ] ; if ( ! subparse ( text , pos , positivePrefix , negativePrefix , digitList , false , status ) ) { return null ; } if ( status [ STATUS_INFINITE ] ) { if ( status [ STATUS_POSITIVE ] == ( multiplier >= 0 ) ) { return new Double ( Double . POSITIVE_INFINITY ) ; } else { return new Double ( Double . NEGATIVE_INFINITY ) ; } } if ( multiplier == 0 ) { if ( digitList . isZero ( ) ) { return new Double ( Double . NaN ) ; } else if ( status [ STATUS_POSITIVE ] ) { return new Double ( Double . POSITIVE_INFINITY ) ; } else { return new Double ( Double . NEGATIVE_INFINITY ) ; } } if ( isParseBigDecimal ( ) ) { BigDecimal bigDecimalResult = digitList . getBigDecimal ( ) ; if ( multiplier != 1 ) { try { bigDecimalResult = bigDecimalResult . divide ( getBigDecimalMultiplier ( ) ) ; } catch ( ArithmeticException e ) { bigDecimalResult = bigDecimalResult . divide ( getBigDecimalMultiplier ( ) , roundingMode ) ; } } if ( ! status [ STATUS_POSITIVE ] ) { bigDecimalResult = bigDecimalResult . negate ( ) ; } return bigDecimalResult ; } else { boolean gotDouble = true ; boolean gotLongMinimum = false ; double doubleResult = 0.0 ; long longResult = 0 ; if ( digitList . fitsIntoLong ( status [ STATUS_POSITIVE ] , isParseIntegerOnly ( ) ) ) { gotDouble = false ; longResult = digitList . getLong ( ) ; if ( longResult < 0 ) { gotLongMinimum = true ; } } else { doubleResult = digitList . getDouble ( ) ; } if ( multiplier != 1 ) { if ( gotDouble ) { doubleResult /= multiplier ; } else { if ( longResult % multiplier == 0 ) { longResult /= multiplier ; } else { doubleResult = ( ( double ) longResult ) / multiplier ; gotDouble = true ; } } } if ( ! status [ STATUS_POSITIVE ] && ! gotLongMinimum ) { doubleResult = - doubleResult ; longResult = - longResult ; } if ( multiplier != 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 ) ; } }
Parses text from a string to produce a <code>Number</code>.
<p>
The method attempts to parse text starting at the index given by
<code>pos</code>.
If parsing succeeds, then the index of <code>pos</code> 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 <code>pos</code> can be used to
indicate the starting point for the next call to this method.
If an error occurs, then the index of <code>pos</code> is not
changed, the error index of <code>pos</code> is set to the index of
the character where the error occurred, and null is returned.
<p>
The subclass returned depends on the value of {@link #isParseBigDecimal}
as well as on the string being parsed.
<ul>
<li>If <code>isParseBigDecimal()</code> is false (the default),
most integer values are returned as <code>Long</code>
objects, no matter how they are written: <code>"17"</code> and
<code>"17.000"</code> both parse to <code>Long(17)</code>.
Values that cannot fit into a <code>Long</code> are returned as
<code>Double</code>s. This includes values with a fractional part,
infinite values, <code>NaN</code>, and the value -0.0.
<code>DecimalFormat</code> does <em>not</em> decide whether to
return a <code>Double</code> or a <code>Long</code> 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 <code>"-9,223,372,036,854,775,808.00"</code>, from being
parsed accurately.
<p>
Callers may use the <code>Number</code> methods
<code>doubleValue</code>, <code>longValue</code>, etc., to obtain
the type they want.
<li>If <code>isParseBigDecimal()</code> is true, values are returned
as <code>BigDecimal</code> objects. The values are the ones
constructed by {@link java.math.BigDecimal#BigDecimal(String)}
for corresponding strings in locale-independent format. The
special cases negative and positive infinity and NaN are returned
as <code>Double</code> instances holding the values of the
corresponding <code>Double</code> constants.
</ul>
<p>
<code>DecimalFormat</code> parses all Unicode characters that represent
decimal digits, as defined by <code>Character.digit()</code>. In
addition, <code>DecimalFormat</code> also recognizes as digits the ten
consecutive characters starting with the localized zero digit defined in
the <code>DecimalFormatSymbols</code> object.

@param text the string to be parsed
@param pos  A <code>ParsePosition</code> object with index and error
index information as described above.
@return     the parsed value, or <code>null</code> if the parse fails
@exception  NullPointerException if <code>text</code> or
<code>pos</code> is null.