Add builtin pow() (fix #294)

pull/335/head
A. R. Shajii 2023-03-25 09:35:43 -04:00
parent 87e5181127
commit 3ca06a50ee
2 changed files with 52 additions and 0 deletions

View File

@ -323,6 +323,29 @@ def oct(n):
def hex(n):
return _int_format(n.__index__(), 16, "0x")
def pow(base: float, exp: float):
return base ** exp
@overload
def pow(base: int, exp: int, mod: Optional[int] = None):
if exp < 0:
raise ValueError("pow() negative int exponent not supported")
if mod is not None:
if mod == 0:
raise ValueError("pow() 3rd argument cannot be 0")
base %= mod
result = 1
while exp > 0:
if exp & 1:
x = result * base
result = x % mod if mod is not None else x
y = base * base
base = y % mod if mod is not None else y
exp >>= 1
return result % mod if mod is not None else result
@extend
class int:
def _from_str(s: str, base: int):

View File

@ -258,6 +258,34 @@ def test_divmod():
assert math.isclose(result[0], exp_result[0])
assert math.isclose(result[1], exp_result[1])
@test
def test_pow():
assert pow(3, 4) == 81
assert pow(-3, 3) == -27
assert pow(1, 0) == 1
assert pow(-1, 0) == 1
assert pow(0, 0) == 1
assert pow(12, 12, 42) == 36
assert pow(1234, 4321, 99) == 46
assert pow(9999, 9999, 2) == 1
assert pow(0, 0, 1) == 0
try:
pow(1, -1, 2)
assert False
except ValueError as e:
assert 'negative' in str(e)
try:
pow(1, 1, 0)
assert False
except ValueError as e:
assert 'cannot be 0' in str(e)
assert pow(1.5, 2) == 2.25
assert pow(9, 0.5) == 3.0
assert pow(2.0, -1.0) == 0.5
@test
def test_num_from_str():
assert int('0') == 0
@ -337,6 +365,7 @@ test_gen_builtins()
test_int_format()
test_reversed()
test_divmod()
test_pow()
test_num_from_str()
test_files(open)
import gzip