4 ms·
Decimal floating point won't avoid this issue, for a sufficiently large value the ulp would be 10.
by smallnamespace 8y ago
Decimal floating point won't avoid this issue, for a sufficiently large value the ulp would be 10.
- ummonk 8y agoIt would solve more common issues like this though: > I appreciate that it may be surprising that 0.1 + 0.2 != 0.3 at first, or that many people are not educated about floating point, but I don't understand the people who "understand" floating point and continue to criticize it for the 0.1 + 0.2 "problem." That's not a calculation that should require a high level of precision.
- smallnamespace 8y agoThe correct solution is to understand how floating point number systems work and use near comparisons for floats. Decimal fp is still 'wrong' for, say, 1/3 + 1/3 = 2/3.
- int_19h 8y agoA lot of real-world data is already in base-10 for obvious reasons, and so an arrangement that lets you add, subtract and multiply those without worrying is worthwhile, even if it can't handle something more exotic.
- smallnamespace 8y agoWould you really call 'any rational with divisible factors other than 2 and 5' to be 'exotic'? Maybe we really should move back to base-60 like the Babylonians used, then you could at least divide by 3.
- int_19h 8y agoBecause humans standardized on base-10, and computers are ultimately for humans to use?
- MauranKilom 8y agoMaybe we should also add data types to every language that can convert exactly between inches, feet, miles and every other non-base-10 unit? The argument "we want to look at base-10 in the end so it should be the internal representation" is really weak and ignores basically every other practical aspect.
- int_19h 8y agoThe way to avoid this issue is to avoid floating-point numbers that have any implicit zeroes (due to exponent) after its significant digits. Basically restrict the range to only values where it's guaranteed that for any x1 and x2 from the range, (x1-x2) produces a non-zero dx such that x2+dx == x1. The only example off the top of my head that is floating point is C# "decimal", which actually originates from the Decimal data type in OLE Automation object model (which could be seen in VB6, and can still be seen in VBA): https://msdn.microsoft.com/en-us/library/cc237603.aspx https://msdn.microsoft.com/en-us/library/cc237603.aspx Note this bit: "scale: MUST be the power of 10 by which to divide the 96-bit integer represented by Hi32 * 2^64 + Lo64. The value MUST be in the range of 0 to 28, inclusive." The reason why it's limited to 28 is because the 96-bit mantissa can represent up to 28 decimal digits exactly. The way it's enforced, any operation that produces a result outside of this range is an overflow error (exception in .NET).
- dbaupp 8y agoI believe IEEE754 floats have that subtraction/addition guarantee (as long as the hardware doesn't map subnormals to zero). The problem in this case is the input numbers are rounded when they are converted from text/decimal to a float, and so aren't exact.
- int_19h 8y ago> I believe IEEE754 floats have that subtraction/addition guarantee (as long as the hardware doesn't map subnormals to zero). They don't - all 11 bits of the exponent (for float64) are in use, so you can have something like 1e300, and then you can't e.g. add 1 to it and get a different number. >>> x = 1e100 >>> x 1e+100 >>> y = x + 1 >>> y 1e+100 >>> x - y 0.0
- dbaupp 8y agoThat's something else: x == y, so the difference must be 0. What you said above is if x != y, x - y != 0 which holds for all x and y, but is different to if dx != 0, x + dx != x which fails for some (many!) x and dx.