Fix GCD; add LCM ()

pull/401/head
A. R. Shajii 2023-06-02 22:55:47 -04:00 committed by GitHub
parent 1fcd2f296b
commit d1a8d1a79b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 116 additions and 44 deletions
test/stdlib

View File

@ -516,18 +516,60 @@ def remainder(x: float, y: float) -> float:
"""
return _check2(x, y, _C.remainder(x, y))
def gcd(a: float, b: float) -> float:
"""
gcd(float, float) -> float
returns greatest common divisor of x and y.
"""
def _gcd2(a, b):
a = abs(a)
b = abs(b)
while a:
a, b = b % a, a
return b
def gcd(*args):
"""
gcd(*args)
returns greatest common divisor of arguments.
"""
if staticlen(args) == 0:
return 0
res = args[0]
T = type(res)
if staticlen(args) == 1:
return abs(res)
for i in range(1, len(args)):
if res == T(1):
break
res = _gcd2(res, args[i])
return res
def lcm(*args):
"""
lcm(*args)
returns least common multiple of arguments.
"""
def lcm2(a, b):
return abs((a // _gcd2(a, b)) * b)
if staticlen(args) == 0:
return 1
res = args[0]
T = type(res)
if staticlen(args) == 1:
return abs(res)
for i in range(1, len(args)):
if not res:
break
res = lcm2(res, args[i])
return res
@pure
def frexp(x: float) -> Tuple[float, int]:
"""
@ -1195,19 +1237,6 @@ def remainder(x: float32, y: float32) -> float32:
"""
return _C.remainderf(x, y)
@overload
def gcd(a: float32, b: float32) -> float32:
"""
gcd(float32, float32) -> float32
returns greatest common divisor of x and y.
"""
a = abs(a)
b = abs(b)
while a:
a, b = b % a, a
return b
@overload
@pure
def frexp(x: float32) -> Tuple[float32, int]:

View File

@ -411,16 +411,73 @@ def test_remainder():
@test
def test_gcd():
assert math.gcd(0.0, 0.0) == 0
assert math.gcd(1.0, 0.0) == 1
assert math.gcd(-1.0, 0.0) == 1
assert math.gcd(0.0, -1.0) == 1
assert math.gcd(0.0, 1.0) == 1
assert math.gcd(7.0, 1.0) == 1
assert math.gcd(7.0, -1.0) == 1
assert math.gcd(-23.0, 15.0) == 1
assert math.gcd(120.0, 84.0) == 12
assert math.gcd(84.0, -120.0) == 12
assert math.gcd(0, 0) == 0
assert math.gcd(1, 0) == 1
assert math.gcd(-1, 0) == 1
assert math.gcd(0, 1) == 1
assert math.gcd(0, -1) == 1
assert math.gcd(7, 1) == 1
assert math.gcd(7, -1) == 1
assert math.gcd(-23, 15) == 1
assert math.gcd(120, 84) == 12
assert math.gcd(84, -120) == 12
assert math.gcd(Int[128]('1216342683557601535506311712'), Int[128]('436522681849110124616458784')) == Int[128](32)
x = 43461
y = 1064
for c in (652560, 576559230):
a = x * c
b = y * c
assert math.gcd(a, b) == c
assert math.gcd(b, a) == c
assert math.gcd(-a, b) == c
assert math.gcd(b, -a) == c
assert math.gcd(a, -b) == c
assert math.gcd(-b, a) == c
assert math.gcd(-a, -b) == c
assert math.gcd(-b, -a) == c
assert math.gcd() == 0
assert math.gcd(120) == 120
assert math.gcd(-120) == 120
assert math.gcd(120, 84, 102) == 6
assert math.gcd(120, 1, 84) == 1
@test
def test_lcm():
assert math.lcm(0, 0) == 0
assert math.lcm(1, 0) == 0
assert math.lcm(-1, 0) == 0
assert math.lcm(0, 1) == 0
assert math.lcm(0, -1) == 0
assert math.lcm(7, 1) == 7
assert math.lcm(7, -1) == 7
assert math.lcm(-23, 15) == 345
assert math.lcm(120, 84) == 840
assert math.lcm(84, -120) == 840
#assert math.lcm(1216342683557601535506311712, 436522681849110124616458784) == 16592536571065866494401400422922201534178938447014944
x = 4346103
y = 1064501
for c in (8171, 58657):
a = x * c
b = y * c
d = x * y * c
assert math.lcm(a, b) == d
assert math.lcm(b, a) == d
assert math.lcm(-a, b) == d
assert math.lcm(b, -a) == d
assert math.lcm(a, -b) == d
assert math.lcm(-b, a) == d
assert math.lcm(-a, -b) == d
assert math.lcm(-b, -a) == d
assert math.lcm() == 1
assert math.lcm(120) == 120
assert math.lcm(-120) == 120
assert math.lcm(120, 84, 102) == 14280
assert math.lcm(120, 0, 84) == 0
@test
@ -714,6 +771,7 @@ test_gamma()
test_lgamma()
test_remainder()
test_gcd()
test_lcm()
test_frexp()
test_modf()
test_isclose()
@ -1131,20 +1189,6 @@ def test_float32_remainder():
assert math.isnan(math.remainder(NAN32, 1.0f32)) == True
@test
def test_float32_gcd():
assert math.gcd(0.0f32, 0.0f32) == 0.0f32
assert math.gcd(1.0f32, 0.0f32) == 1.0f32
assert math.gcd(-1.0f32, 0.0f32) == 1.0f32
assert math.gcd(0.0f32, -1.0f32) == 1.0f32
assert math.gcd(0.0f32, 1.0f32) == 1.0f32
assert math.gcd(7.0f32, 1.0f32) == 1.0f32
assert math.gcd(7.0f32, -1.0f32) == 1.0f32
assert math.gcd(-23.0f32, 15.0f32) == 1.0f32
assert math.gcd(120.0f32, 84.0f32) == 12.0f32
assert math.gcd(84.0f32, -120.0f32) == 12.0f32
@test
def test_float32_frexp():
assert math.frexp(-2.0f32) == (-0.5f32, 2)
@ -1222,7 +1266,6 @@ test_float32_erfc()
test_float32_gamma()
test_float32_lgamma()
test_float32_remainder()
test_float32_gcd()
test_float32_frexp()
test_float32_modf()
test_float32_isclose()