2 ms·
Currency + JavaScript Number type = bad idea The Number type in JavaScript is a IEEE754 floating point number. Someone explained why floating point numbers are
by partycoder 8y ago
Currency + JavaScript Number type = bad idea
The Number type in JavaScript is a IEEE754 floating point number. Someone explained why floating point numbers are not good to represent currency:
https://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency/ https://stackoverflow.com/questions/3730019/why-not-use-doub...
In fact, even a simple operation like equality in floating point numbers becomes harder. e.g:
Math.abs(x - y) < Number.EPSILON
I would be very careful about this since it becomes problematic for large numbers.
- alkonaut 8y agoA 64 bit floating point number can still represent exactly all integers smaller than 2^53 so it’s possible to use that for constructing proper rationals or doing proper exact comparisons and currency calculations within certain bounds e.g by using 1/100000 dollars as the unit you can fit any amount under 2^48. It’s terrible to not even have proper integers but that doesn’t make the problem go away. People still have to do financial calculations in JS.
- partycoder 8y agoIt's not being validated. Validation and tests involving large numbers need to be added.
- alkonaut 8y agoI didn’t look at the details of this specific library (which I expect is even more complex than just using the exact integers of ieee754). But yes - in order to properly use the exact integers, the number would have to be encapsulated in an object and validated (range, dropping decimals, returning optional values for things that might fail etc). You can not just take two “Number” and use for proper decimal math without enforcing some invariants.
- tzahola 8y ago>People still have to do financial calculations in JS. No, they don't.
- deleted 8y ago[deleted]
- jen729w 8y agoaccounting.js [0] handles this by multiplying the number out by a few thousand before doing the maths, ensuring rounding works as expected. Source: Gordon Zhu’s excellent introduction to JS course, Watch and Code [1]. I haven’t used accounting.js myself. 0: http://openexchangerates.github.io/accounting.js/ http://openexchangerates.github.io/accounting.js/ 1: http://watchandcode.com http://watchandcode.com
- partycoder 8y agoThat is not enough. Converting an amount to cents, e.g: $1.99 becomes 199 cents, will help you only briefly. As numbers become larger or you have successive divisions, numbers will start to suffer from issues such as absorption. Then you may also suffer from issues when comparing numbers, since floating point equality is different. e.g: > 1e16 -1 10000000000000000 Note that this code should output 9999999999999999. But it doesn't because of absorption. In this case, "multiplying by a few thousands" makes this situation more likely.