Hacker News new | ask | show | jobs
by antonyme 2341 days ago
Sorry, but I remain skeptical. The same people who use `float` for financial calculations are probably the same people who don't understand how/why to do the rounding described to avoid these problems. Way too many programmers think that they are working in base 10 when using float. Why not just make them use it, and keep them out of trouble.

Also, I wonder what the overhead of rounding every operation is? Comparable to the cost of using a proper Decimal class?

"if you are doing some financial math that does not need to be accurate to the penny, just use floating point numbers."

I would argue that financial math by definition needs to be accurate to the penny. Where is "pretty close" financial calculations considered acceptable? Having worked at a bank, I know how seriously this sort of thing is taken.

From experience, working in scientific applications and numerical computing, summing large numbers of floats is fraught with accuracy problems too.

8 comments

> I wonder what the overhead of rounding every operation is? Comparable to the cost of using a proper Decimal class?

For what it’s worth, for the major ICs (Intel, NVIDIA, etc.) there is zero extra overhead. A choice of rounding modes is part of the floating point operation’s instruction. And keep in mind that a floating point op is always rounding no matter what you do, the question is whether it’s always using the same rounding strategy consistently, whether you can control it, and whether it has what you need.

> I remain skeptical

You are correct.

There are good reasons not to use float for money that the article didn’t discuss, and perhaps the author isn’t aware of. You run out of integer precision at 2^24, which is only 16 million. If you process a 20 million dollar payment in units of dollars, you might be off by at least a dollar. That error will multiply with every floating point op done on the result. If your units are pennies, the largest safe value is only 160,000 dollars. If you ever subtract floats, like say make a payment or withdrawal, you can run into catastrophic cancellation without knowing it. Deposit $200k and then withdraw $199k, suddenly you have a small balance with large error that could remain in your account and continue to grow until the balance is zero. https://pharr.org/matt/blog/2019/11/03/difference-of-floats....

It has great benefits to the user, though. Once you have $20 million in the bank, you can continue to withdraw $1 at a time as often as you like without spending any of your principal!
By benefits to the user which would mean the bank made a mistake and now the IT department has a production P0 issue that will probably have everyone working to fix that yesterday then sure.
> You run out of integer precision at 2^24, which is only 16 million

To be fair, the author seems to be suggesting using double-precision floating point. If you use integer numbers of pennies, signed 32-bit integers cap out at a similar value of $21M. 32 bits is just too small for financial calculations.

You’re absolutely right; he did say 64 bit. I just wouldn’t do that blindly either, and the author admitted to not being fluent in error analysis. The issue with even doubles is that the magnitude of your error in a running total calculation is a sum of all the errors of your largest intermediate results (the results of multiplies you don’t see or store explicitly). That means with a bank account, the error of your calculations continues to grow forever unless you are explicitly correcting the errors. Rounding does not solve that, so even using doubles for money is a sketchy proposition unless you really know what you’re doing.
Isn't the proposal in the article is "round after every operation"? Since rounding to nearest cent values corrects each subtotal's error to zero, this should work up to 2^53 cents. ($90T)
Yes, that is the proposal. Rounding doesn’t correct errors though, it can make the error grow faster. Rounding just keeps you from dealing with sub-pennies.
> I would argue that financial math by definition needs to be accurate to the penny. Where is "pretty close" financial calculations considered acceptable?

There is a difference between analysis and accounting. There are many financial models (e.g. Black-Scholes-Merton option pricing) that are analytic in nature and use transcendental functions, so the idea of getting an exact, arbitrary-precision answer is hopeless. Using a decimal type for this kind of computation would be an exercise in slowing down processing by a few orders of magnitude.

This is an excellent point.

When computing around money, you're either working with magnitudes or units.

If you don't know which, you're working with units; use a Decimal.

If you are working with units, ordinary binary integers are overwhelmingly better for almost every operation.
> I would argue that financial math by definition needs to be accurate to the penny.

It sometimes needs to be accurate beyond the penny; pennies may be the smallest unit of settlement, but they aren't the smallest tracked quantity in all financial matters.

This thread seems to be unaware of DEC64, so this seems as good a place as any to point to this: http://www.dec64.com/

The gist: It's efficient (adds and mults in a few instructions), and preserves the decimal representation.

It's quite simple, really: Store a whole-number integer with a smaller one representing the number of shifts to the decimal point. This is probably a good choice for sensitive financial calculations.

> I would argue that financial math by definition needs to be accurate to the penny. Where is "pretty close" financial calculations considered acceptable?

Computing tips, from the standpoint of a customer paying the tip.

Saying "pay 20%" isn't precise to begin with, in that you will not use fractional cents to make it precise, so having a tipping granularity a bit larger than a penny is also acceptable, particularly in jurisdictions where there is no one-cent coin (or equivalent) in any event.

> I would argue that financial math by definition needs to be accurate to the penny.

Yes, indeed. There is no such thing as "financial math that does not need to be accurate to the penny". I wonder if OP has ever worked with a bookkeeper...

Bookkeeping needs to be accurate to the penny. Estimating growth for the next quarter or last years GDP doesn't.
Yes, but why switch systems though ?
How are you going to do linear interpolation, let alone exponential growth, without floating-point? On August 1 you made $1000, on August 7 you made $1100, assuming that growth is linear, how much are you going to make on August 20?

If you have some routines for dividing fixed-point numbers, one, why do you believe they have more accuracy than floating point (especially if you're doing divisions by numbers that aren't divisible by 10, as in the example above - don't you have the same problem as with floating point?), and why do you believe they're more correct than floating point? Did you write a test suite? Do you know what needs to be tested? What prevented you from writing the test suite for the floating-point calculations you were originally doing to do?

> How are you going to do linear interpolation, let alone exponential growth, without floating-point?

Fixed point is one answer, but I see you know that already. I don’t know what the banks use for interest, but I can guarantee that it’s not float32.

> If you have some routines for dividing fixed-point numbers, one, why do you believe they have more accuracy than floating point

Fixed point routines do not have more best-case accuracy than float, given the same number of bits ... but float32 definitely has a worst-case accuracy that is very very bad compared to a fixed point number.

> why do you believe they’re more correct than floating point?

Can’t speak for the GP, but I think asking about correctness is a straw man. The issue is really about safety, predictability, and controllability. Floating point can be very accurate, but guaranteeing that accuracy is notoriously difficult, and it depends very much on the unknown ranges of your intermediate calculations. Fixed point, on the other hand, never changes accuracy as you go, so you don’t get surprises.

> I think asking about correctness is a straw man. The issue is really about safety, predictability, and controllability.

Uh, and compliance? (if you didn't mean to imply that under "controllability")

That's not strictly true. Some of the work I do involves software to do premium calculations for insurance. While pennies do matter for intermediate values during calculation, virtually everyone rounds the final premium to a dollar amount or the closest 10 cent increment. Nobody cares about pennies when each transaction is hundreds or thousands of dollars.
Rounding at the last step is very different from rounding at each step.
It's hard to consider float anything, but a hack - and certainly something to keep away from discrete domains (countables).

I'm a little more curious on the suitability of using integers for money though (integer number of pennies). I suppose there are cases (and rules) concerning fractional pennies? Like in the case of percents of interests, often given by the year, accumulated[1] by the month?

[1] that's probably not the correct term in English.

> It's hard to consider float anything, but a hack

GPU engineers might have something to say about that. Depending on the context, trading off on precision can be a valid engineering choice.

In some countries, cents are a very insignificant number(they have the additional three zeros for whole numbers) and businesses are allow to round to the nearest hundredth, most small to medium businesses round to an integer.