1767 lines · 66.1 KB · Java
RawDownload
                }             }            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