That would have been my default assumption
That would have been my default assumption
So you need to run a massive physics simulation really fast? Yes, floats are great.
You need to calculate taxes on a massive corporation's fiscal year? Bad idea.
Some libraries advertise "arbitrary precision", many computer systems have a "decimal" type intended for currency, etc. and then they won't make all the same mistakes, but as the OP said you still need to control rounding rules and make sure they match the law.
That depends on whether the hundred-billion-dollar corporation cares about being off by a dollar.
And by "off" I mean "different from how humans round", not necessarily further away from an infinite-precision calculation. In fact at "massive corporation" level I would guess that binary floating point is more accurate than a typical fractional penny system.
How many hundred billion dollar corporations are private? Public companies would care a great deal about accounting accuracy.
Every single publicly listed company, every single one of them, is off when it comes to calculating their taxes by way more than just a dollar. And I don't mean clever accounting tricks or tax avoidance schemes, I just mean in terms of actual mistakes being made.
Also if the local tax code states using 5 decimal places for intermediate values when you will introduce “errors” using formats that give greater precision as well as those that give less precision. Having worked on mortgage and pension calculations I can state that the (very) small errors seen at individual steps because of this can balloon significantly through repeated calculations.
Furthermore, the name floating point gives away the other issue. Floating point numbers are accurate to a given number of significant figures not decimal places. For large numbers any decimal places you have in the result are at best an estimate, and as above any rounding errors at each stage can compound into a much larger error by the end of a calculation.
And binary has trouble representing fractions that are common in prices:
$ bc
obase=2
scale=20
1/5
1/5 in binary is a repeating binary fraction: 0.0011001100110011...Just as you can't express 1/3 or 1/7 precisely as a non-repeating decimal fraction, you can't express 1/5 and 1/10 as a non-repeating binary fraction. As a result, most prices involving cents in currency cannot be expressed precisely as binary floating point numbers.
edit: fixed formatting
FP numbers have their use but they re better reserved for scientists doing actually scientific stuff and not just to represent what are actually tiny numbers (in the grand scheme of things) and which can be represented perfectly by other means.
This is not to say that using floats and rounding correctly necessarily does yield different results, by the way (although most likely it will) – but if they do differ, you're going to have a bad time using floats.
-2.7755575615628914e-17
And now you overdrafted
There is no floating point value equal to 0.3.
You can represent 0.3 as 0.300000…0004, which rounds to 0.3 again in the end.
But you need to reason about the number and nature of intermediate operations, which is tricky, since errors usually accumulate and don’t always cancel out.
No, it really is the original sin here.
> since errors usually accumulate and don’t always cancel out.
The problem is that from the system's perspective, these aren't "errors". 0.3000000....4 is a perfectly valid value. It's just not the value that you want. But the computer doesn't know what you want.
When I say "error" here I mean the mathematical term, i.e. numerical error, from error analysis, not "error" as in "an erroneous result".
There is a formalism for measuring this type of error and making sure it does not exceed your desired precision.
> It's just not the value that you want.
My point is exactly that if you're looking at 0.300000...4, you aren't done with your calculation yet. If you stop there and show that value to a user somewhere (or are blindly casting it to a decimal or arbitrary precision type), you are using IEEE 754 wrong.
You know that your input values have a precision of only one or two sub-decimal digits, in this example, so considering more than ten digits of precision of your output is wrong. You have to round!
It's the same type of error that newspapers sometimes make when they say "the damage is estimated to be on the order of $100 million (€93.819 million)".
Yes, this is often more complicated and error-prone (the human kind this time) than just using decimals or integers, and sometimes it will outright not work (since it's not precise enough – which your error analysis should tell you!)! But that doesn't mean that IEEE 754 is somehow inherently not suitable for this type of task.
As a practical example, Bitcoin was (according to at least one source) designed with floating point precision and error analysis in mind, i.e. by limiting the domain of possible values so that it fits into double-length IEEE 754 floating point values losslessly – not because it's necessarily a good idea to do Bitcoin arithmetics using floating point numbers, but to put bounds on the resulting errors if somebody does it anyway: That's applied error analysis :)
Often these things are not a big problem on their own, but then later gets compounded because someone does something stupid like passing these imprecise values around to be distorted further all over the place.
And sometimes the reason it doesn't become a legal problem turns out to be because your finance department quietly works their way around it by expending expensive manpower accounting for discrepancies that shouldn't be there in the first place, and so increases the cost to the business by many magnitudes over the loss the developers might have assumed to be the worst case (if they're aware of the discrepancy at all).
This is one of those things you can get away with many times, many places, with no ill effects. But when it finally bites you it can get expensive and/or really bad to deal with, and it's fixed by simply never doing money calculations on datatypes with imprecise arithmetic, and having a five minute conversation with your finance team about what your local rules for rounding tax amounts are.
Where in financial accounting do people multiply an amount of money by a multiplicand larger than order-of-unity?
Yeah, that's one example. I wasn't imaginative enough; thanks!
1: https://en.wikipedia.org/wiki/Decimal64_floating-point_forma... 2: https://dev.mysql.com/doc/refman/8.0/en/precision-math-decim...
The standard in ad-tech (not sure about banking) is to use int64s representing either microdollars or microcents, so a max capacity of 9.3*10^13 or 10^11 dollars
It gets even worse when you start doing calculations on floats/doubles.
These inaccuracies are ok for a lot of things. graphics often uses floats and the errors are small enough they don't matter.
But currency absolutely needs to be accurate, and for that reason, floats/doubles are in appropriate.