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);
}