diff --git a/integration_tests/test_math.py b/integration_tests/test_math.py index 1903380113..7f3b7a6fa5 100644 --- a/integration_tests/test_math.py +++ b/integration_tests/test_math.py @@ -1,8 +1,44 @@ -from math import factorial +from math import factorial, isqrt, perm, comb, degrees, radians +from ltypes import i32, f64 def test_factorial_1(): i: i32 i = factorial(10) print(i) + +def test_comb(): + i: i32 + i = comb(10, 2) + print(i) + + +def test_perm(): + i: i32 + i = perm(5, 2) + + +def test_isqrt(): + i: i32 + i = isqrt(15) + print(i) + + +def test_degrees(): + i: f64 + i = degrees(32.2) + print(i) + + +def test_radians(): + i: f64 + i = degrees(100.1) + print(i) + + test_factorial_1() +test_comb() +test_isqrt() +test_perm() +test_degrees() +test_radians() diff --git a/src/runtime/math.py b/src/runtime/math.py index 61c6dec835..477cf313f6 100644 --- a/src/runtime/math.py +++ b/src/runtime/math.py @@ -1,3 +1,8 @@ +from ltypes import i32, f64 + +def pi() -> f64: + return 3.141592653589793238462643383279502884197 + def factorial(x: i32) -> i32: """ Computes the factorial of `x`. @@ -7,7 +12,63 @@ def factorial(x: i32) -> i32: return 0 result: i32 result = 1 - while x > 0: - result = result * x - x -= 1 + i: i32 + for i in range(1, x+1): + result *= i return result + + +def comb(n: i32, k: i32) -> i32: + """ + Computes the result of `nCk`, i.e, the number of ways to choose `k` + items from `n` items without repetition and without order. + """ + + if n < k or n < 0: + return 0 + return factorial(n)//(factorial(k)*factorial(n-k)) + + +def perm(n: i32, k: i32) -> i32: + """ + Computes the result of `nPk`, i.e, the number of ways to choose `k` items + from `n` items without repetition and with order. + """ + + if n < k or n < 0: + return 0 + return factorial(n)//factorial(n-k) + + +def isqrt(n: i32) -> i32: + """ + Computes the integer square root of the nonnegative integer `n`. + """ + if n < 0: + raise ValueError('`n` should be nonnegative') + low: i32 + mid: i32 + high: i32 + low = 0 + high = n+1 + while low + 1 < high: + mid = (low + high)//2 + if mid*mid <= n: + low = mid + else: + high = mid + return low + + +def degrees(x: f64) -> f64: + """ + Convert angle `x` from radians to degrees. + """ + return x * 180.0 / pi() + + +def radians(x: f64) -> f64: + """ + Convert angle `x` from degrees to radians. + """ + return x * pi() / 180.0