4 ms·
No, do not do financial calculations in binary floating point. Converting between base 2 and base 10 fractions can do funny things (including during the roundin
by kstenerud 7y ago
No, do not do financial calculations in binary floating point. Converting between base 2 and base 10 fractions can do funny things (including during the rounding step, which is also 99% guaranteed to be inaccurate because base 10 fractions can't be exactly represented as base 2 fractions).
Most professional financial packages use fixed point decimal, which can easily be implemented by specifying a fractional unit (such as thousandths of cents). The computations will be faster (because they're ints) and at 64 bits you get a min/max value of +- 9,223,372,036,854,775,807 units (90 quadrillion if you're using thousandths of cents), and rounding functions will always be exact (provided you have enough digits of scratch precision).
There's also the 2008 addition of decimal floating point types to ieee754 [1], which have been implemented in gcc and clang (software emulation only).
So no, don't use binary floats for financial calculations. You're 99.9% guaranteed to get it wrong and introduce bugs.
[1] https://en.wikipedia.org/wiki/Decimal64_floating-point_format https://en.wikipedia.org/wiki/Decimal64_floating-point_forma...
- dragonwriter 7y ago> No, do not do financial calculations in floating point. Floating point is fine, so long as it is big enough for the application and decimal (not binary) floating point. Fixed point decimal is easier to get right, and, really, arbitrary precision decimal (or, for even more generality, arbitrary precision rational) is even easier to get right.
- kstenerud 7y agoUpdated my comment, thanks. I meant binary float. Decimal float is rather unknown (unfortunately), so most people imply binary when they say "float", and most languages don't even have decimal float, so the warning is necessary. PSA: If your favorite language doesn't support ieee754 decimal float, start badgering them to add it! This has gone on long enough, and the inertia against change is strong.
- dragonwriter 7y ago> If your favorite language doesn't support ieee754 decimal float, start badgering them to add it! This has gone on long enough, and the inertia against change is strong. Without hardware support (which makes decimal float a good choice for performance), I'm not sure I've ever run into a use case where decimal float is a compelling choice if I already have arbitrary precision decimal and hardware-backed binary float types available.
- ncmncm 7y agoSuperstitions about decimal floating point are far more prevalent, even, than superstitions about binary floating point. Generally, whatever you think you are getting from decimal floating point, you very, very likely are not. There is exactly one place where decimal floating point is the Right Thing: when interoperating with another system that is already using it. Those exist because others' superstitions have been locked in, sometimes even into regulatory frameworks. Decimal floating point is inherently less accurate, on any lossy computation, than binary, so you need a lot more digits to maintain the same result accuracy. This is why 128-bit decimal is common. It is generally pointless to argue with anybody who thinks decimal computations are better. If reason mattered to them, they wouldn't be stuck on the idea. So, just roll your eyes and, if they have any authority, use a library. Performance will suck, but not so badly as you might guess, and you can spend the time until release circulating your CV without panic.
- ComputerGuru 7y agoA notable exception to the general lack of floating decimal support is C#, which has had floating decimal (System.Decimal) support in the CLR from the start (128 bits with a scale of 0 to 28). https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/types#the-decimal-type https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...
- sixstringtheory 7y agoApple SDKs have NSDecimal [0] and NSDecimalNumber [1]. [0]: https://developer.apple.com/documentation/foundation/nsdecimal https://developer.apple.com/documentation/foundation/nsdecim... [1]: https://developer.apple.com/documentation/foundation/nsdecimalnumber?language=objc https://developer.apple.com/documentation/foundation/nsdecim...