私は次のモジュロ累乗を書きました。しかし、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
ですgmpy2
。
Python の long 型は任意精度です。long
との間の変換mpz
は常に正確です。
は任意の精度であるためlong
、組み込みの pow() 関数は、gmpy
またはを使用しなくても正しい結果を計算します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