6 ms·
In Haskell/GHC it depends on what representation you chose. Default is Double, which exhibits this problem. But if I force it to Float I get the 'correct' resul
by wereHamster 11y ago
In Haskell/GHC it depends on what representation you chose. Default is Double, which exhibits this problem. But if I force it to Float I get the 'correct' result. Or if I use the 'Scientific' data type (which has arbitrary precision). Just like 'Int' vs 'Integer', where the former is restricted by the machine's word size, while the later is unbounded.
Prelude> 0.1 + 0.2 :: Float
0.3
Prelude> 0.1 + 0.2 :: Double
0.30000000000000004
Prelude> :m +Data.Scientific
Prelude Data.Scientific> 0.1 + 0.2 :: Scientific
0.3
- deleted 11y ago[deleted]
- headmelted 11y agoSo effectively, in Haskell, it's both and neither. A Float will round, as expected. A double will return the correct value as it, should. Shouldn't the Scientific, if it has arbitrary precision, arrive at the correct value too? Clearly the only logical conclusion is that the Glasgow compiler, at its roots, virtualizes the entire quantum mechanics model as a compilation step, enabling superposition-as-a-feature. My futile attempts at humour aside, this is quite an interesting thing to know and exactly the kind of intricate little detail I was hoping for. Tip of the hat, friend.
- wereHamster 11y agoThe Scientific type does arrive at the correct value. 0.3 is the correct answer, and Scientific gives it to you. I don't know why you would expect something else from a type which implements arbitrary precision arithmetic.
- dragonwriter 11y agoIts important to understand that 0.1 + 0.2 is actually 0.3, and Scientific is giving the correct answer. The Haskell type annotations aren't casting values that are interpreted as binary floating point (as might be the case in some languages), it is instructing the compiler how to treat the literals. Scientific is arbitrary precision decimal, so it can exactly represent 0.1 and 0.2, and return the exact result 0.3, rather than representing 0.1 and 0.2 as binary floating point approximations, adding them, and then producing some decimal approximation of the binary floating point result when asked.