python 中大数的求和产生最大参数

Summation of large numbers in python yields the maximal parameter

在我的程序中,我使用 numpy 获取数字的指数,然后使用 sum 函数对它们求和。 我注意到总结这些大数字,有或没有 numpy,导致返回最大的参数,不变。

exp_joint_probabilities=[  1.57171938e+81,   1.60451506e+56,   1.00000000e+00]
exp_joint_probabilities.sum()
=> 1.571719381352921e+81

与 python 相同:

(1.57171938e+81+1.60451506e+56+1.00000000e+00)==1.57171938e+81
=>True

这是近似的问题吗?我应该使用更大的数据类型来表示数字吗? 我如何才能获得更准确的此类计算结果?

这似乎是近似问题:

>>> 1.57171938e+81 + 1.60451506e+65 > 1.57171938e+81
<<< True

>>> 1.57171938e+81 + 1.60451506e+64 > 1.57171938e+81
<<< False

您可以通过转换为 int 来解决这个问题:

>>> int(1.57171938e+81) + int(1.60451506e+64) > int(1.57171938e+81)
<<< True

1.57171938e+81 是一个 81 位的数字,您只需输入前 9 位。1.60451506e+56 是一个小得多的数字,只有 56 位。

你期待什么样的答案?第一个完全使第二个相形见war。如果您想要与原始数字具有相似精度的东西(这就是您使用浮点数得到的结果),那么答案就是正确的。

你可以使用整数:

>>> a = int(1.57171938e+81)
>>> b = int(1.60451506e+56)
>>> a
571719379999999945626903548020224083024251666384876684446269499489505292916359168L
>>> b
160451506000000001855754747064077065047170486040598151168L
>>> a+b
1571719379999999945626903708471730083024253522139623748523334546659991333514510336L

但这有多大用处取决于您。

你可以使用 the decimal standard library:

from decimal import Decimal

a = Decimal(1.57171938e+81)
b = Decimal(1.60451506e+56)
d = a + b
print(d)
print(d > a and d > b)

输出:

1.571719379999999945626903708E+81
True

之后您可以将其转换回浮点数,但这会导致与之前相同的问题。

f = float(d)
print(f)
print(f > a and f > b)

输出:

1.57171938e+81
False

请注意,如果您将 Decimal 存储在 numpy 数组中,您将失去快速矢量化操作,如 numpy does not recognize Decimal objects。虽然它确实有效:

import numpy as np

a = np.array([1.57171938e+81, 1.60451506e+56, 1.00000000e+00])
d = np.vectorize(Decimal)(a)  # convert values to Decimal
print(d.sum())
print(d.sum() > d[0]

输出:

1.571719379999999945626903708E+81
True