Live data from Hacker News

How to Handle Monetary Values in JavaScript

frontstuff.io

41–50 of 115 posts

Re: How to Handle Monetary Values in JavaScript

#41
My goto for any kind of arbitrary precision math in JavaScript is https://github.com/MikeMcl/big.js

As others have noted, if you're doing any kind of math that involves floating point numbers and you will displaying them to a user, you'll almost certainly want something like this.

While it's not specifically a "Money" class it can form an excellent base for one.

Re: How to Handle Monetary Values in JavaScript

#42
post #4

I 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

Floating point arithmetics is not the only problem. See bankers rounding.

Re: How to Handle Monetary Values in JavaScript

#43

Earlier quoted context omitted.

Integers can be represented exactly in IEEE754.

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.

Re: How to Handle Monetary Values in JavaScript

#44
post #25

While reading, I thought "hang on, what about non-decimal currencies?" but it turns out that is no longer a concern for modern usages: https://en.wikipedia.org/wiki/Non-decimal_currency

You can handle non-decimal currencies by treating money as a fraction.

You can implement a correct set of fraction manipulation functions in well under 100 lines of code with a bit of algebra. It seems likely there are several well-tested high-performance fraction libraries for JavaScript. They should be tiny.

Some people in the UK apparently voted to leave the EU so that they could have a blue passport [0], perhaps there are some who also hope we return to imperial measurements and pounds, shillings and pence. I'm quite sure that even in that unlikely event, some programmers will still insist on using floating point numbers for currency.

[0] Although Malta has a blue passport and is in the EU. And the only reason the passports were blue in the first place was to meet an international standardization.

Re: How to Handle Monetary Values in JavaScript

#45
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'm far from wizard on the topic, but from my experience it's not that simple since the relative magnitudes of the operands and the operator affect the size of the error in non obvious ways.

I spent 13 years maintaining a 2mloc reservation and accounting system that used floats for everything. By the time I got there and understood enough it was simply too late to do anything about it.

Just say no, really; that road leads to madness.

If you need precision; and many do; consider fixnums, rationals or bignums, in order of increasing complexity and flexibility.

Re: How to Handle Monetary Values in JavaScript

#46

Banking apps, e-commerce websites, stock exchange platforms, we interact with money daily. We also increasingly rely on technology to handle ours. Yet, there’s no consensus around how to programmatically handle monetary values. I wonder if the average person would find this frightening.

Douglas Crockford has talked about JavaScript's number handling, and it makes for a good listen. It's in https://www.youtube.com/watch?v=DxnYQRuLX7Q and there's a follow-up in https://www.youtube.com/watch?v=oYFU0gkAYdc

Re: How to Handle Monetary Values in JavaScript

#47
post #37

Equally important to choosing a valid numeric type to store the data is solid business logic to handle it. In the contrived example of splitting a value of 999.99 among more than one payment, the correct solution is: * Determine the next payment based on the current balance. * Invoice/Apply/Etc that payment * Repeat until there is a balance of 0 (zero).

recording an incoming payment and applying that payment value to specific accounts is its own thing to be aware of. People want to see that they paid $200, even if it was $150 to one account and $50 to account.

Re: How to Handle Monetary Values in JavaScript

#50
post #17

Earlier quoted context omitted.

Your details are off. 1.0 is precisely representable in double precision floating point with no error.

Sorry, picked the wrong number. But I think the general idea is correct.

I am pretty sure you were thinking of 0.1 which, indeed, requires an infinite number of digits to be represented in binary (like 1/3 in decimal).
Post reply on HN