diff --git a/integration_tests/test_math_02.py b/integration_tests/test_math_02.py index 2b63a6ac0d..fc8f1af35e 100644 --- a/integration_tests/test_math_02.py +++ b/integration_tests/test_math_02.py @@ -1,6 +1,6 @@ from math import (sin, cos, tan, pi, sqrt, log, log10, log2, erf, erfc, gamma, lgamma, asin, acos, atan, atan2, asinh, acosh, atanh, - tanh, sinh, cosh) + tanh, sinh, cosh, hypot, copysign) def test_trig(): # TODO: importing from `math` doesn't work here yet: @@ -46,7 +46,20 @@ def test_hyperbolic(): assert abs(cosh(1.0) - 0) < eps assert abs(tanh(0.0) - 0) < eps +def test_copysign(): + eps: f64 = 1e-12 + assert abs(copysign(-8.56, 97.21) - 8.56) < eps + assert abs(copysign(-43.0, -76.67) - (-43.0)) < eps + +def test_hypot(): + eps: f64 = 1e-12 + assert abs(hypot(3, 4) - 5.0) < eps + assert abs(hypot(-3, 4) - 5.0) < eps + assert abs(hypot(6, 6) - 8.48528137423857) < eps + test_trig() test_sqrt() test_log() test_special() +test_copysign() +test_hypot() diff --git a/src/runtime/math.py b/src/runtime/math.py index fcd594bf68..8ebf4d8a74 100644 --- a/src/runtime/math.py +++ b/src/runtime/math.py @@ -140,6 +140,24 @@ def lcm(a: i32, b: i32) -> i32: return 0 return (a*b)//gcd(a, b) + +def copysign(x: f64, y: f64) -> f64: + """ + Return `x` with the sign of `y`. + """ + if y > 0.0 or (y == 0.0 and atan2(y, -1.0) > 0.0): + return fabs(x) + else: + return -fabs(x) + + +def hypot(x: i32, y: i32) -> f64: + """ + Returns the hypotenuse of the right triangle with sides `x` and `y`. + """ + return sqrt(1.0*(x**2 + y**2)) + + def sqrt(x: f64) -> f64: return x**(1/2)