Skip to content

Commit 0bf7ff9

Browse files
committed
Special handling for base -1, 0, 1 for big exp
1 parent c18615b commit 0bf7ff9

2 files changed

Lines changed: 21 additions & 6 deletions

File tree

tests/snippets/math_basics.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,14 @@
3939
lambda: round(-float('inf')),
4040
'OverflowError: cannot convert float NaN to integer')
4141

42+
assert pow(0, 0) == 1
4243
assert pow(2, 2) == 4
4344
assert pow(1, 2.0) == 1.0
4445
assert pow(2.0, 1) == 2.0
46+
assert pow(0, 10**1000) == 0
47+
assert pow(1, 10**1000) == 1
48+
assert pow(-1, 10**1000+1) == -1
49+
assert pow(-1, 10**1000) == 1
4550

4651
assert pow(2, 4, 5) == 1
4752
assert_raises(

vm/src/obj/objint.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::hash::{Hash, Hasher};
33

44
use num_bigint::BigInt;
55
use num_integer::Integer;
6-
use num_traits::{Pow, Signed, ToPrimitive, Zero};
6+
use num_traits::{One, Pow, Signed, ToPrimitive, Zero};
77

88
use crate::format::FormatSpec;
99
use crate::function::{OptionalArg, PyFuncArgs};
@@ -13,7 +13,6 @@ use crate::pyobject::{
1313
};
1414
use crate::vm::VirtualMachine;
1515

16-
use super::objfloat::PyFloat;
1716
use super::objstr::{PyString, PyStringRef};
1817
use super::objtype;
1918
use crate::obj::objtype::PyClassRef;
@@ -116,11 +115,22 @@ fn inner_pow(int1: &PyInt, int2: &PyInt, vm: &VirtualMachine) -> PyResult {
116115
let v1 = int1.float(vm)?;
117116
let v2 = int2.float(vm)?;
118117
vm.ctx.new_float(v1.pow(v2))
119-
} else if let Some(v2) = int2.value.to_u64() {
120-
vm.ctx.new_int(int1.value.pow(v2))
121118
} else {
122-
// missing feature: BigInt exp
123-
vm.ctx.not_implemented()
119+
if let Some(v2) = int2.value.to_u64() {
120+
vm.ctx.new_int(int1.value.pow(v2))
121+
} else if int1.value.is_one() || int1.value.is_zero() {
122+
vm.ctx.new_int(int1.value.clone())
123+
} else if int1.value == BigInt::from(-1) {
124+
if int2.value.is_odd() {
125+
vm.ctx.new_int(-1)
126+
} else {
127+
vm.ctx.new_int(1)
128+
}
129+
} else {
130+
// missing feature: BigInt exp
131+
// practically, exp over u64 is not possible to calculate anyway
132+
vm.ctx.not_implemented()
133+
}
124134
})
125135
}
126136

0 commit comments

Comments
 (0)