Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么expmod的这两种实现在大值方面有所不同?_Python_Algorithm - Fatal编程技术网

Python 为什么expmod的这两种实现在大值方面有所不同?

Python 为什么expmod的这两种实现在大值方面有所不同?,python,algorithm,Python,Algorithm,我已经编写了两个函数,即,(x**y)%n。这两个都是标准函数,我已经检查并重新检查了这两个函数,但没有发现任何愚蠢的错误 这里是递归的一个: def expmod(x,y,m): if y == 0: return 1 if y % 2 == 0: return square(expmod(x,y/2,m)) % m # def square(x): return x*x else: return (x * expmod(x,y-1,m)

我已经编写了两个函数,即,
(x**y)%n
。这两个都是标准函数,我已经检查并重新检查了这两个函数,但没有发现任何愚蠢的错误

这里是递归的一个:

def expmod(x,y,m):
    if y == 0: return 1
    if y % 2 == 0:
        return square(expmod(x,y/2,m)) % m # def square(x): return x*x
    else:
        return (x * expmod(x,y-1,m)) % m
def non_recursive_expmod(x,y,m):
    x = x % m
    y = y % m
    result = 1
    while y > 0:
        if(y%2 == 1):
            result = (result * x) % m
        x = (x*x) % m
        y = y/2
    return result
…这里是非递归的一个:

def expmod(x,y,m):
    if y == 0: return 1
    if y % 2 == 0:
        return square(expmod(x,y/2,m)) % m # def square(x): return x*x
    else:
        return (x * expmod(x,y-1,m)) % m
def non_recursive_expmod(x,y,m):
    x = x % m
    y = y % m
    result = 1
    while y > 0:
        if(y%2 == 1):
            result = (result * x) % m
        x = (x*x) % m
        y = y/2
    return result
他们同意小价值:

>>> expmod(123,456,789) - non_recursive_expmod(123,456,789)
0
…但对于较大的,不要:

>>> expmod(24354321,5735275,654) - non_recursive_expmod(24354321,5735275,654)
-396L

发生了什么事?

您的函数
非递归expmod
中有一些可疑步骤:在开始时删除
%m
中的
x
y
。两者都不是必需的

另外,通过使用
y=y//2
,确保
y
的除法是整数除法

总的来说,函数应该如下所示:

def non_recursive_expmod(x, y, m):
    result = 1
    while y > 0:
        if y % 2 == 1:
            result = (result * x) % m
        x = (x * x) % m
        y = y // 2
    return result

如果y为奇数,则非递归不会减少y,如果y==1,则偶数部分需要使用else

python中有pow()函数。第三个参数可以是mod.
TypeError:pow需要2个参数,得到3个
@TomMedley:you可能从math(从math import*)导入了一个star,它将内置的3参数pow替换为数学库的pow,它只有2个参数。这很公平。但它仍然不能回答这个问题。做出这些改变会完全破坏它!这个算法是正确的,如果你用较小的值来处理它,很明显它做的是正确的。这就解决了它,谢谢!把它加到你的答案里,这样我就可以接受了。@Tom Medley你可以把
x=x%m
留在那里,但是
y
一个肯定会打破它。@Michael J.Barber你说得对。在我的回答中改变了。我不知道你想说什么。