David Roundy droundy at darcs.net
Mon Jun 16 21:32:19 EDT 2008

```On Mon, Jun 16, 2008 at 05:39:39PM -0700, Don Stewart wrote:
> > decodeFloat really ought to be a partial function, and this should
> > be a crashing bug, if the standard libraries were better-written.
>
> It's a bug in the H98 report then:
>
>     Section 6.4.6:
>
>     "The function decodeFloat applied to a real floating-point number returns
>     the significand expressed as an Integer and an appropriately scaled
>     exponent (an Int). If decodeFloat x yields (m,n), then x is equal in value
>     to mb^n, where b is the floating-point radix, and furthermore, either m
>     and n are both zero or else b^d-1<=m<b^d, where d is the value of
>     floatDigits x.  encodeFloat performs the inverse of this transformation.
>     "

Yes, it is a bug in the report, that it doesn't fully specify the
behavior this function when given a NaN or infinity.  There's also a
bug in the standard libraries, which is that they don't conform to the
report.

let x = 0/0
let (m,n) = decodeFloat x
Prelude> (m,n)
(-6755399441055744,972)
Prelude> let x = 0/0
Prelude> x
NaN
Prelude> let d = floatDigits x
Prelude> let (m,n) = decodeFloat x
Prelude> let x' = (fromInteger m :: Double)*2^n
Prelude> x'
-Infinity
Prelude> 2^d-1<=m
False
Prelude> m<2^d
True

So for the ghc decodeFloat, when operating on a NaN, the
specifications of decodeFloat are almost completely unsatisfied.  On
the plus side, at least it's true that m<b^d, so that's one out of
three.  I suppose the problem is that quickcheck was developed only
after the standard was written...

David
```