mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-16 08:04:20 +00:00
Make toRational proc to loop through integers (#6633)
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user