} } return (isNegative)? -dValue : dValue; } } /* * Take a FormattedFloatingDecimal, which we presumably just scanned in, * and find out what its value is, as a float. * This is distinct from doubleValue() to avoid the extremely * unlikely case of a double rounding error, wherein the converstion * to double has one rounding error, and the conversion of that double * to a float has another rounding error, IN THE WRONG DIRECTION, * ( because of the preference to a zero low-order bit ). */ public strictfp float floatValue(){ int kDigits = Math.min( nDigits, singleMaxDecimalDigits+1 ); int iValue; float fValue; // First, check for NaN and Infinity values if(digits == infinity || digits == notANumber) { if(digits == notANumber) return Float.NaN; else return (isNegative?Float.NEGATIVE_INFINITY:Float.POSITIVE_INFINITY); } else { /* * convert the lead kDigits to an integer. */ iValue = (int)digits[0]-(int)'0'; for ( int i=1; i < kDigits; i++ ){ iValue = iValue*10 + (int)digits[i]-(int)'0'; } fValue = (float)iValue; int exp = decExponent-kDigits; /* * iValue now contains an integer with the value of * the first kDigits digits of the number. * fValue contains the (float) of the same. */ if ( nDigits <= singleMaxDecimalDigits ){ /* * possibly an easy case. * We know that the digits can be represented * exactly. And if the exponent isn't too outrageous, * the whole thing can be done with one operation, * thus one rounding error. * Note that all our constructors trim all leading and * trailing zeros, so simple values (including zero) * will always end up here. */ if (exp == 0 || fValue == 0.0f) return (isNegative)? -fValue : fValue; // small floating integer else if ( exp >= 0 ){ if ( exp <= singleMaxSmallTen ){ /* * Can get the answer with one operation, * thus one roundoff. */ fValue *= singleSmall10pow[exp]; return (isNegative)? -fValue : fValue; } int slop = singleMaxDecimalDigits - kDigits; if ( exp <= singleMaxSmallTen+slop ){ /* * We can multiply dValue by 10^(slop) * and it is still "small" and exact. * Then we can multiply by 10^(exp-slop) * with one rounding. */ fValue *= singleSmall10pow[slop]; fValue *= singleSmall10pow[exp-slop]; return (isNegative)? -fValue : fValue; } /* * Else we have a hard case with a positive exp. */ } else { if ( exp >= -singleMaxSmallTen ){ /* * Can get the answer in one division. */ fValue /= singleSmall10pow[-exp]; return (isNegative)? -fValue : fValue; } /* * Else we have a hard case with a negative exp. */ } } else if ( (decExponent >= nDigits) && (nDigits+decExponent <= maxDecimalDigits) ){ /* * In double-precision, this is an exact floating integer. * So we can compute to double, then shorten to float * with one round, and get the right answer. * * First, finish accumulating digits. * Then convert that integer to a double, multiply * by the appropriate power of ten, and convert to float. */ long lValue = (long)iValue; for ( int i=kDigits; i < nDigits; i++ ){ lValue = lValue*10L + (long)((int)digits[i]-(int)'0'); } double dValue = (double)lValue; exp = decExponent-nDigits; dValue *= small10pow[exp]; fValue = (float)dValue; return (isNegative)? -fValue : fValue; } /* * Harder cases: * The sum of digits plus exponent is greater than * what we think we can do with one error. * * Start by weeding out obviously out-of-range * results, then convert to double and go to * common hard-case code. */ if ( decExponent > singleMaxDecimalExponent+1 ){ /* * Lets face it. This is going to be * Infinity. Cut to the chase. */ return (isNegative)? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY; } else if ( decExponent < singleMinDecimalExponent-1 ){ /* * Lets face it. This is going to be * zero. Cut to the chase. */ return (isNegative)? -0.0f : 0.0f; } /* * Here, we do 'way too much work, but throwing away * our partial results, and going and doing the whole * thing as double, then throwing away half the bits that computes * when we convert back to float. * * The alternative is to reproduce the whole multiple-precision * algorythm for float precision, or to try to parameterize it * for common usage. The former will take about 400 lines of code, * and the latter I tried without success. Thus the semi-hack * answer here. */ mustSetRoundDir = !fromHex; double dValue = doubleValue(); return stickyRound( dValue ); } } /* * All the positive powers of 10 that can be * represented exactly in double/float. */ private static final double small10pow[] = { 1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9, 1.0e10, 1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15, 1.0e16, 1.0e17, 1.0e18, 1.0e19, 1.0e20, 1.0e21, 1.0e22 }; private static final float singleSmall10pow[] = { 1.0e0f, 1.0e1f, 1.0e2f, 1.0e3f, 1.0e4f, 1.0e5f, 1.0e6f, 1.0e7f, 1.0e8f, 1.0e9f, 1.0e10f }; private static final double big10pow[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; private static final double tiny10pow[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 }; private static final int maxSmallTen = small10pow.length-1; private static final int singleMaxSmallTen = singleSmall10pow.length-1; private static final int small5pow[] = { 1, 5, 5*5, 5*5*5, 5*5*5*5, 5*5*5*5*5, 5*5*5*5*5*5, 5*5*5*5*5*5*5, 5*5*5*5*5*5*5*5, 5*5*5*5*5*5*5*5*5, 5*5*5*5*5*5*5*5*5*5, 5*5*5*5*5*5*5*5*5*5*5, 5*5*5*5*5*5*5*5*5*5*5*5, 5*5*5*5*5*5*5*5*5*5*5*5*5 }; private static final long long5pow[] = { 1L, 5L, 5L*5, 5L*5*5, 5L*5*5*5, 5L*5*5*5*5, 5L*5*5*5*5*5, 5L*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, }; // approximately ceil( log2( long5pow[i] ) ) private static final int n5bits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21, 24, 26, 28, 31, 33, 35, 38, 40, 42, 45, 47, 49, 52, 54, 56, 59, 61, }; private static final char infinity[] = { 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y' }; private static final char notANumber[] = { 'N', 'a', 'N' }; private static final char zero[] = { '0', '0', '0', '0', '0', '0', '0', '0' };}Lines 1501–1767 of 1767. Previous lines
} } return (isNegative)? -dValue : dValue; } } /* * Take a FormattedFloatingDecimal, which we presumably just scanned in, * and find out what its value is, as a float. * This is distinct from doubleValue() to avoid the extremely * unlikely case of a double rounding error, wherein the converstion * to double has one rounding error, and the conversion of that double * to a float has another rounding error, IN THE WRONG DIRECTION, * ( because of the preference to a zero low-order bit ). */ public strictfp float floatValue(){ int kDigits = Math.min( nDigits, singleMaxDecimalDigits+1 ); int iValue; float fValue; // First, check for NaN and Infinity values if(digits == infinity || digits == notANumber) { if(digits == notANumber) return Float.NaN; else return (isNegative?Float.NEGATIVE_INFINITY:Float.POSITIVE_INFINITY); } else { /* * convert the lead kDigits to an integer. */ iValue = (int)digits[0]-(int)'0'; for ( int i=1; i < kDigits; i++ ){ iValue = iValue*10 + (int)digits[i]-(int)'0'; } fValue = (float)iValue; int exp = decExponent-kDigits; /* * iValue now contains an integer with the value of * the first kDigits digits of the number. * fValue contains the (float) of the same. */ if ( nDigits <= singleMaxDecimalDigits ){ /* * possibly an easy case. * We know that the digits can be represented * exactly. And if the exponent isn't too outrageous, * the whole thing can be done with one operation, * thus one rounding error. * Note that all our constructors trim all leading and * trailing zeros, so simple values (including zero) * will always end up here. */ if (exp == 0 || fValue == 0.0f) return (isNegative)? -fValue : fValue; // small floating integer else if ( exp >= 0 ){ if ( exp <= singleMaxSmallTen ){ /* * Can get the answer with one operation, * thus one roundoff. */ fValue *= singleSmall10pow[exp]; return (isNegative)? -fValue : fValue; } int slop = singleMaxDecimalDigits - kDigits; if ( exp <= singleMaxSmallTen+slop ){ /* * We can multiply dValue by 10^(slop) * and it is still "small" and exact. * Then we can multiply by 10^(exp-slop) * with one rounding. */ fValue *= singleSmall10pow[slop]; fValue *= singleSmall10pow[exp-slop]; return (isNegative)? -fValue : fValue; } /* * Else we have a hard case with a positive exp. */ } else { if ( exp >= -singleMaxSmallTen ){ /* * Can get the answer in one division. */ fValue /= singleSmall10pow[-exp]; return (isNegative)? -fValue : fValue; } /* * Else we have a hard case with a negative exp. */ } } else if ( (decExponent >= nDigits) && (nDigits+decExponent <= maxDecimalDigits) ){ /* * In double-precision, this is an exact floating integer. * So we can compute to double, then shorten to float * with one round, and get the right answer. * * First, finish accumulating digits. * Then convert that integer to a double, multiply * by the appropriate power of ten, and convert to float. */ long lValue = (long)iValue; for ( int i=kDigits; i < nDigits; i++ ){ lValue = lValue*10L + (long)((int)digits[i]-(int)'0'); } double dValue = (double)lValue; exp = decExponent-nDigits; dValue *= small10pow[exp]; fValue = (float)dValue; return (isNegative)? -fValue : fValue; } /* * Harder cases: * The sum of digits plus exponent is greater than * what we think we can do with one error. * * Start by weeding out obviously out-of-range * results, then convert to double and go to * common hard-case code. */ if ( decExponent > singleMaxDecimalExponent+1 ){ /* * Lets face it. This is going to be * Infinity. Cut to the chase. */ return (isNegative)? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY; } else if ( decExponent < singleMinDecimalExponent-1 ){ /* * Lets face it. This is going to be * zero. Cut to the chase. */ return (isNegative)? -0.0f : 0.0f; } /* * Here, we do 'way too much work, but throwing away * our partial results, and going and doing the whole * thing as double, then throwing away half the bits that computes * when we convert back to float. * * The alternative is to reproduce the whole multiple-precision * algorythm for float precision, or to try to parameterize it * for common usage. The former will take about 400 lines of code, * and the latter I tried without success. Thus the semi-hack * answer here. */ mustSetRoundDir = !fromHex; double dValue = doubleValue(); return stickyRound( dValue ); } } /* * All the positive powers of 10 that can be * represented exactly in double/float. */ private static final double small10pow[] = { 1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9, 1.0e10, 1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15, 1.0e16, 1.0e17, 1.0e18, 1.0e19, 1.0e20, 1.0e21, 1.0e22 }; private static final float singleSmall10pow[] = { 1.0e0f, 1.0e1f, 1.0e2f, 1.0e3f, 1.0e4f, 1.0e5f, 1.0e6f, 1.0e7f, 1.0e8f, 1.0e9f, 1.0e10f }; private static final double big10pow[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; private static final double tiny10pow[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 }; private static final int maxSmallTen = small10pow.length-1; private static final int singleMaxSmallTen = singleSmall10pow.length-1; private static final int small5pow[] = { 1, 5, 5*5, 5*5*5, 5*5*5*5, 5*5*5*5*5, 5*5*5*5*5*5, 5*5*5*5*5*5*5, 5*5*5*5*5*5*5*5, 5*5*5*5*5*5*5*5*5, 5*5*5*5*5*5*5*5*5*5, 5*5*5*5*5*5*5*5*5*5*5, 5*5*5*5*5*5*5*5*5*5*5*5, 5*5*5*5*5*5*5*5*5*5*5*5*5 }; private static final long long5pow[] = { 1L, 5L, 5L*5, 5L*5*5, 5L*5*5*5, 5L*5*5*5*5, 5L*5*5*5*5*5, 5L*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, }; // approximately ceil( log2( long5pow[i] ) ) private static final int n5bits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21, 24, 26, 28, 31, 33, 35, 38, 40, 42, 45, 47, 49, 52, 54, 56, 59, 61, }; private static final char infinity[] = { 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y' }; private static final char notANumber[] = { 'N', 'a', 'N' }; private static final char zero[] = { '0', '0', '0', '0', '0', '0', '0', '0' }; }