This commit is contained in:
blueloveTH 2023-06-16 00:51:42 +08:00
parent d7e277e822
commit 3b6da19781

View File

@ -100,15 +100,26 @@ inline void init_builtins(VM* _vm) {
return VAR(MappingProxy(mod)); return VAR(MappingProxy(mod));
}); });
static const auto _mul = [](i64 a, i64 b, i64 c){
if(c < 16384) return (a%c) * (b%c) % c;
i64 res = 0;
while(b > 0){
if(b & 1) res = (res + a) % c;
a = (a << 1) % c;
b >>= 1;
}
return res;
};
_vm->bind_builtin_func<3>("pow", [](VM* vm, ArgsView args) { _vm->bind_builtin_func<3>("pow", [](VM* vm, ArgsView args) {
i64 lhs = CAST(i64, args[0]); // assume lhs>=0 i64 lhs = CAST(i64, args[0]); // assume lhs>=0
i64 rhs = CAST(i64, args[1]); // assume rhs>=0 i64 rhs = CAST(i64, args[1]); // assume rhs>=0
i64 mod = CAST(i64, args[2]); // assume mod>0, mod*mod should not overflow i64 mod = CAST(i64, args[2]); // assume mod>0, mod*mod should not overflow
i64 res = 1; i64 res = 1;
lhs %= mod;
while(rhs){ while(rhs){
i64 lhs_mod = lhs % mod; if(rhs & 1) res = _mul(res, lhs, mod);
if(rhs & 1) res = ((res % mod) * lhs_mod) % mod; lhs = _mul(lhs, lhs, mod);
lhs = (lhs_mod * lhs_mod) % mod;
rhs >>= 1; rhs >>= 1;
} }
return VAR(res); return VAR(res);