Python 为什么numpy.prod()错误地为我的一长串自然数返回负结果或0?

Python 为什么numpy.prod()错误地为我的一长串自然数返回负结果或0?,python,list,numpy,math,Python,List,Numpy,Math,我只是在做Euler项目,所以我需要对500多个唯一因子的倍数进行一些测试 我认为数组[1,2,3…500]将是一个很好的起点,因为该数组的乘积是可能的最小值。但是,numpy.prod()对此数组返回零。我肯定我错过了一些明显的东西,但到底是什么 >>> import numpy as np >>> array = [] >>> for i in range(1,100): ... array.append(i) ... >&g

我只是在做Euler项目,所以我需要对500多个唯一因子的倍数进行一些测试


我认为数组[1,2,3…500]将是一个很好的起点,因为该数组的乘积是可能的最小值。但是,numpy.prod()对此数组返回零。我肯定我错过了一些明显的东西,但到底是什么

>>> import numpy as np
>>> array = []
>>> for i in range(1,100):
...   array.append(i)
... 
>>> np.prod(array)
0
>>> array.append(501)
>>> np.prod(array)
0
>>> array.append(5320934)
>>> np.prod(array)
0

这些数字变得非常大,很快

>>> np.prod(array[:25])
7034535277573963776
>>> np.prod(array[:26])
-1569523520172457984
>>> type(_)
numpy.int64
实际上,您在这里溢出了numpy的数据类型,因此产生了古怪的结果。如果您坚持使用python int,就不会有溢出

>>> import operator
>>> reduce(operator.mul, array, 1)
933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000L
请注意,但在numpy中,所有内容都是类型化的,因此这里它是一个“C”样式(可能是64位)的整数。您可能正在经历溢出

如果您查看的文档,可以看到
dtype
参数:

返回数组的类型,以及元素相乘的累加器的类型

您可以做以下几件事:

  • 回到Python,使用它的“无限整数”进行乘法(请参阅了解如何实现)

  • 考虑一下你是否真的需要找到如此巨大的数字的乘积。通常,当处理非常小或非常大的数的乘积时,会切换到对数和。正如@WarrenWeckesser所指出的,这显然是不精确的(并不是说在最后取指数就能得到精确的答案),而是用来衡量一种产品是否比另一种增长更快


  • 由于产品中有大量的因子2,结果为0,其中有450多个因子。因此,在约化模
    2^64
    中,结果为零

    其他答案解释了为什么数据类型会强制进行这种缩减



    新增12/2020:或者,仔细阅读问题及其代码

    49+24+12+6+3+1 = 95 as the multiplicity of 2 in 99!
    
    这是您列表第一部分的产品。数字末尾还有足够的二进制零来填充64位整数的所有位位置。只是比较一下,你会发现

    19+3 = 22 factors of 5 in 99!
    

    这也是这个阶乘的十进制表达式中尾随的零的数目。

    Uhoh。。。numpy溢出…我似乎记得Python int是可变位数,或者至少大于64位整数。因此,也许可以尝试使用Python int数据类型的普通Python列表(速度较慢,占用更多内存,但应该可以解决您的问题)。相关问题-为什么
    np.array(array,dtype=np.object.).prod()
    在这里也不起作用?“因为该数组的乘积是可能的最小值”,您可能需要重新考虑这个问题。实际的解远小于
    factorial(500)
    。使用8个不同素数的乘积,您将得到512个不同的因子。使用
    float
    s将失去精度。@WarrenWeckesser感谢您的正确提示,我已根据您的观点更新了答案。我还认为这是一个XY问题,因为问题是为什么需要这么大的产品,所以尝试添加一些替代品。我应该更加强调:不要使用
    float
    s解决这个问题!任何正确的解决方案都可能依赖于对整数执行精确的算术运算。使用(足够大)
    float
    s,您将无法获得精确的算术结果。@WarrenWeckesser好的,谢谢,我放弃了原来的第一个选项。使用对数也会引入浮点不精确性。(对不起,我太讨厌了!)
    19+3 = 22 factors of 5 in 99!