ieee754.java~1~

来自「一个一元曲线多项式数值演示例子」· JAVA~1~ 代码 · 共 602 行 · 第 1/2 页

JAVA~1~
602
字号
package numbercruncher.mathutils;

/**
 * Decompose a floating-point value into its parts
 * according to the IEEE 754 standard.
 */
public class IEEE754 implements IEEE754Constants
{
    /** sign bit as a string */         private String signBit;
    /** exponent bits as a string */    private String exponentBits;
    /** fraction bits as a string */    private String fractionBits;
    /** implied bit as a string */      private String impliedBit;

    /** biased exponent value */    private int  biased;
    /** fraction value */           private long fraction;

    /** exponent bias */            private int bias;

    /** float number value */       private float  floatValue;
    /** double number value */      private double doubleValue;

    /** true if number
        value is zero */            private boolean isZero;
    /** true if reserved
        exponent value */           private boolean isReserved;
    /** true if number type
        is double */                private boolean isDouble;
    /** true if denormalized
        number value */             private boolean isDenormalized;

    //--------------//
    // Constructors //
    //--------------//

    /**
     * Constructor. Decompose a float value.
     * @param value the float value to decompose
     */
    public IEEE754(float value)
    {
        // Convert the value to a character array of '0' and '1'.
        char bits[] = toCharBitArray(Float.floatToIntBits(value), 32);

        floatValue = value;
        isDouble   = false;

        decompose(bits,
                  FLOAT_EXPONENT_BIAS,  FLOAT_EXPONENT_RESERVED,
                  FLOAT_SIGN_INDEX,     FLOAT_SIGN_SIZE,
                  FLOAT_EXPONENT_INDEX, FLOAT_EXPONENT_SIZE,
                  FLOAT_FRACTION_INDEX, FLOAT_FRACTION_SIZE);
    }

    /**
     * Constructor. Decompose a double value.
     * @param value the double-precision value to decompose
     */
    public IEEE754(double value)
    {
        // Convert the value to a character array of '0' and '1'.
        char bits[] = toCharBitArray(Double.doubleToLongBits(value), 64);

        doubleValue = value;
        isDouble    = true;

        decompose(bits,
                  DOUBLE_EXPONENT_BIAS,  DOUBLE_EXPONENT_RESERVED,
                  DOUBLE_SIGN_INDEX,     DOUBLE_SIGN_SIZE,
                  DOUBLE_EXPONENT_INDEX, DOUBLE_EXPONENT_SIZE,
                  DOUBLE_FRACTION_INDEX, DOUBLE_FRACTION_SIZE);
    }

    /**
     * Constructor. Reconstitute a float value.
     * @param sign the sign bit value, 0 or 1
     * @param biasedExponent the biased exponent value, 0..255
     * @param fraction the fraction bits
     * @throws numbercruncher.mathutils.IEEE754.Exception
     */
    public IEEE754(int sign, int biasedExponent, FloatFraction fraction)
        throws Exception
    {
        // Check the sign.
        if ((sign != 0) && (sign != 1)) {
            throw new Exception("Invalid sign bit.");
        }

        validateFloatBiasedExponent(biasedExponent);

        // Consolidate the parts.  First the sign ...
        int intBits = sign;

        // ... then the biased exponent value ...
        intBits <<= FLOAT_EXPONENT_SIZE;
        intBits += biasedExponent;

        // ... and finally the fraction value.
        intBits <<= FLOAT_FRACTION_SIZE;
        intBits += fraction.toInt();

        // Convert to the float value.
        floatValue = Float.intBitsToFloat(intBits);
        isDouble   = false;

        // Convert the value to a character array of '0' and '1'.
        char bits[] = toCharBitArray(intBits, 32);

        decompose(bits,
                  FLOAT_EXPONENT_BIAS,  FLOAT_EXPONENT_RESERVED,
                  FLOAT_SIGN_INDEX,     FLOAT_SIGN_SIZE,
                  FLOAT_EXPONENT_INDEX, FLOAT_EXPONENT_SIZE,
                  FLOAT_FRACTION_INDEX, FLOAT_FRACTION_SIZE);
    }

    /**
     * Constructor. Reconstitute a double value.
     * @param sign the sign bit value, 0 or 1
     * @param biasedExponent the biased exponent value, 0..2047
     * @param fraction the fraction bits
     * @throws numbercruncher.mathutils.IEEE754.Exception
     */
    public IEEE754(int sign, int biasedExponent, DoubleFraction fraction)
        throws Exception
    {
        // Check the sign.
        if ((sign != 0) && (sign != 1)) {
            throw new Exception("Invalid sign bit.");
        }

        validateDoubleBiasedExponent(biasedExponent);

        // Consolidate the parts.  First the sign ...
        long longBits = sign;

        // ... then the biased exponent value ...
        longBits <<= DOUBLE_EXPONENT_SIZE;
        longBits += biasedExponent;

        // ... and finally the fraction value.
        longBits <<= DOUBLE_FRACTION_SIZE;
        longBits += fraction.toLong();

        // Convert to the double value.
        doubleValue = Double.longBitsToDouble(longBits);
        isDouble    = true;

        // Convert the value to a character array of '0' and '1'.
        char bits[] = toCharBitArray(longBits, 64);

        decompose(bits,
                  DOUBLE_EXPONENT_BIAS,  DOUBLE_EXPONENT_RESERVED,
                  DOUBLE_SIGN_INDEX,     DOUBLE_SIGN_SIZE,
                  DOUBLE_EXPONENT_INDEX, DOUBLE_EXPONENT_SIZE,
                  DOUBLE_FRACTION_INDEX, DOUBLE_FRACTION_SIZE);
    }

    //-------------------------//
    // Methods to return parts //
    //-------------------------//

    /**
     * Return the float value.
     * @return the float value
     */
    public float floatValue() { return floatValue; }

    /**
     * Return the double value.
     * @return the double value
     */
    public double doubleValue() { return doubleValue; }

    /**
     * Return the biased value of the exponent.
     * @return the unbiased exponent value
     */
    public int biasedExponent() { return biased; }

    /**
     * Return the unbiased value of the exponent.
     * @return the unbiased exponent value
     */
    public int unbiasedExponent()
    {
        return isDenormalized ? -bias + 1
                              : biased - bias;
    }

    /**
     * Return the sign as a string of '0' and '1'.
     * @return the string
     */
    public String signBit() { return signBit; }

    /**
     * Return the exponent as a string of '0' and '1'.
     * @return the string
     */
    public String exponentBits() { return exponentBits; }

    /**
     * Return the fraction as a string of '0' and '1'.
     * @return the string
     */
    public String fractionBits() { return fractionBits; }

    /**
     * Return the significand as a string of '0', '1' and '.'.
     * @return the string
     */
    public String significandBits()
    {
        return impliedBit + "." + fractionBits;
    }

    /**
     * Return whether or not the value is zero.
     * @return true if zero, else false
     */
    public boolean isZero() { return isZero; }

    /**
     * Return whether or not the value is a double.
     * @return true if a double, else false
     */
    public boolean isDouble() { return isDouble; }

    /**
     * Return whether or not the value is denormalized.
     * @return true if denormalized, else false
     */
    public boolean isDenormalized() { return isDenormalized; }

    /**
     * Return whether or not the exponent value is reserved.
     * @return true if reserved, else false
     */
    public boolean isExponentReserved() { return isReserved; }

    //-----------------------//
    // Decomposition methods //
    //-----------------------//

    /**
     * Convert a long value into a character array of '0' and '1'
     * that represents the value in base 2.
     * @param value the long value
     * @param size the array size
     * @return the character array
     */
    private static char[] toCharBitArray(long value, int size)
    {
        char bits[] = new char[size];

        // Convert each bit from right to left.
        for (int i = size-1; i >= 0; --i) {
            bits[i] = (value & 1) == 0 ? '0' : '1';
            value >>>= 1;
        }

        return bits;
    }

    /**
     * Decompose a floating-point value into its parts.
     * @param bits the character array of '0' and '1'
     *             that represents the value in base 2
     * @param bias the exponent bias value
     * @param reserved the reserved exponent value (other than 0)
     * @param signIndex the index of the sign bit
     * @param signSize the size  of the sign bit
     * @param exponentIndex the index of the exponent
     * @param exponentSize the size  of the exponent
     * @param fractionIndex the index of the fraction
     * @param fractionSize the size  of the fraction
     */
    private void decompose(char bits[],
                           int bias,          int reserved,
                           int signIndex,     int signSize,
                           int exponentIndex, int exponentSize,
                           int fractionIndex, int fractionSize)
    {
        this.bias = bias;

        // Extract the individual parts as strings of '0' and '1'.
        signBit       = new String(bits, signIndex,     signSize);
        exponentBits  = new String(bits, exponentIndex, exponentSize);
        fractionBits  = new String(bits, fractionIndex, fractionSize);

        try {
            biased   = Integer.parseInt(exponentBits, 2);
            fraction = Long.parseLong(fractionBits, 2);
        }
        catch(NumberFormatException ex) {}

        isZero         = (biased == 0) && (fraction == 0);
        isDenormalized = (biased == 0) && (fraction != 0);
        isReserved     = (biased == reserved);

        impliedBit = isDenormalized || isZero || isReserved ? "0" : "1";
    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?