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

时间:2017-07-24 10:36:03

标签: python numpy math exponent

在我的程序中,我使用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

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

3 个答案:

答案 0 :(得分:2)

您可以使用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

答案 1 :(得分:1)

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

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

你可以使用ints:

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

但是这对你有多大帮助。

答案 2 :(得分:0)

近似似乎是一个问题:

>>> 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