[Haskell-cafe] floating point operations and representation

Don Stewart dons at galois.com
Wed Mar 12 21:27:59 EDT 2008


quark:
> I have two questions about using the Double data type and the
> operations in the Floating typeclass on a computer that uses IEEE
> floating point numbers.
> 
> I notice that the Floating class only provides "log" (presumably log
> base 'e') and "logBase" (which, in the latest source that I see for
> GHC is defined as "log y / log x").  However, in C, the "math.h"
> library provides specific "log2" and "log10" functions, for extra
> precision.  A test on IEEE computers (x86 and x86-64), shows that for
> a range of 64-bit "double" values, the answers in C do differ (in the
> last bit) if you use "log2(x)" and "log10(x)" versus "log (x) /
> log(2)" and "log(x) / log(10)".

You could consider binding directly to the C functions, if needed,

    {-# OPTIONS -fffi -#include "math.h" #-}

    import Foreign.C.Types

    foreign import ccall unsafe "math.h log10"
        c_log10 :: CDouble -> CDouble

    log10 :: Double -> Double
    log10 x = realToFrac (c_log10 (realToFrac x))

    main = mapM_ (print . log10) [1..10]

Also, is there any difference if you compile with -fvia-C or -fexcess-precision
 (or both)?
  
> My second question is how to get at the IEEE bit representation for a
> Double.  I am already checking "isIEEE n" in my source code (and
> "floatRadix n == 2").  So I know that I am operating on hardware that
> implements floating point numbers by the IEEE standard.  I would like
> to get at the 64 bits of a Double.  Again, I can convert to a CDouble
> and use the FFI to wrap a C function which casts the "double" to a
> 64-bit number and returns it.  But I'm wondering if there's not a
> better way to do this natively in Haskell/GHC (perhaps some crazy use
> of the Storable typeclass?).  Or if someone has already tackled this
> problem with FFI, that would be interesting to know.

The FFI is a good way. You can just bind to any C code linked with your code.
There's some similar code for messing with doubles and longs in the
mersenne-random package you might be able to use for inspiration:

    http://code.haskell.org/~dons/code/mersenne-random/

-- Don


More information about the Haskell-Cafe mailing list