Live data from Hacker News

How to Handle Monetary Values in JavaScript

frontstuff.io

51–60 of 115 posts

Re: How to Handle Monetary Values in JavaScript

#52
post #24

> Floats: 0.1 + 0.2 // returns 0.30000000000000004 The question is how much of an issue is this really? How often is 4 parts in 10 quadrillion a meaningful error when dealing with money? Especially when most of the time JS is dealing with money it will be presentation.

I might suggest reading https://doc.lagout.org/science/0_Computer%20Science/3_Theory...

This is in general how floating point math works.

Re: How to Handle Monetary Values in JavaScript

#54
I wish you could add different currencies together:

    Dinero({amount: 5000, currency: 'USD'})
      .add(Dinero({ amount: 1000, currency: 'EUR'}))
...and then convert that sum to a concrete currency later.

This feature request inspired by http://blog.ploeh.dk/2017/10/16/money-monoid/

Re: How to Handle Monetary Values in JavaScript

#55

Earlier quoted context omitted.

Not all of them, e.g. 9007199254740993 can't be represented in a double precision format (what javascript uses) For single precision floats you start having issues representing integers as low as 16777217

Sure, you can’t represent Graham’s number either... I know you knew what I meant.

No not really. You have to define the bounds you were talking about.

People believing that a float type can represent all integers that the int type in their language can represent is not exactly uncommon.

Re: How to Handle Monetary Values in JavaScript

#56
post #20
post #12

Earlier quoted context omitted.

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.

You'd need to accumulate 10^14 such errors to be off by an entire penny, which doesn't seem relevant to a web shopping cart.

Addition and subtraction are usually fine as you point out. Multiplication and division can cause problems depending on the values and the number of times you do it. If you are doing more complicated financial calculations, you could get in trouble more quickly. If you are careful and know exactly what you are doing, then you can certainly get away with normal FP for many applications.

My experience has been, though, that many developers have a bit of a laissez-faire attitude towards these kinds of details (time is, of course, another area where precision is incredibly important in corner cases). Rather than expecting all future programmers to be as diligent as they need to be, it's probably easier to simply use tools that make it difficult to make mistakes. Every time I'm working on financial systems I build currency classes (usually I'm doing OOP). Usually people grumble and there will be people who ignore the currency classes. I've never had to wait long before someone trips over an edge cases and everybody understands the benefits.

Re: How to Handle Monetary Values in JavaScript

#57
post #24

> Floats: 0.1 + 0.2 // returns 0.30000000000000004 The question is how much of an issue is this really? How often is 4 parts in 10 quadrillion a meaningful error when dealing with money? Especially when most of the time JS is dealing with money it will be presentation.

I ran into this once because a price was slightly too low, and got truncated. A $19.99 item got displayed as $19.98. You can work around this by rounding everywhere but that’s error-prone.

Re: How to Handle Monetary Values in JavaScript

#58
> Using floats to store monetary values is a bad idea

This is waay overstating the case, it very much depends on whether getting the exact answer down to the penny matters to you.

Worked for a few years at a large investment bank, everything was done in floats because the modeling error of your derivatives pricers would be much larger than the roundoff error, but floats were much more convenient to develop with and faster since you avoided a bunch of casts.

Most of the time people think they need things down to the penny, they actually don't. An accountant does not care if you rounded off a few thousand dollars in your $10bn a year income statement.

A customer does not really care that you paid them $0.33 three times, rather than $0.33 twice and $0.34 on the third transaction (and fixnums don't even solve this 'extra precision' case without a bunch of extra work).

Re: How to Handle Monetary Values in JavaScript

#59

I 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.

I think the advantage behind using something like Big.js is to future proof the code against hyper-inflation. Though a dedicated currency engine would better have the ability to set and conveniently update the currency denomination of stored values to cope with this. With float64's maximum 'safe' integer at almost ten thousand trillion, I believe this should be enough to compute most commercial transactions securely…

> I think the advantage behind using something like Big.js is to future proof the code against hyper-inflation.

This is probably over-engineering.

Currencies that go through hyperinflation typically end up being officially re-denominated many times, there's no 'zero maintenance' path that a library will give you.

Re: How to Handle Monetary Values in JavaScript

#60

> Using floats to store monetary values is a bad idea This is waay overstating the case, it very much depends on whether getting the exact answer down to the penny matters to you. Worked for a few years at a large investment bank, everything was done in floats because the modeling error of your derivatives pricers would be much larger than the roundoff error, but floats were much more convenient to develop with and f…

I really want to be generous here: I think your experience is very isolated. I have family that is executive level at a Wall Street bank, they would have you fired over the superfluous loss of a dollar, much less a few thousand dollars because that type of rounding error can end up in the millions over the course of a year if you deal 100+ million dollar transactions 5-6 times a day.

Here's how it would go:

"Why are we losing a couple of thousands of dollars?"

"Well it was easier to just work in floats"

"Pack your shit and get the f--- out of here, now."

Post reply on HN