Special handling for base -1, 0, 1 for big exp

This commit is contained in:
Jeong YunWon
2019-05-02 22:42:28 +09:00
parent c18615b6e5
commit 0bf7ff96b8
2 changed files with 21 additions and 6 deletions

View File

@@ -39,9 +39,14 @@ assert_raises(
lambda: round(-float('inf')),
'OverflowError: cannot convert float NaN to integer')
assert pow(0, 0) == 1
assert pow(2, 2) == 4
assert pow(1, 2.0) == 1.0
assert pow(2.0, 1) == 2.0
assert pow(0, 10**1000) == 0
assert pow(1, 10**1000) == 1
assert pow(-1, 10**1000+1) == -1
assert pow(-1, 10**1000) == 1
assert pow(2, 4, 5) == 1
assert_raises(

View File

@@ -3,7 +3,7 @@ use std::hash::{Hash, Hasher};
use num_bigint::BigInt;
use num_integer::Integer;
use num_traits::{Pow, Signed, ToPrimitive, Zero};
use num_traits::{One, Pow, Signed, ToPrimitive, Zero};
use crate::format::FormatSpec;
use crate::function::{OptionalArg, PyFuncArgs};
@@ -13,7 +13,6 @@ use crate::pyobject::{
};
use crate::vm::VirtualMachine;
use super::objfloat::PyFloat;
use super::objstr::{PyString, PyStringRef};
use super::objtype;
use crate::obj::objtype::PyClassRef;
@@ -116,11 +115,22 @@ fn inner_pow(int1: &PyInt, int2: &PyInt, vm: &VirtualMachine) -> PyResult {
let v1 = int1.float(vm)?;
let v2 = int2.float(vm)?;
vm.ctx.new_float(v1.pow(v2))
} else if let Some(v2) = int2.value.to_u64() {
vm.ctx.new_int(int1.value.pow(v2))
} else {
// missing feature: BigInt exp
vm.ctx.not_implemented()
if let Some(v2) = int2.value.to_u64() {
vm.ctx.new_int(int1.value.pow(v2))
} else if int1.value.is_one() || int1.value.is_zero() {
vm.ctx.new_int(int1.value.clone())
} else if int1.value == BigInt::from(-1) {
if int2.value.is_odd() {
vm.ctx.new_int(-1)
} else {
vm.ctx.new_int(1)
}
} else {
// missing feature: BigInt exp
// practically, exp over u64 is not possible to calculate anyway
vm.ctx.not_implemented()
}
})
}