Consider the following code:
import Text.Parsec
import Text.Parsec.Language
import Text.Parsec.String
import qualified Text.Parsec.Token as Token
float :: Parser Double
float = Token.float (Token.makeTokenParser emptyDef)
myTest :: String -> Either ParseError Double
myTest = parse float ""
Now, thanks to QuickCheck I know a magic number (I have aligned result for convenience):
λ> myTest "4.23808622486133"
Right 4.2380862248613305
Some floating point numbers cannot be exactly represented in memory, some operations easily introduce «fluctuations» into floating point numbers. We all know that. However, cause of this parsing problem seems to be different.
A few words about tests that helped me discover this… feature. Put simply,
in these tests floating point value is generated, printed, and parsed back
(with Parsec). For example, number 9.2
is known to be impossible to
represent as floating
point value,
however it passes the tests (obviously because of «smart» printing
function). Why does 4.23808622486133
fail?
For those who believe that these numbers are the same and 4.23808622486133
is just shortest unambiguous representation of 4.2380862248613305
:
a1 :: Double
a1 = 9.2000000000000003
a2 :: Double
a2 = 9.200000000000001
b1 :: Double
b1 = 4.23808622486133
b2 :: Double
b2 = 4.2380862248613305
Now:
λ> a1 == a2
True
λ> b1 == b2
False