Floating point issues
Hi, I had the following issue reported to me by Albert (please CC him on responses), which if it is correct is certainly very confusing. Consider the following examples: Hugs> 3 ** 2 9.0 Hugs> 3 ** 2 :: Float 9.0 Hugs> 3 ** 2 :: Double 9.0 Hugs> 3 ** 2 == 9 False Hugs> 3 ** 2 == (9::Double) False Hugs> 3 ** 2 == (9::Float) True Note that GHC gets the sensible answer of True for all these cases. I also tested this on Linux Hugs with the same results as WinHugs. This doesn't seem that logical - I know floating point == is just asking for trouble, but why is the less precise one keeping the correct answer? Also it seems weird not to have the property that read . show = id and that show a == show b => a == b Thanks Neil
On Thu, Jun 08, 2006 at 10:26:49AM +0100, Neil Mitchell wrote:
Consider the following examples:
Hugs> 3 ** 2 9.0 Hugs> 3 ** 2 :: Float 9.0 Hugs> 3 ** 2 :: Double 9.0 Hugs> 3 ** 2 == 9 False Hugs> 3 ** 2 == (9::Double) False Hugs> 3 ** 2 == (9::Float) True
Note that GHC gets the sensible answer of True for all these cases. I also tested this on Linux Hugs with the same results as WinHugs.
This doesn't seem that logical - I know floating point == is just asking for trouble, but why is the less precise one keeping the correct answer? Also it seems weird not to have the property that read . show = id and that show a == show b => a == b
Hugs uses the Haskell 98 default definition of (**): x ** y = exp (log x * y) GHC uses a specialized definition of (**) that happens to give 9.0, but the default definition gives this answer (in ghci): Prelude> exp (log 3 * 2) :: Double 9.000000000000002 Hugs gets the same answer, but shows it incorrectly. This is a documented bug (section 5.1.5 of the User's Guide): Haskell 98 has a precise definition of show on these types that does indeed satisfy those equations, but Hugs uses printf instead, to avoid a lot of extra code in the Prelude. So Hugs> 3 ** 2 :: Double 9.0 Hugs> 3 ** 2 - 9 :: Double 1.77635683940025e-15 As for Float, Hugs does all operations in double and then truncates to float, and in this case truncation wipes out the small error. As you say, floating point is notorious for this sort of thing. The only real bug here is in Hugs's show.
participants (2)
-
Neil Mitchell -
Ross Paterson