【问题标题】:Do I loose precision when converting from MPZ to long?从 MPZ 转换为 long 时,我会失去精度吗?
【发布时间】:2015-02-15 06:27:17
【问题描述】:

我写了以下模幂运算。但我不确定从 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)

【问题讨论】:

标签: python gmpy


【解决方案1】:

免责声明:我是gmpygmpy2的维护者。

Python long 类型是任意精度的。与longmpz 之间的转换始终是准确的。

由于long 是任意精度,内置的 pow() 函数将计算正确的结果,而不需要使用gmpygmpy2。但是,使用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)

即使包括longmpz之间的转换,它仍然比使用内置的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

【讨论】:

    【解决方案2】:

    没有。

    但是使用gmpy.mpz 类型大部分是不需要的,因为内置的long 类型具有此功能所需的所有操作。该代码使用内置的pow 函数而不是gmpy.powmod 函数,因此不需要转换为gmpy.mpz,并且当pow 函数返回long 时,代码变为:

    def mypowmod(base, power, modulus):
      result = pow(base, power, modulus)
      return result
    

    最好写成:

    mypowmod = pow
    

    【讨论】:

    • 如果不将输入转换为 MPZ,如何处理大于 2^63-1 的整数大小?你能举个关于 gmpy.powmod 的简单例子吗?
    • python 整数没有固定大小。它们可以任意大。
    猜你喜欢
    • 2019-10-23
    • 2021-10-19
    • 2015-12-07
    • 2022-12-31
    • 2012-05-23
    • 1970-01-01
    • 2018-11-18
    • 2010-12-11
    相关资源
    最近更新 更多