我写了以下模幂运算。但我不确定从 MPZ 类型转换为 long 时是否会降低精度。
def mypowmod(base, power, modulus):
base = gmpy.mpz(base)
power = gmpy.mpz(power)
modulus = gmpy.mpz(modulus)
result = pow(base, power, modulus)
return long(result)
免责声明:我是gmpy
and的维护者gmpy2
。
Python long 类型是任意精度的。转换到/从long
并且mpz
总是准确的。
由于long
是任意精度,内置 pow() 函数将计算正确的结果,而无需使用gmpy
or gmpy2
。但是,使用该mpz
类型会快得多。快速测试表明,即使只有 10 位数字,它也更快。
$ python -m timeit -s "import gmpy;a=10;b=gmpy.mpz('1'*a);p=gmpy.mpz('2'*a)-7;m=gmpy.mpz('3'*a)+11" "pow(b,p,m)"
1000000 loops, best of 3: 1.41 usec per loop
$ python -m timeit -s "a=10;b=long('1'*a);p=long('2'*a)-7;m=long('3'*a)+11" "pow(b,p,m)"
100000 loops, best of 3: 8.89 usec per loop
gmpy
没有 powmod() 函数。该功能是在gmpy2
. gmpy2.powmod
将自动将参数转换为mpz
并返回mpz
结果。你的函数可以写成:
def mypowmod(base, power, modulus):
return long(gmpy2.powmod(base, power modulus)
即使包括 和 之间的转换long
,mpz
它仍然比使用内置long
类型快得多。
python -m timeit -s "import gmpy2;a=10;b=long('1'*a);p=long('2'*a)-7;m=long('3'*a)+11" "long(gmpy2.powmod(b,p,m))"
1000000 loops, best of 3: 1.72 usec per loop
不。
但是gmpy.mpz
大多数情况下不需要使用该类型,因为内置long
类型具有此功能所需的所有操作。代码使用内置pow
函数而不是说gmpy.powmod
函数,因此不需要转换为gmpy.mpz
,并且随着pow
函数返回 a long
,代码变为:
def mypowmod(base, power, modulus):
result = pow(base, power, modulus)
return result
最好写成:
mypowmod = pow