2015-09-29 3 views
0

У меня проблема, потому что Mongodb, похоже, не сохраняет точность при добавлении поплавков. Например, следующий должен дать 2.0:Mongodb недостаток точности приращения поплавков

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 

Как я могу обойти эту проблему?

+0

Возможно, установив точность кода клиента. Позже это часть, которая обеспечивает ценность в первую очередь. Так что понимайте, что ** вы ** вызываете проблему, а не интерфейс. Проблема с интерфейсом «клавиатура-стул». –

ответ

3

К сожалению, вы не можете - по крайней мере, не напрямую. Mongo хранит числа с плавающей точкой как плавающие по IEEE с двойной точностью (https://en.wikipedia.org/wiki/IEEE_floating_point), и эти ошибки округления присущи этому формату.

Я замечаю, что вы используете Decicals в своем коде - они преобразуются в поплавки Python (которые удваиваются) перед отправкой в ​​БД. Если вы хотите сохранить свою истинную десятичную точность, вам нужно будет хранить свои номера в виде строковых десятичных разрядов, а это значит, что вам также придется отказаться от средств обработки номеров Mongo, таких как $inc.

Это, к сожалению, компромисс, с которым вам придется столкнуться в большинстве баз данных и языков программирования: номера с плавающей запятой IEEE - это процессоры формата, на которых есть дело, и любые попытки отклониться от них (использовать произвольно- прецизионные десятичные знаки, такие как decimal.Decimal) имеют высокую производительность и юзабилити.

+0

Одновременно полезно и удручает, спасибо. – MFB