Потеря точности транзакции Firebase - PullRequest
0 голосов
/ 12 октября 2018

В базе данных реального времени Firebase у меня есть такой путь ../funds/balance со значением 10.

У меня есть функция, выполняющая транзакцию, которая уменьшает баланс на 2 цента.

В первый раз, когда я удаляю 2 цента, все работает и баланс сохраняется 9,98.

Я делаю это еще раз, когда все показы в консольном журнале я читал из базы данных 9,98, а после обновления данных в консоли Firebase показывал 9,96.

В следующий раз я запомню, что консоль Firebase показывает 9,96, но когда я записываю в журнал консоль, значение, полученное в транзакции, в настоящее время равно 9,96000001.

Кто-то теперь почему.

1 Ответ

0 голосов
/ 12 октября 2018

Это хорошо известное свойство представлений с плавающей запятой.

Проблема возникает потому, что в этом случае 0,02 нельзя представить точно в виде числа с плавающей запятой.Он может быть представлен точно в десятичном (2x10 ^ -1), но в двоичном он имеет повторяющееся "1001" (1.1001100110011001 ... x2 ^ -3).

То, что вы видите, аналогично представлению 1/3 в десятичном виде как 0,333.Вы ожидаете, что вычитание 1/3 из одного 3 раза оставит 0, а вычитание 0,333 из одного 3 раза даст 0,001.

Решение не состоит в том, чтобы представлять деньги как плавающую точку.В SQL вы будете использовать тип MONEY, NUMERIC или DECIMAL или, в более общем смысле, вы можете представлять деньги как целое число копеек (или сотен копеек и т. Д., В зависимости от ваших потребностей).

Есть статья под названием "Что каждый ученый-компьютерщик должен знать об арифметике с плавающей точкой" , которую вы можете найти в Интернете, которая объясняет проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...