【问题标题】:Modular Exponentiation Algorithm in PythonPython中的模幂算法
【发布时间】:2014-05-18 05:24:08
【问题描述】:

我创建了一个计算大模指数的函数。我知道这个函数是内置在 python 语言中的。对于大于 17 位的数字,我的函数不正确,我不知道为什么。非常感谢任何帮助。

from random import randint

def modpow(x,n,m):
  if n == 0:
    return 1
  elif n == 1:
    return x
  elif n%2 == 0:
    return modpow(x*(x%m),n/2,m)%m
  elif n%2 == 1:
    return (x *  modpow(x*(x%m),(n-1)/2,m)%m )%m

for i in range(5,32):
  x = ''
  n = ''
  m = ''
  for j in range(i):
    x += str(randint(0,9))
    n += str(randint(0,9))
    m += str(randint(0,9))
  x = int(x)
  n = int(n)
  m = int(m)
  if pow(x,n,m) != modpow(x,n,m):
    print(i,x,n,m)

样本输出:

17 38508450670424585 67111951647554134 59005802612594983
18 24027200512104766 205942669690724726 816654795945860553
...

我已经运行了几次,它总是在 i = 17 开始失败,我不太清楚为什么。

【问题讨论】:

  • 如果您使用的是 Python 3,/ 运算符会返回一个浮点值。您可能希望使用 // 来返回 Python 2 和 3 的整数结果。
  • 刚刚用from random import * 和m = int(m) 运行了代码,它似乎做得很好。编辑:Python 2.7
  • 我已经按照上面的建议进行了修改。我正在使用 Py3。
  • 用 // 替换 / 有效,谢谢 casevh!将 n/2 转换为双精度时,我一定失去了一些精度。
  • int 在 python 中是“无限”精度。 double 只有 64 位,所以是的,这可能是你的问题。

标签: python algorithm modular-arithmetic


【解决方案1】:

我的猜测是 Python 的 pow() 在后台运行 doubles。第一个失败的值(38508450670424585)的对数基数 2 约为 55,但 double 只有 53 位精度,因此大于 2^53 的整数不一定能精确表示。我的猜测是,如果您检查最后一个成功数字的以 2 为底的日志(即 x=16),它将小于 53。

【讨论】:

    猜你喜欢
    • 2018-01-15
    • 1970-01-01
    • 2014-08-21
    • 2017-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-03
    • 2020-05-14
    相关资源
    最近更新 更多