mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-24 05:20: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) {
|
_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)){
|
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{
|
}else{
|
||||||
return vm->PyFloat((f64)pow(vm->num_to_float(args[0]), vm->num_to_float(args[1])));
|
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.8) == 24
|
||||||
assert round(-23.2) == -23
|
assert round(-23.2) == -23
|
||||||
assert round(-23.8) == -24
|
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