... until the collector arrives ...

This "blog" is really just a scratchpad of mine. There is not much of general interest here. Most of the content is scribbled down "live" as I discover things I want to remember. I rarely go back to correct mistakes in older entries. You have been warned :)

2007-09-04

IEEE 754 Double to Rational Conversion

Here is an algorithm to convert an IEEE 754 double-precision floating point number to a rational (in Java, using the JScience number types):

    private static final Rational doubleToRational(double value) {
        long bits = Double.doubleToLongBits(value);
        int sign = ((bits & 0x8000000000000000L) == 0 ? 1 : -1);
        int fractionBits = 52;
        int bias = 1023;
        int exponent = (int) (((bits & 0x7ff0000000000000L) >> fractionBits) - bias);
        long significand = bits & 0x000fffffffffffffL;
        if (exponent == (bias + 1)) {
            throw new ArithmeticException("cannot convert NaN or infinity to a rational number: "
                    + value);
        }
        if (0 != exponent) {
            significand += 0x0010000000000000L;
        }
        exponent -= fractionBits;
        LargeInteger numerator;
        LargeInteger denominator;
        if (exponent >= 0) {
            numerator = LargeInteger.valueOf(2).pow(exponent).times(sign * significand);
            denominator = LargeInteger.ONE;
        } else {
            numerator = LargeInteger.valueOf(sign * significand);
            denominator = LargeInteger.valueOf(2).pow(-exponent);
        }
        return Rational.valueOf(numerator, denominator);
    }

Blog Archive