News for hackers. Stuff that matters.
Re:Why does 0.1 and 0.2 = 0.30000000000000004? by SideQuark on Wednesday February 08, 2023 @09:24PM (#34718978)
Fixed point fails for just about any financial calcs beyond simple addition. Try doing common compound interest calcs for example, and you'll get much worse answers.

The correct answer is to use floating point and to understand it and numerical software before doing it. If you don't have a decent understanding of numerical analysis, don't write important numerical software.

Re:Why does 0.1 and 0.2 = 0.30000000000000004? by PeterisP on Wednesday February 08, 2023 @10:12PM (#34719312)
Well, but the "common" compound interest calcs aren't how compound interest is actually calculated. You use floating point to calculate the amount due, but once you do, you round to a fixed point (e.g. whole cents) and that's it, that's the final truth. The interest accrued, interest due and interest paid out is a fixed point value by definition. And then for the next interest period you start with that rounded off value as the basis for calculating the next interest which compounds.

So yes, if you use fixed point you obviously get different results, but you won't get correct results according to what's required by accounting standards unless you truncate to fixed point when needed. It's not that this difference is large - after all, it's about rounding off fractions of a cent - but accounting does need to be exact.

Re:Why does 0.1 and 0.2 = 0.30000000000000004? by SideQuark on Thursday February 09, 2023 @02:53PM (#34730305)
> aren't how compound interest is actually calculated.

Completely depends - package them in tranches to sell to secondary markets by the thousands - then you do exactly as I pointed out. Or if you're doing Monte Carlo futures projections modeled as compound interest and only need the value at a future time.... Or any of thousands of financial modeling needs....

If you're printing monthly bills for consumers then you round, but only at output, and only for viewable parts.

So you cannot claim things are not computed this way - it depends on the financial application you're working on,

>So yes, if you use fixed point you obviously get different results, but you won't get correct results according to what's required by accounting standards

Ha - which standard are these? Care to cite them? I've been through this space a long time, and every time someone tells me there is a standard and I ask them for it they soon realize there is no gold, single standard. There are zillions of acceptable choices. There are ones for consumers, ones for intrabank, interbank, fed to bank, loans, mortgagaes, taxes, and on and on. There is no "correct results according to what's required by accounting standards ".

Please cite your standards that apply to all these cases.

Have you worked in finance on numerical financial software?

>you round to a fixed point (e.g. whole cents) and that's it, that's the final truth

Having done numerical stuff, including finance for decades, you simply write the entire codebase in floating point, being sure to do proper analysis that things handle ranges correctly.

Then, and only for output, do you snap to desired observable precision. Never ever even once do you round something to make it look pretty, then jam it back into calculations.

Re:Why does 0.1 and 0.2 = 0.30000000000000004? by PeterisP on Friday February 10, 2023 @07:48PM (#34748248)
The difference seems to be that you are talking about modeling and analysis and I was talking about calculating actual interest, as in the interest that is actually owed for a particular loan or contract (i.e. every particular contract) and properly accounting for that.

It doesn't matter if the interest is calculated for consumers, intrabank, interbank, fed to bank, loans, mortgages, taxes - the interest rates and interest periods and interest day basis and all kinds of details may vary, and of course accounting standards vary between countries, but the core principles are the same that it all eventually comes up to some amount of money owed to the counterparty - measured in whole cents or perhaps whole dollars or roubles or whatever, but never an arbitrary-precision float. You can't get to a final compounded result "only for output" because when interest compounds (for example, monthly) then at every such point you do have actual "intermediate output" which materializes into a customer-visible change of balance from which the next period's interest is then calculated, and that intermediate output gets rounded because that (unlike estimates or models) is a specific balance owed and it is denominated in a currency with fixed, limited precision. And so after many such steps, the total actual compound interest - i.e. the actual dollars and cents paid by (or to) the counterparty - is slightly different from what the common modeling approach gets if e.g., as you state, it does rounding only for the final output. The difference is tiny, so there is no problem for modeling to ignore it, but actual financial systems (i.e. tracking facts of money owed, not doing estimates and models for decision support) do have to come down to a rounded fixed-precision number owed for every contract at the end of every day.

Re:Why does 0.1 and 0.2 = 0.30000000000000004? by wruza on Thursday February 09, 2023 @04:08AM (#34721439)
There’s also a middle ground, which I find more useful than either full-floating or full-fixed. Use floating for intermediate calculations and fixed-only with autorounding for “fields”. So that:

  var t = obj.x // fixed -> fp
  for (<n times>) {
    t += 0.1
  }
  obj.x = t // adds exactly n/10
The key observation is that intermediates don’t float free long enough before being assigned back to a fixed storage. So the error has no chance to accumulate. But still can manifest in comparisons. If necessary, floating point can be replaced with precise enough fixed point for intermediates (at a cost, e.g. tens of digits).

The correct answer is to use floating point and to understand it and numerical software before doing it

Yes, but this also has associated costs and risks. Unless you’re pressed against some wall, it’s more safe to offload that to a runtime. Humans are way too unreliable when it comes to understanding numerical software.

Re:Why does 0.1 and 0.2 = 0.30000000000000004? by SideQuark on Thursday February 09, 2023 @02:56PM (#34730348)
Never ever ever ever perform summation like that. You just added O(n) error instead of O(1) error.

This is why ad-hoc methods that people feel are ok based on untrained or not-carefully-studied analysis should not write production numerical code.

Just use floating point everywhere, and only output things snapped to whatever resolution you want (and even that is tricky). Otherwise all those fixed to float to fixed to float going on in your code are going to add all sorts of numerical problems - each loses information.

Re:Why does 0.1 and 0.2 = 0.30000000000000004? by wruza on Thursday February 09, 2023 @06:29PM (#34733268)
I believe you missed the part where it rounds the error away. Of course for high N it may overflow into a significant part, but that’s 25-30 bits away for `double` and much more for custom non-fixed types, which implies a dataset that a client app wouldn’t be able to handle anyway. Multiplication is another beast, but repeating multiplication doesn’t appear in finance naturally.

In case you did not miss it: I’ve worked with and supported financial systems which do exactly that for a very long time without any micro-numerical issues^. Otoh, floating-point is a constant source of microbugs, unless all your developers are Knuth-level pros who are also versed in consulting and have no monday mornings or deadlines. It doesn’t matter if an error is O(N < 1e6) or O(1) when an underwater comparison to a limit fails and control flow triggers randomly.

^ The last [few] cent problem is usually handled explicitly, either naively (last=rest) or in Bresenham-like way (rarely, when it matters) and is easily catched in an accounting balance when left unhandled

Re:Why does 0.1 and 0.2 = 0.30000000000000004? by SideQuark on Friday February 10, 2023 @05:25AM (#34737877)
>I believe you missed the part where it rounds the error away.

I've been down this argument with other HN commenters some time back and explicitly demonstrated that it fails when you do it this way. It's not worth chasing down all the details again.

The short answer is it will fail, and in unexpected places. The only correct answer when doing this to is do the numerical analysis completely and correctly. This half-assed "it rounds the error away" is completely insufficient (and wrong).

The problem with letting such error slop around in code is that someone will take your code and use it to aggregate 1m loans, then your 25 bits of safety just became real money. Then someone will leverage that routine and add more problems.

When you build the lowest pieces so sloppily, it quickly contaminates the whole system. Make each piece as numerically solid as possible, otherwise you will get bitten.

If you have not proven your algorithm correct using numerical analysis for this stuff, it is not correct. End of story.

>but repeating multiplication doesn’t appear in finance naturally

Yes it does - compound interest if you need periods and tables.

And we're in agreement - floating point, not fixed point, is how to do financial calculations. I'm amazed how many people on HN want to argue that fixed point works when it's easy to demonstrate it fails in terrible ways and is significantly more error prone than simply using doubles (or double- or quad- doubles when needed).

Re:Why does 0.1 and 0.2 = 0.30000000000000004? by wruza on Friday February 10, 2023 @08:15AM (#34739238)
Maybe it will, I’m only halfway there. I’ll take the risk, cause your solution (hiring theorem provers) simply costs much more than the risk itself upfront.

Yes it does - compound interest if you need periods and tables.

Only if you don’t round to fixed before capitalizing. But when you don’t, numerically less savvy investors (99.9% of people) would just ask to fix it and stop being so smart. They want deterministic output for any particular end of period.

I see you’re coming from academic side, but real world doesn’t work like that. Nobody’s going to take our algorithms and shove 2^(>20) records of sums greater than $100M into them.