Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.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是如何实现内置函数pow()的?_Python_Algorithm_Math - Fatal编程技术网

Python是如何实现内置函数pow()的?

Python是如何实现内置函数pow()的?,python,algorithm,math,Python,Algorithm,Math,我必须编写一个程序来计算a**b%c,其中b和c都是非常大的数字。如果我只使用a**b%c,速度非常慢。然后我发现内置函数pow()可以通过调用pow(a,b,c) 我很想知道Python是如何实现这一点的?或者在哪里可以找到实现此函数的源代码文件?Python在一般情况下使用C数学库,在某些概念(如无穷大)中使用它自己的逻辑。的第1426行显示了实现math.pow的Python代码,但基本上,它可以归结为调用标准C库,该库可能具有该函数的高度优化版本 Python在进行密集的数字运算时可能会

我必须编写一个程序来计算
a**b%c
,其中
b
c
都是非常大的数字。如果我只使用
a**b%c
,速度非常慢。然后我发现内置函数
pow()
可以通过调用
pow(a,b,c)


我很想知道Python是如何实现这一点的?或者在哪里可以找到实现此函数的源代码文件?

Python在一般情况下使用C数学库,在某些概念(如无穷大)中使用它自己的逻辑。

的第1426行显示了实现math.pow的Python代码,但基本上,它可以归结为调用标准C库,该库可能具有该函数的高度优化版本


Python在进行密集的数字运算时可能会非常慢,但可以给您带来相当快的速度提升,尽管它不如调用标准库的C代码好。

我不了解Python,但如果您需要快速幂,可以通过平方使用幂运算:


这是一种简单的递归方法,使用了指数的可交换性。

如果
a
b
c
是整数,则在每个步骤(包括第一步)中,通过减少模
c
可以提高实现效率(即,在开始之前减少
a
c
)。这就是真正的功能。该函数有200多行代码,因为它必须处理引用计数,并处理负指数和一系列特殊情况

但是,该算法的核心思想相当简单。假设我们要计算正整数
a
b
,并且
b
具有二进制数字
b_i
。然后我们可以将
b
写成

b = b_0 + b1 * 2 + b2 * 2**2 + ... + b_k ** 2**k
a ** b = a**b0 * (a**2)**b1 * (a**2**2)**b2 * ... * (a**2**k)**b_k
ans
a**b
as

b = b_0 + b1 * 2 + b2 * 2**2 + ... + b_k ** 2**k
a ** b = a**b0 * (a**2)**b1 * (a**2**2)**b2 * ... * (a**2**k)**b_k
本产品中的每个因素的形式为<代码>(a**2**i)**b_i。如果
b_i
为零,我们可以简单地忽略因子。如果
b_i
为1,因子等于
a**2**i
,可以通过反复平方
a
来计算所有
i
的幂。总的来说,我们需要平方和乘
k
次,其中
k
是二进制di>的数目吉特的
b


以上,对于<代码> PoW(a,b,c)我们可以在每一步中减少模<代码> c>代码>平方和乘法之后。

您可以考虑以下两种实现来计算<代码>(x**y)%Z快速。< /P> Python中的

def pow_mod(x, y, z):
    "Calculate (x ** y) % z efficiently."
    number = 1
    while y:
        if y & 1:
            number = number * x % z
        y >>= 1
        x = x * x % z
    return number
#include <stdio.h>

unsigned long pow_mod(unsigned short x, unsigned long y, unsigned short z)
{
    unsigned long number = 1;
    while (y)
    {
        if (y & 1)
            number = number * x % z;
        y >>= 1;
        x = (unsigned long)x * x % z;
    }
    return number;
}

int main()
{
    printf("%d\n", pow_mod(63437, 3935969939, 20628));
    return 0;
}
在C语言中:

def pow_mod(x, y, z):
    "Calculate (x ** y) % z efficiently."
    number = 1
    while y:
        if y & 1:
            number = number * x % z
        y >>= 1
        x = x * x % z
    return number
#include <stdio.h>

unsigned long pow_mod(unsigned short x, unsigned long y, unsigned short z)
{
    unsigned long number = 1;
    while (y)
    {
        if (y & 1)
            number = number * x % z;
        y >>= 1;
        x = (unsigned long)x * x % z;
    }
    return number;
}

int main()
{
    printf("%d\n", pow_mod(63437, 3935969939, 20628));
    return 0;
}
#包括
无符号长功率模块(无符号短x、无符号长y、无符号短z)
{
无符号长数=1;
while(y)
{
如果(y&1)
编号=编号*x%z;
y>>=1;
x=(无符号长)x*x%z;
}
返回号码;
}
int main()
{
printf(“%d\n”,pow_mod(634373393596993920628));
返回0;
}
在Python中实现pow(x,n)

def myPow(x, n):
        p = 1
        if n<0:
            x = 1/x
            n = abs(n)

        # Exponentiation by Squaring

        while n:
            if n%2:
                p*= x
            x*=x
            n//=2
        return p
def myPow(x,n,m):
            p = 1
            if n<0:
                x = 1/x
                n = abs(n)
            while n:
                if n%2:
                    p*= x%m
                x*=x%m
                n//=2
            return p
def myPow(x,n):
p=1

如果cpython源repo位于Objects/longobject.c:long_pow()(正如JimB已经评论的那样)。
math.pow()
没有模参数,并且与内置的
pow()不是同一个函数
。另外,仅供参考,Psyco变得非常陈旧,并且没有64位支持。NumPy对于严肃的数学非常有用。@Noctis,我尝试运行您的Python实现,得到了以下结果:TypeError:ufunc“bitwise”和“not supported for the input type,并且根据强制转换规则“safe”,无法安全地将输入强制为任何受支持的类型------如下我现在正在学习Python,我想您可能知道这个错误(搜索表明它可能是一个bug,但我认为有一个快速的解决方法)@stackuser:在下面的演示中,它似乎工作得很好:有人能解释为什么这个解决方案有效吗?我很难理解这个算法背后的逻辑。@NoctisSkytower,考虑到本机python
pow()
内置函数也支持这一点,而且似乎更快?
>>st_pow='pow(65537L,767587L,14971787L)>>>st_pow mod='pow mod(65537L,767587L,14971787L)>>timeit.timeit(st_pow)4.510787010192871>>timeit.timeit(st_pow mod,def_pow mod)10.135776996612549
@Fabiano我的函数不应该被使用。它只是解释Python如何在场景后面工作,而没有参考C语言的源代码。我试图回答wong2关于
pow
是如何实现的问题。为什么我们可以在每个步骤中使用模C来减少?@BenSandler:因为≡ a'(模块c)和b≡ b’(模c)表示ab≡ a'b'(mod c),或者换句话说,先将a和b模c减然后乘,还是先将它们乘然后再减模c都无关紧要。请参见。请注意,
long\u pow
现在在该文件的另一行定义:@JohanC我已经更新了包含提交哈希的链接,因此它不再过时。