对于我的长长的自然数列表,为什么numpy.prod()错误地返回负结果或0?

sigwle7e  于 2022-11-10  发布在  其他
关注(0)|答案(3)|浏览(155)

我只是在做Project Euler problem 12,所以我需要对超过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
vngu2lb8

vngu2lb81#

注意Python uses "unlimited" integers,但在NumPy中,所有内容都是类型的,所以这里是一个“C”样式(可能是64位)的整数。您可能正在经历溢出。
如果您查看numpy.prod的文档,您可以看到dtype参数:
返回的数组的类型,以及元素相乘的累加器的类型。
您可以做以下几件事:
1.回到Python,使用它的“无限整数”进行乘法(具体操作请参见this question)。
1.想一想,你是否真的需要找到这么大数字的乘积。通常,当你处理非常小或非常大的数字的乘积时,你会切换到对数和。正如@WarrenWeckesser指出的那样,这显然是不精确的(这并不是说取末尾的指数就能给出准确的解决方案)--相反,它是用来衡量一种产品是否比另一种产品增长得更快。

nkkqxpd9

nkkqxpd92#

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

>>> np.prod(array[:25])
7034535277573963776
>>> np.prod(array[:26])
-1569523520172457984
>>> type(_)
numpy.int64

您实际上在这里溢出了NumPy的数据类型,因此产生了古怪的结果。如果坚持使用pythonint,就不会出现溢出。

>>> import operator
>>> reduce(operator.mul, array, 1)
933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000L
chhkpiq4

chhkpiq43#

你得到的结果是,由于乘积中有大量的因子2,这些因子超过450个。因此,在模2^64的约化中,结果是零。
在其他答案中解释了为什么数据类型会强制这种减少。

250+125+62+31+15+7+3+1 = 494 is the multiplicity of 2 in 500!
  • 增加了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!

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

相关问题