
Never Use Floats for Money (2016) - adunk
https://husobee.github.io/money/float/2016/09/23/never-use-floats-for-currency.html
======
riskneutral
This type of thing coming from programmers really bothers me. Here is a more
universal rule: Never say "never."

Whether or not floating point numbers can be used depends on the context. If
you are talking about an accounting system, core banking system, ERP, or
similar transactional systems, then sure you probably should use integers not
floats.

However, if you're working on any financial model, like something as simple as
discounted cash-flow model, then floating point is the correct choice and only
choice.

I've had a programmer try to convince me that I had to use integers in
financial modeling software that I was developing, and he used this same
folksy argument with me. It was a genuine struggle to convince him that this
was not a universal law and made no sense for the application at hand.

~~~
revicon
I’ve built two different payment platforms in the past, I’m curious why
floating point is the correct and only choice for financial modeling.

~~~
unlinked_dll
Quantization error is irrelevant in modelling so far as the datatype has the
appropriate dynamic range. You don't care about the rounding errors, you care
about the speed of execution of your model and how able it is to find
trends/behaviors. Exact values aren't useful.

------
analog31
I'd qualify the statement a bit and say, don't use floats for accounting. It's
a tradition that the last column of an accounting calculation is a kind of
crude error checking code.

I think if you're doing financial modeling, or anything where the real
uncertainty is bigger than your unit of money, then it's like any other
calculation -- use floats with all of the cautions that you learned in
numerical analysis class.

My dad played the stock market and used a _slide rule_ for his calculations.

Another reminiscence: Since he owned some stocks, my dad got annual reports. I
remember leafing through the report from General Motors, and seeing that all
of the numbers were given at full precision, down to the penny. I remember
thinking to myself: If one worker accidentally carries a pencil home, those
numbers are all wrong!

------
nostrademons
I remember hearing this back when I worked on financial software for hedge
funds (2005ish), adjusting our product so it represented currencies as integer
numbers of cents, taking the change to my boss (the company CEO), and then
hearing "Use floats for money. All of our customers do, and if we don't you'll
create needless friction for them."

Ran into it more recently when doing cryptocurrency market analytics. Bitcoin
represents currency as integer numbers of satoshi, where 100M satoshi = 1 BTC.
Ethereum represents it as integer numbers of wei, where 10^18 wei = 1 ETH. I
thought I'd be smart and use these fundamental units internally, only to find
out that basically every exchange quotes prices in floats. By the time you get
the data, it's already lost whatever precision it had, and you're just
introducing needless friction by trying to get smart.

Sometimes being compatible is more important than being correct.

~~~
flukus
> and then hearing "Use floats for money. All of our customers do, and if we
> don't you'll create needless friction for them."

Until a competent customer doesn't, then you've got to explain to them why
your calculations are intentionally wrong, never a good look. Regulatory
bodies also tends to want the correct decimal numbers.

~~~
nostrademons
If 99% of your customers do things the wrong way and 1% wants to do it the
"correct" way that you don't support, there's an easy business call: you do it
the way the 99% want and tell the 1% "Sorry, we don't support that. Hopefully
you'll find a provider who does." Massive portions of the economy are built
upon that principle, from IE6 to UNIX to C to VHS to QWERTY to 120V
electricity to U.S. custom measurements to MM/DD/YYYY date formats to the use
of decimal (as opposed to binary) subdivisions in the first place.

Context matters too: both of these examples are financial _modeling_ as
opposed to transactions, where (as riskneutral's sibling comment points out)
floating point error is swamped by the errors in your models in the first
place, and some concepts can't be modeled at all with integers. Also
regulators explicitly don't care about this area: if your models give
incorrect results and you trade on them that's your problem.

------
bonyt
Fun Fact: Microsoft Excel uses double precision floating point numbers. Much
of the world's numbers are run through Excel. I feel like some people have
probably just ended up using the same floats themselves, just so that their
boss's spreadsheet agrees with their numbers...

[https://en.wikipedia.org/wiki/Numeric_precision_in_Microsoft...](https://en.wikipedia.org/wiki/Numeric_precision_in_Microsoft_Excel)

~~~
user2994cb
As does Javascript of course. On the other hand, IEEE754 guarantees correct
rounding, so floating point operations on integral values will come out
alright (additions and multiplications will be exact within a large range, and
inexact divisions will be rounded correctly, so you shouldn't be any worse
than using integer operations).

------
pgroves
More time has passed between Office Space (1999) and today than between Office
Space and Superman 3 (1983).

------
Cactus2018
the perennial stackoverflow question ->
[https://stackoverflow.com/questions/3730019/why-not-use-
doub...](https://stackoverflow.com/questions/3730019/why-not-use-double-or-
float-to-represent-currency)

A real life example: in the R language, this statement resolves to FALSE

    
    
        > 74.20+153.20==227.40
        [1] FALSE

------
zzo38computer
I agree that you should not use floating numbers for amounts of money (maybe
with some kind of calculations it might be suitable, but this is rare), but I
do not deal with calculations involving money on the computer so much. But,
yes normally integers are better for the amount of money (and for some other
stuff that normally involves fractions, too; if fixed point is suitable (as is
the case for money), then integers are probably better than using floating
point). (Comment 22322487, and its replies, also mentions why sometimes
floating point is used, but normally to record amounts of money, integers are
better. As other comments mention, sometimes you might even use other types
such as rational type.)

------
toolslive
In the past (1990s) there have been banks caught skimming. They were always
exchanging (with other banks) amounts of currency (fe EUR to USD) specifically
chosen so the error was always in their favour.

------
TorKlingberg
The article is right, you should use integers for the number of cents (or
whatever the smallest unit of the currency is). That is easy enough as long as
you are just adding and subtracting, but what do you do about multiplication
and division? How do you calculate interest or yearly yields? I think the
answer is fixed point, but that is not easy.

~~~
viraptor
What problem do you see with multiplication or division? You can still do
those with the precision you need, followed by the legally valid rounding for
the use case.

Unless you don't have a use case where those are defined/relevant, then
¯\\_(ツ)_/¯

------
Will_Parker
In terms of purity, sure, but pragmatically, meh. You do need to round to
cents in ui and after every calculation though. Exercise: how large do amounts
need to be before losing a penny?

I used to evangelize integer cents but then I worked on a few systems with
floats and the world didn't fall over.

------
fb03
How do I properly handle Money on the web frontend side?

on the backend I have python's exquisite Decimal() which covers all bases and
is base-10

how would one guarantee that precision when you have to serialize it into json
and that's gonna become a normal double in JS?

~~~
dsego
There are libraries, such as Dinero.JS [0] or Decimal.js (handles decimals as
strings). Alternatively, don't use decimals and always convert everything to
cents.

[0][https://frontstuff.io/how-to-handle-monetary-values-in-
javas...](https://frontstuff.io/how-to-handle-monetary-values-in-javascript)

------
davidw
Postgres has this: [https://www.postgresql.org/docs/12/datatype-
numeric.html#DAT...](https://www.postgresql.org/docs/12/datatype-
numeric.html#DATATYPE-NUMERIC-DECIMAL) which is pretty handy.

------
chimen
Great advice on going for the lowest (cents) so you can work with integers. I
do something similar with dates on all my apps where I go for ints in the
database and always save unix timestamps. I can't stand dates unless I'm
working with timestamps.

~~~
notduncansmith
Same! Dates are one of the biggest sources of programmer error in my
experience, and representing them as ints until they are rendered to a UI
prevents a lot of it.

------
etdeagle2
I tried a small C++ program and it does not exhibit this behavior. Why is it
not showing there?

program: #include <iostream>

using namespace std;

int main(int argc, char __argv) { float s = 165 * 1.40; cout << s << endl; }

output: ./floats 231

~~~
dchest
[https://stackoverflow.com/a/554134/311196](https://stackoverflow.com/a/554134/311196)

~~~
etdeagle2
thanks!

------
iamleppert
Use a big decimal library with the precision you need, overload the
serialization methods for your preferred data store and be done with it.

------
ineedasername
I just use blobs for everything. Just in case.

------
Hamuko
I can see a whole heap of issues using integers and cents when it comes to VAT
calculation.

------
person_of_color
Use a rational type :)

~~~
hansvm
I rather like this approach. It easily handles sub-cent transactions with any
desired degree of precision (e.g. internal computations using the 9/10 cent bs
at gas pumps). Internally everything is a rational quantity, and you just need
to maintain correct (de) serialization at the system boundaries.

That all gets thrown out the window when somebody really wants an exchange
rate of pi for god knows why, but satisfying every real number is impossible,
and satisfying every computable number exposes you to things like the halting
problem, so having a system that just supports rationals seems like a good
compromise.

------
Koshkin
Money is real.

