mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-23 13:00:17 +00:00
use qpow algo for int to fix precision loss
This commit is contained in:
parent
2c111cd563
commit
30c673b875
@ -171,7 +171,18 @@ void init_builtins(VM* _vm) {
|
||||
|
||||
_vm->_bind_methods<1>({"int", "float"}, "__pow__", [](VM* vm, pkpy::Args& args) {
|
||||
if(args[0]->is_type(vm->tp_int) && args[1]->is_type(vm->tp_int)){
|
||||
return vm->PyInt((i64)round(pow(vm->PyInt_AS_C(args[0]), vm->PyInt_AS_C(args[1]))));
|
||||
i64 lhs = vm->PyInt_AS_C(args[0]);
|
||||
i64 rhs = vm->PyInt_AS_C(args[1]);
|
||||
bool flag = false;
|
||||
if(rhs < 0) {flag = true; rhs = -rhs;}
|
||||
i64 ret = 1;
|
||||
while(rhs){
|
||||
if(rhs & 1) ret *= lhs;
|
||||
lhs *= lhs;
|
||||
rhs >>= 1;
|
||||
}
|
||||
if(flag) return vm->PyFloat((f64)(1.0 / ret));
|
||||
return vm->PyInt(ret);
|
||||
}else{
|
||||
return vm->PyFloat((f64)pow(vm->num_to_float(args[0]), vm->num_to_float(args[1])));
|
||||
}
|
||||
|
@ -117,3 +117,12 @@ assert round(23.2) == 23
|
||||
assert round(23.8) == 24
|
||||
assert round(-23.2) == -23
|
||||
assert round(-23.8) == -24
|
||||
|
||||
|
||||
assert 7**21 == 558545864083284007
|
||||
assert 7**22 == 3909821048582988049
|
||||
assert 2**62 == 4611686018427387904
|
||||
assert eq(2**-2, 0.25)
|
||||
assert 0**0 == 1
|
||||
assert 0**1 == 0
|
||||
assert 1**0 == 1
|
Loading…
x
Reference in New Issue
Block a user