In Firebase real time database i have a path like this ../funds/balance with a value of 10.
I have a function doing a transaction which decrease the balance by 2 cents.
The first time i remove 2 cents everything works and balance is saved has 9.98.
I do it one more time everything console log show i read 9.98 from the db and after data is updated firebase console show 9.96.
Next time i do it remember that Firebase console shows 9.96 but when i console log the value received in the transaction is currently 9.96000001.
Someone nows why.
This is a well-known property of floating-point representations.
The issue arises because, in this case, because 0.02 cannot be represented exactly as a floating-point number. It can be represented exactly in decimal (2x10^-1), but in binary it has a recurring "1001" (1.1001100110011001... x2^-3).
What you are seeing is analogous to representing 1/3 in decimal as 0.333. You expect that subtracting 1/3 from one 3 times would leave 0, but subtracting 0.333 from one 3 times leaves 0.001.
The solution is not to represent money as floating-point. In SQL you'd use a MONEY, NUMERIC or DECIMAL type or, more generally, you can represent money as an integer number of pennies (or hundreths of a penny, etc., according to your needs).
There's an article called "What Every Computer Scientist Should Know About Floating-Point Arithmetic" that you can find online that explains the issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With