diff --git a/lib/pure/rationals.nim b/lib/pure/rationals.nim index 3443f75d4c..7fb24c26f3 100644 --- a/lib/pure/rationals.nim +++ b/lib/pure/rationals.nim @@ -39,7 +39,7 @@ proc toRational*[T:SomeInteger](x: T): Rational[T] = result.num = x result.den = 1 -proc toRational*(x: float, n: int = high(int)): Rational[int] = +proc toRational*(x: float, n: int = high(int32)): Rational[int] = ## Calculates the best rational numerator and denominator ## that approximates to `x`, where the denominator is ## smaller than `n` (default is the largest possible @@ -60,19 +60,17 @@ proc toRational*(x: float, n: int = high(int)): Rational[int] = var m11, m22 = 1 m12, m21 = 0 - ai = x.int + ai = int(x) x = x - while m21.float * ai.float + m22.float <= n.float: + while m21 * ai + m22 <= n: swap m12, m11 swap m22, m21 m11 = m12 * ai + m11 m21 = m22 * ai + m21 - if x == ai.float: # division by zero - break - if x > 0x7FFFFFFF.float: # representation failure - break - x = 1.0 / (x - ai.float) - ai = x.int + if x == float(ai): break # division by zero + x = 1/(x - float(ai)) + if x > float(high(int32)): break # representation failure + ai = int(x) result = m11 // m21 proc toFloat*[T](x: Rational[T]): float = @@ -325,15 +323,14 @@ when isMainModule: assert abs(toFloat(y) - 0.4814814814814815) < 1.0e-7 assert toInt(z) == 0 - assert $toRational(0.98765432) == "5376864444397469455/5444075255396513284" - assert $toRational(PI) == "8566508067901016491/2726804208086097199" - assert toRational(0.1, 1000000) == 1 // 10 - assert toRational(0.9, 1000000) == 9 // 10 - #assert toRational(PI) == 80143857 // 25510582 + assert toRational(0.98765432) == 2111111029 // 2137499919 + assert toRational(PI) == 817696623 // 260280919 + assert toRational(0.1) == 1 // 10 + assert toRational(0.9) == 9 // 10 assert toRational(0.0) == 0 // 1 - assert toRational(-0.25, 10) == 1 // -4 - assert toRational(3.2, 10) == 16 // 5 - assert toRational(0.33, 100) == 33 // 100 - assert toRational(0.22, 50) == 11 // 50 + assert toRational(-0.25) == 1 // -4 + assert toRational(3.2) == 16 // 5 + assert toRational(0.33) == 33 // 100 + assert toRational(0.22) == 11 // 50 assert toRational(10.0) == 10 // 1