Fix toRational overflow by calculating internally with int64s (fixes #4194)
This commit is contained in:
parent
6dd0887009
commit
834ad57d94
1 changed files with 11 additions and 11 deletions
|
|
@ -41,26 +41,26 @@ proc toRational*[T:SomeInteger](x: T): Rational[T] =
|
||||||
|
|
||||||
proc toRationalSub(x: float, n: int): Rational[int] =
|
proc toRationalSub(x: float, n: int): Rational[int] =
|
||||||
var
|
var
|
||||||
a = 0
|
a = 0'i64
|
||||||
b, c, d = 1
|
b, c, d = 1'i64
|
||||||
result = 0 // 1 # rational 0
|
result = 0 // 1 # rational 0
|
||||||
while b <= n and d <= n:
|
while b <= n and d <= n:
|
||||||
let ac = (a+c)
|
let ac = (a+c)
|
||||||
let bd = (b+d)
|
let bd = (b+d)
|
||||||
# scale by 1000 so not overflow for high precision
|
# scale by 1000 so not overflow for high precision
|
||||||
let mediant = (ac/1000) / (bd/1000)
|
let mediant = (ac.float/1000) / (bd.float/1000)
|
||||||
if x == mediant:
|
if x == mediant:
|
||||||
if bd <= n:
|
if bd <= n:
|
||||||
result.num = ac
|
result.num = ac.int
|
||||||
result.den = bd
|
result.den = bd.int
|
||||||
return result
|
return result
|
||||||
elif d > b:
|
elif d > b:
|
||||||
result.num = c
|
result.num = c.int
|
||||||
result.den = d
|
result.den = d.int
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
result.num = a
|
result.num = a.int
|
||||||
result.den = b
|
result.den = b.int
|
||||||
return result
|
return result
|
||||||
elif x > mediant:
|
elif x > mediant:
|
||||||
a = ac
|
a = ac
|
||||||
|
|
@ -69,8 +69,8 @@ proc toRationalSub(x: float, n: int): Rational[int] =
|
||||||
c = ac
|
c = ac
|
||||||
d = bd
|
d = bd
|
||||||
if (b > n):
|
if (b > n):
|
||||||
return initRational(c, d)
|
return initRational(c.int, d.int)
|
||||||
return initRational(a, b)
|
return initRational(a.int, b.int)
|
||||||
|
|
||||||
proc toRational*(x: float, n: int = high(int)): Rational[int] =
|
proc toRational*(x: float, n: int = high(int)): Rational[int] =
|
||||||
## Calculate the best rational numerator and denominator
|
## Calculate the best rational numerator and denominator
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue