News for hackers. Stuff that matters.
Re:Beware of Fast-Math by SonOfLilit on Saturday May 31, 2025 @11:04AM (#44144734)
You can make money modeling buy/sell decisions in floats and then having the bank execute them, but if the bank models your account as a float and loses a cent here and there, it will be sued into bankruptcy.
Re:Beware of Fast-Math by jcranmer on Saturday May 31, 2025 @11:31AM (#44144902)
A double-precision float has ~16 decimal digits of precision. Which means as long as your bank account is less than a quadrillion dollars, it can accurately store the balance to the nearest cent.
Re:Beware of Fast-Math by kccqzy on Saturday May 31, 2025 @11:10AM (#44144789)
You will not lose a cent here and there just by using float64, for the range of values that banks deal with. For added assurance, just round to the nearest cent after each operation.
Re:Beware of Fast-Math by kbolino on Saturday May 31, 2025 @11:52PM (#44148545)
You can round to the nearest .0078125 (1/128) but not to the nearest .01 (1/100) because that number cannot be represented in float64.

To round to the nearest cent, you would need to make cents your units (i.e. the quantity "1 dollar" would be represented as 100 instead of 1.0).

Re:Beware of Fast-Math by nurettin on Sunday June 01, 2025 @12:42AM (#44148698)
Within the general context of this discussion, "cannot be represented" is a red herring.

You don't need to have a representation of the exact number 0.1 if you can tolerate errors after the 7th decimal (and it turns out you can). And 0.1+0.1+0.1 does not have to be comparable with 0.3 using operator==. You have an is_close function for that. And accumulation is not an issue because you have rounding and fma for that.

Re:Beware of Fast-Math by kbolino on Sunday June 01, 2025 @09:17AM (#44150656)
Ok, but in the context of this thread, it is important. Remember that I'm replying to the statement "For added assurance, just round to the nearest cent after each operation." That is misleading advice and the behavior of floats is just context for why.

First of all, a lot of languages don't include arbitrary rounding in their math libraries at all, only having rounding to integers. Second, in the docs of Python, which does have arbitrary rounding, it specifically says:

    Note: The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. [...]
Thus I think what I said stands: you cannot round to nearest cent reliably all the time, assuming cent means 0.01. The only rounding you can sort of trust is display rounding because it actually happens after converting to base 10. It's why 2.675 will print as 2.675 in Python even though it won't round as you'd expect. But you'd only do that once at the end of a chain of operations.

In a lot of cases, errors like these don't matter, but the key point is that if the errors don't matter, then they don't need to be "assured" away by dubious rounding either.

Re:Beware of Fast-Math by nurettin on Sunday June 01, 2025 @11:06AM (#44151432)
floats are also a red herring. Maybe you can continue with someone else.
Re:Beware of Fast-Math by kccqzy on Sunday June 01, 2025 @07:08PM (#44154445)
> First of all, a lot of languages don't include arbitrary rounding in their math libraries at all, only having rounding to integers.

You do the simple, obvious and correct thing: multiply by 100, round to int, convert to double, divide by 100. It does not matter whether the final division by 100 results in an exact value. (You might argue this is inefficient but it's not a correctness problem.)

> for example, round(2.675, 2) gives 2.67 instead of the expected 2.68.

You are not going to execute round(2.675, 2) if you follow my advice of rounding after every operation. Because the error will never reach 0.005. Your argument is moot.

Re:Beware of Fast-Math by kbolino on Monday June 02, 2025 @12:05AM (#44155763)
round(2.14*1.25,2) - round(2.675,2) > 0.01