How to Handle Monetary Values in JavaScript
11–20 of 115 posts
Re: How to Handle Monetary Values in JavaScript
#12I looked into using Dinero.js before but it was overkill for my use case of calculating cart totals in USD only. I went with Big.js because it was better suited for what I wanted: a small library for decimal arithmetic.
Can you illustrate a case where you can't use regular FP arithmetic and round to 2 decimal places at the end?
$ node
> 0.1 + 0.2 - 0.3
5.551115123125783e-17
Close enough for trivial cases but errors can accumulate.Ruby, Perl5, Python also fail this. Perl6 uses Rat numbers for things like this and doesn't have this problem.
Re: How to Handle Monetary Values in JavaScript
#13Re: How to Handle Monetary Values in JavaScript
#14I looked into using Dinero.js before but it was overkill for my use case of calculating cart totals in USD only. I went with Big.js because it was better suited for what I wanted: a small library for decimal arithmetic.
Can you illustrate a case where you can't use regular FP arithmetic and round to 2 decimal places at the end?
for (let n = 0; n < 1; n += .01) { console.log(`n: ${n}, half: ${(n / 2).toFixed(2)}`); }
Re: How to Handle Monetary Values in JavaScript
#15I looked into using Dinero.js before but it was overkill for my use case of calculating cart totals in USD only. I went with Big.js because it was better suited for what I wanted: a small library for decimal arithmetic.
With float64's maximum 'safe' integer at almost ten thousand trillion, I believe this should be enough to compute most commercial transactions securely as long as the amounts base denomination is up to date (eg cents or dollars or megadollars).
The quantization noise mentioned in this article is possible to round off when appropriate.
function round_tail_digits(c){
return Math.round(c*1e15)/1e15
}
function round_at_hundreds(c){
return Math.round(c*100)/100
}Re: How to Handle Monetary Values in JavaScript
#16Earlier quoted context omitted.
Can you illustrate a case where you can't use regular FP arithmetic and round to 2 decimal places at the end?
(1.005).toFixed(2) // Expected rounding to "1.01" "1.00"
2.875.toFixed(2) = "2.88" while 2.675.toFixed(2) = "2.67"
7205759403792794 + 1.1 = 7205759403792795
7205759403792794 + 1.9 = 7205759403792796
Re: How to Handle Monetary Values in JavaScript
#17Earlier quoted context omitted.
You can't model 1.0 correctly but it will be something like 1.000006667. If you add enough of these numbers you will be off.
Your details are off. 1.0 is precisely representable in double precision floating point with no error.
Re: How to Handle Monetary Values in JavaScript
#18Yet, there’s no consensus around how to programmatically handle monetary values.
I wonder if the average person would find this frightening.
Re: How to Handle Monetary Values in JavaScript
#19I really like the approach Perl 6 takes with FatRat[1]. You basically have an object which holds a numerator and denominator, so all arithmetic calculations do not loose precision. [1] https://docs.perl6.org/type/FatRat
Re: How to Handle Monetary Values in JavaScript
#20Earlier quoted context omitted.
Can you illustrate a case where you can't use regular FP arithmetic and round to 2 decimal places at the end?
Bring up a Javascript interpreter and try this: $ node > 0.1 + 0.2 - 0.3 5.551115123125783e-17 Close enough for trivial cases but errors can accumulate. Ruby, Perl5, Python also fail this. Perl6 uses Rat numbers for things like this and doesn't have this problem.