MCPcopy Index your code
hub / github.com/RustPython/RustPython / modpow

Method modpow

crates/vm/src/builtins/int.rs:397–436  ·  view source on GitHub ↗
(&self, other: PyObjectRef, modulus: PyObjectRef, vm: &VirtualMachine)

Source from the content-addressed store, hash-verified

395 }
396
397 fn modpow(&self, other: PyObjectRef, modulus: PyObjectRef, vm: &VirtualMachine) -> PyResult {
398 let modulus = match modulus.downcast_ref::<Self>() {
399 Some(val) => val.as_bigint(),
400 None => return Ok(vm.ctx.not_implemented()),
401 };
402 if modulus.is_zero() {
403 return Err(vm.new_value_error("pow() 3rd argument cannot be 0"));
404 }
405
406 self.general_op(
407 other,
408 |a, b| {
409 let i = if b.is_negative() {
410 // modular multiplicative inverse
411 // based on rust-num/num-integer#10, should hopefully be published soon
412 fn normalize(a: BigInt, n: &BigInt) -> BigInt {
413 let a = a % n;
414 if a.is_negative() { a + n } else { a }
415 }
416 fn inverse(a: BigInt, n: &BigInt) -> Option<BigInt> {
417 let ExtendedGcd { gcd, x: c, .. } = a.extended_gcd(n);
418 if gcd.is_one() {
419 Some(normalize(c, n))
420 } else {
421 None
422 }
423 }
424 let a = inverse(a % modulus, modulus).ok_or_else(|| {
425 vm.new_value_error("base is not invertible for the given modulus")
426 })?;
427 let b = -b;
428 a.modpow(&b, modulus)
429 } else {
430 a.modpow(b, modulus)
431 };
432 Ok(vm.ctx.new_int(i).into())
433 },
434 vm,
435 )
436 }
437
438 #[pymethod]
439 fn __round__(

Callers 1

int.rsFile · 0.80

Calls 7

as_bigintMethod · 0.80
general_opMethod · 0.80
ok_or_elseMethod · 0.80
ErrClass · 0.50
not_implementedMethod · 0.45
is_zeroMethod · 0.45
new_intMethod · 0.45

Tested by

no test coverage detected