python - 了解数值稳定性大计算损失

标签 python

我正在学习一些关于机器学习的类(class),我试图理解这个计算问题:

variable = 1000000000 #1 billion
for i in xrange(1000000):
       variable = variable+ 1e-6 #0.000001

variable = variable -1000000000 #1 subtracts with 1 billion again
variable
#>> 0.95367431640625

应该是 1 但结果是 0.95367431640625

谁能告诉我为什么会这样?

最佳答案

你正在失去精度。这是因为 Python 中的 float 实现了 double floating point 精度,它只能保证精度达到 15/16 位。

当你这样做时:

1,000,000,000 + 0.000001
1,000,000,000.000001 + 0.000001
# and so on, note that you are adding the 16-th digit
# but 1,000,000,000.000001 is not actually exactly 1,000,000,000.000001
# behind is something like 1,000,000,000.000001014819 or 1,000,000,000.000000999819

不断地,你打破了精度限制,在 0.000001 中的最后一个 1 之后还有一些其他值,它仅表示为 0.000001。因此你得到了累积误差。

如果您将 variable 初始化为 0,情况就会有所不同。这是因为在计算中:

0.000000 + 0.000001
0.000001 + 0.000001
0.000002 + 0.000001
#and so on

虽然0.000001的实际值不完全是0.000001,但是第16位的不精度与有效数相去甚远:

0.000000 + 0.00000100000000000000011111
0.000001 + 0.00000100000000000000011111 #insignificant error

您还可以通过使用 decimal 值而不是 double 来避免错误:

from decimal import *
variable = Decimal(1000000000)
addition = Decimal(1e-6)
for i in xrange(1000000):
   variable = variable+ addition #0.000001

variable = variable-Decimal(1000000000) #1 subtracts with 1 billion again
variable

关于python - 了解数值稳定性大计算损失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35919315/

相关文章:

python - Mpmath.meijerg : Order of arguments

python - 自引用表 [SQLAlchemy/Alembic] 中的外键不明确

python - 检查数据框是否具有完整数据网格的有效方法

python : range between dates when range field has time

python - 使用元素列表查询 dynamoDB

python - 在 Windows 下使用 NumPy 数组对图像进行快速傅里叶变换期间的内存错误

python - Pandas - 按字符串重新排序列包含概念并在它们之间进行比较

python - 用不等长度的列表填充 Pandas 列

python - 将一个 SQLAlchemy 模型定义为与多个其他模型之一相关联

python多线程加入超时