Mongodb 缺少精确递增的浮点数

Mongodb lack of precision incrementing floats

我有一个问题,因为 Mongodb 在递增浮点数时似乎无法保持精度。例如,以下应产生 2.0:

from decimal import Decimal  # for python precision
for i in range(40):
    db.test.update({}, {'$inc': {'count': float(Decimal(1) / 20)}}, upsert=True)
print db.test.find_one()['count']
2.000000000000001

我该如何解决这个问题?

不幸的是,你不能——至少不能直接。 Mongo 将浮点数存储为双精度 IEEE 浮点数 (https://en.wikipedia.org/wiki/IEEE_floating_point),这些舍入误差是格式固有的。

我注意到您在代码中使用了小数——它们在发送到数据库之前被转换为 Python 浮点数(双精度值)。如果您想保持真正的小数精度,则必须将数字存储为字符串化小数,这意味着您还必须放弃 Mongo 的数字处理功能,例如 $inc .

遗憾的是,这是您在大多数数据库和编程语言中都会遇到的权衡:IEEE 浮点数是 CPU 本地处理的格式,任何偏离它们的尝试(使用任意-精度小数,如 decimal.Decimal) 会带来很大的性能和可用性损失。