Note that I know there have been some other questions, but no real answer, on SO, regarding this issue.
So, what has been happening since the increment field value was implemented, is that when incrementing floating numbers, most of the time you'll get a dozen decimals instead of the actual number.
// incrementing 0, with 0.1, 11 times, returns 1.0999999999999999
Math.round( 1.0999999999999999 * 100 + Number.EPSILON ) / 100
This returns the correct number ... so I wonder, can't this be implemented inside the method that deals with incrementing the actual value inside Firestore ?
Problem is, when I want to show numbers locale-based, I use the following:
number.toLocaleString( undefined, { minimumFractionDigits: 2 })
That would show 1.09 which is wrong, and customers get confused about their earnings.
What's to be done aside manipulating the data after receiving it client side?
Another side effect of this is that when using incrementing a big negative value, sometimes, for some reason, you get that +e inside your value in Firestore, and when fetching it server-side ( at least with the PHP Admin SDK ), the number ends up as a string, and not as an integer.
According to the documentation, Cloud Firestore stores floating point numbers in IEEE 754 format. Please take some time to understand what this format implies. Basically, you can't count on floating point number to retain exactly the accuracy that you've specified, as the format can't possibly do that for some numbers. You can expect some small variation when the number is stored. A good summary of this type of behavior can already be found here on Stack Overflow:
If you must retain numerical accuracy, look into using a library that will help load and store numbers that have the accuracy you need. Pretty much all financial application will do something like this, as IEEE 754 can effectively lose data in order to compress the data down to a small size.
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