Fraction.fromDouble constructor

Fraction.fromDouble(
  1. num value, {
  2. int maxDenominator = 1000000000,
  3. double absoluteError = 0.0,
})

Creates an approximate fraction from a floating point value.

The algorithm uses an expansion of the continued fraction of the floating point value. The resulting fraction is returned once the maxDenominator has been reached, or the result is better than absoluteError.

Implementation

factory Fraction.fromDouble(num value,
    {int maxDenominator = 1000000000, double absoluteError = 0.0}) {
  if (value.isNaN) {
    return Fraction.nan;
  } else if (value.isInfinite) {
    return value < 0 ? Fraction.negativeInfinity : Fraction.infinity;
  }
  var sign = 1;
  if (value < 0) {
    sign = -1;
    value *= -1;
  }
  var numerator1 = value.floor(), denominator1 = 1;
  var numerator2 = 1, denominator2 = 0;
  var integerPart = numerator1;
  var fractionPart = value - numerator1.toDouble();
  while (fractionPart != 0.0 &&
      (value - numerator1 / denominator1).abs() > absoluteError) {
    final newValue = 1.0 / fractionPart;
    integerPart = newValue.floor();
    fractionPart = newValue - integerPart.toDouble();
    final temp1 = numerator2;
    numerator2 = numerator1;
    numerator1 = numerator1 * integerPart + temp1;
    final temp2 = denominator2;
    denominator2 = denominator1;
    denominator1 = denominator1 * integerPart + temp2;
    if (maxDenominator < denominator1) {
      return numerator2 == 0
          ? Fraction(sign * numerator1, denominator1)
          : Fraction(sign * numerator2, denominator2);
    }
  }
  return Fraction(sign * numerator1, denominator1);
}