[Haskell-cafe] ANN: ieee version 0.7

John Millikin jmillikin at gmail.com
Tue Sep 21 13:46:02 EDT 2010

On Mon, Sep 20, 2010 at 22:11, Conrad Parker <conrad at metadecks.org> wrote:
> I've been using unsafeCoerce:
> getFloat64be :: Get Double
> getFloat64be =
>    do n <- getWord64be
>       return (unsafeCoerce n :: Double)
> putFloat64be :: Double -> Put
> putFloat64be n = putWord64be (unsafeCoerce n :: Word64)
> but only tested it with quickcheck -- it passes about 10^7 checks,
> comparing roundtrips in combinatrion with the previous
> data-binary-ieee754 versions. However could that sometimes behave
> incorrectly?

QuickCheck only generates a subset of possible floating point values;
when I tested unsafeCoerce, it sometimes gave incorrect results when
dealing with edge cases like signaling NaNs.

> Should the d-b-iee754-0.4.2 versions with castPtr etc. be even faster?

It should be slightly slower, but not nearly as slow as the
bitfield-based parsing.

On Tue, Sep 21, 2010 at 07:10, Daniel Fischer <daniel.is.fischer at web.de> wrote:
> And I'd expect it to be a heck of a lot faster than the previous
> implementation. Have you done any benchmarks?

Only very rough ones -- a few basic Criterion checks, but nothing
extensive. Numbers for put/get of 64-bit big-endian:

                   getWord   getFloat   putWord   putFloat
Bitfields (0.4.1)    59 ns    8385 ns   1840 ns   11448 ns
poke/peek (0.4.2)    59 ns     305 ns   1840 ns     744 ns
unsafeCoerce         59 ns      61 ns   1840 ns     642 ns

Note: I don't know why the cast-based versions can put a Double faster
than a Word64; Float is (as expected) slower than Word32. Some
special-case GHC optimization?

> One problem I see with both, unsafeCoerce and poke/peek is endianness.
> Will the bit-pattern of a double be interpreted as the same uint64_t on
> little-endian and on big-endian machines? In other words, is the byte order
> for doubles endianness-dependent too?
> If yes, that's fine, if no, it would break between machines of different
> endianness.

Endianness only matters when marshaling bytes into a single value --
Data.Binary.Get/Put handles that. Once the data is encoded as a Word,
endianness is no longer relevant.

More information about the Haskell-Cafe mailing list