Python:operator mul返回'inf'

时间:2017-10-04 16:05:23

标签: python

我有清单:

[75.82, 48.88, 56.05, 37.4, 24.88, 71.37, 50.69, 68.12, 99.32, 72.55, 52.62, 40.91, 34.4, 29.75, 96.46, 71.0, 51.7, 40.35, 33.72, 29.39, 29.19, 77.67, 56.1, 43.1, 34.3, 28.49, 103.35, 73.63, 53.04, 40.9, 34.23, 29.53, 114.6, 88.33, 73.62, 60.88, 51.19, 44.62, 39.3, 35.79, 31.87, 29.03, 101.63, 80.56, 68.28, 96.44, 74.88, 62.23, 136.52, 106.22, 88.27, 76.43, 66.62, 58.61, 51.2, 46.32, 41.79, 38.26, 34.85, 31.74, 29.7, 276.63, 195.5, 137.44, 106.73, 88.14, 74.11, 65.49, 57.94, 51.67, 47.24, 43.17, 39.3, 36.46, 33.74, 31.63, 29.75, 27.79, 26.37, 25.19, 23.95, 22.56, 21.5, 20.65, 19.85, 19.08, 18.24, 17.62, 17.06, 16.43, 15.79, 15.35, 14.88, 107.18, 78.63, 57.28, 44.48, 37.79, 32.85, 28.77, 119.63, 93.31, 79.56, 66.49, 56.76, 50.05, 43.82, 39.01, 35.64, 32.36, 29.16, 300.19, 224.14, 158.77, 121.52, 99.91, 82.87, 73.49, 64.39, 58.21, 52.77, 48.09, 44.48, 41.04, 38.0, 35.41, 33.22, 31.43, 29.67, 28.1, 26.77, 25.3, 24.33, 23.27, 22.44, 21.4, 20.65, 19.85, 19.18, 18.52, 17.9, 17.31, 16.75, 16.3, 15.75, 15.33, 14.88, 68.12, 57.01, 49.22, 41.83, 35.49, 31.46, 27.87, 36.13, 26.13, 63.63, 43.11, 27.93, 90.64, 66.72, 50.51, 39.79, 33.12, 28.72, 116.34, 71.64, 49.21, 37.78, 31.48, 26.96, 120.3, 75.12, 51.0, 39.22, 32.34, 27.71, 149.1, 117.34, 87.34, 66.79, 56.37, 48.21, 42.07, 37.64, 34.5, 31.68, 29.52, 146.57, 119.44, 93.46, 71.57, 58.84, 162.76, 122.14, 106.72, 89.18, 76.95, 66.7, 58.64, 53.43, 48.27, 43.97, 40.78, 38.16, 35.35, 32.82, 30.84, 28.99]

我尝试通过operator.mul得到共同的价值:

reduce(operator.mul, list)

我也尝试使用lambda:

reduce(lambda x, y: x * y, list)

当我打印它时 - 我得到'inf' - 这是什么?发生什么了?

3 个答案:

答案 0 :(得分:3)

您的乘法结果不能以这种方式执行,因为它会溢出numpy.float128。尝试对decimal>>> from decimal import Decimal >>> a = [75.82, 48.88, 56.05, 37.4, 24.88, 71.37, 50.69, 68.12, 99.32, 72.55, 52.62, 40.91, 34.4, 29.75, 96.46, 71.0, 51.7, 40.35, 33.72, 29.39, 29.19, 77.67, 56.1, 43.1, 34.3, 28.49, 103.35, 73.63, 53.04, 40.9, 34.23, 29.53, 114.6, 88.33, 73.62, 60.88, 51.19, 44.62, 39.3, 35.79, 31.87, 29.03, 101.63, 80.56, 68.28, 96.44, 74.88, 62.23, 136.52, 106.22, 88.27, 76.43, 66.62, 58.61, 51.2, 46.32, 41.79, 38.26, 34.85, 31.74, 29.7, 276.63, 195.5, 137.44, 106.73, 88.14, 74.11, 65.49, 57.94, 51.67, 47.24, 43.17, 39.3, 36.46, 33.74, 31.63, 29.75, 27.79, 26.37, 25.19, 23.95, 22.56, 21.5, 20.65, 19.85, 19.08, 18.24, 17.62, 17.06, 16.43, 15.79, 15.35, 14.88, 107.18, 78.63, 57.28, 44.48, 37.79, 32.85, 28.77, 119.63, 93.31, 79.56, 66.49, 56.76, 50.05, 43.82, 39.01, 35.64, 32.36, 29.16, 300.19, 224.14, 158.77, 121.52, 99.91, 82.87, 73.49, 64.39, 58.21, 52.77, 48.09, 44.48, 41.04, 38.0, 35.41, 33.22, 31.43, 29.67, 28.1, 26.77, 25.3, 24.33, 23.27, 22.44, 21.4, 20.65, 19.85, 19.18, 18.52, 17.9, 17.31, 16.75, 16.3, 15.75, 15.33, 14.88, 68.12, 57.01, 49.22, 41.83, 35.49, 31.46, 27.87, 36.13, 26.13, 63.63, 43.11, 27.93, 90.64, 66.72, 50.51, 39.79, 33.12, 28.72, 116.34, 71.64, 49.21, 37.78, 31.48, 26.96, 120.3, 75.12, 51.0, 39.22, 32.34, 27.71, 149.1, 117.34, 87.34, 66.79, 56.37, 48.21, 42.07, 37.64, 34.5, 31.68, 29.52, 146.57, 119.44, 93.46, 71.57, 58.84, 162.76, 122.14, 106.72, 89.18, 76.95, 66.7, 58.64, 53.43, 48.27, 43.97, 40.78, 38.16, 35.35, 32.82, 30.84, 28.99] >>> reduce(operator.mul, [Decimal(i) for i in a]) Decimal('3.460278987987417665359929071E+348')

执行相同的操作
sys.float_info.max

使用import sys sys.float_info.max 检查最大浮点值(取决于实现):

float('inf')

如果乘法结果溢出此限制,则Python将其表示为A·B = x^(log_x A + log_x B)

答案 1 :(得分:2)

正如评论所指出的,问题是结果数字太大了。为了给你一个提示,你可以使用等价> import operator, math, sys > l = [...] > reduce(operator.add, map(math.log10, l)) 348.53911111557284

> sys.float_info.max
1.7976931348623157e+308

这是一个包含348位的十进制数字。

让我们看看您的实现支持的最大数字是什么:

float('Infinity')

10 348 > 10 308 。这比支持的最大数字要大,因此Python使用{{1}}代替。

答案 2 :(得分:1)

您的列表只包含float numbers,因此自然地,乘法运算是使用浮点运算完成的。 Python使用IEEE-754 double-precision floating point numbers作为浮点数的底层结构。这意味着该数字受限于该数据类型的限制,这意味着它可以表示最大数量。

您可以使用sys.float_info

查看最大数量
>>> sys.float_info
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)

>>> sys.float_info.max
1.7976931348623157e+308

所以1.7976931348623157e+308是Python中浮点数最大的数字。在此之上,您将达到inf,这是无穷大的特殊常量。

不幸的是,列表中项目相乘的结果大约是3.46027898e+348,大约增加了40个数量级。因此,您无法使用float表示该值。

但是,您可以使用decimal library来表示使用无限精度小数的数字。这将使您获得结果:

>>> from decimal import Decimal
>>> reduce(lambda a, b: a * Decimal(b), lst, Decimal(1))
Decimal('3.460278987987417665359929071E+348')