public static RationalNumber valueOf(double value) {
        if (value >= Integer.MAX_VALUE) {
            return new RationalNumber(Integer.MAX_VALUE, 1);
        }
        if (value <= -Integer.MAX_VALUE) {
            return new RationalNumber(-Integer.MAX_VALUE, 1);
        }

        boolean negative = false;
        if (value < 0) {
            negative = true;
            value = Math.abs(value);
        }

        final RationalNumber l;
        final RationalNumber h;

        if (value == 0) {
            return new RationalNumber(0, 1);
        }
        if (value >= 1) {
            final int approx = (int) value;
            if (approx < value) {
                l = new RationalNumber(approx, 1);
                h = new RationalNumber(approx + 1, 1);
            } else {
                l = new RationalNumber(approx - 1, 1);
                h = new RationalNumber(approx, 1);
            }
        } else {
            final int approx = (int) (1.0 / value);
            if (1.0 / approx < value) {
                l = new RationalNumber(1, approx);
                h = new RationalNumber(1, approx - 1);
            } else {
                l = new RationalNumber(1, approx + 1);
                h = new RationalNumber(1, approx);
            }
        }
        Option low = Option.factory(l, value);
        Option high = Option.factory(h, value);

        Option bestOption = low.error < high.error ? low : high;

        final int maxIterations = 100; // value is quite high, actually.
                                       // shouldn't matter.
        for (int count = 0; bestOption.error > TOLERANCE && count < maxIterations; count++) {
            final RationalNumber mediant = factoryMethod(low.rationalNumber.numerator + high.rationalNumber.numerator,
                    low.rationalNumber.divisor + high.rationalNumber.divisor);
            final Option mediantOption = Option.factory(mediant, value);

            if (value < mediant.doubleValue()) {
                if (high.error <= mediantOption.error) {
                    break;
                }

                high = mediantOption;
            } else {
                if (low.error <= mediantOption.error) {
                    break;
                }

                low = mediantOption;
            }

            if (mediantOption.error < bestOption.error) {
                bestOption = mediantOption;
            }
        }

        return negative ? bestOption.rationalNumber.negate() : bestOption.rationalNumber;
    }
Calculate rational number using successive approximations.

@param value rational number double value
@return the RationalNumber representation of the double value
src/main/java/org/apache/commons/imaging/common/RationalNumber.java