numpy.prod异常问题:正整数相乘出现负数或零的原因咨询
问题解答
核心原因:numpy整数类型的溢出特性
numpy默认使用有符号64位整数(int64)存储整数计算结果,而阶乘的增长速度极快,很快就会超出int64的取值范围([-9223372036854775808, 9223372036854775807]),触发整数溢出,导致结果出现异常符号或变为0。
1. 为什么np.prod(np.arange(1,34))>0为True,np.prod(np.arange(1,32))>0为False?
- 21!的结果(51090942171709440000)已超过int64的最大值,溢出后变为负数。
- 随着阶乘继续增大,每经过若干次溢出,结果的符号会翻转。32!到33!的溢出使得符号再次变化,到34!时溢出后的结果回到正数,因此
np.prod(np.arange(1,34))>0返回True;而31!溢出后是负数,所以np.prod(np.arange(1,32))>0返回False。
2. 为什么np.prod(np.arange(1,100))结果为0?
100!中包含大量的2和5的因子(100以内的偶数提供足够多的2,5的倍数提供5),两者相乘会产生大量的10(对应二进制中的末尾0)。当结果超出int64范围时,仅低64位会被保留,而100!的低64位全是0,因此存储的结果就是0。
验证与解决方法
若要避免溢出,可以指定使用更大精度的类型:
- 使用浮点数类型(会损失部分精度):
np.prod(np.arange(1, 100), dtype=np.float64) - 使用Python任意精度整数(无精度损失):
np.prod(np.arange(1, 100), dtype=np.object_)
内容的提问来源于stack exchange,提问作者Wisthon Aby Haro Moya
相关产品推荐
相关产品推荐

