# [Haskell-cafe] attoparsec double precision, quickCheck and aeson

Doug McIlroy doug at cs.dartmouth.edu
Wed Jun 6 15:20:34 CEST 2012

```> Date: Tue, 5 Jun 2012 10:25:26 -0700
> From: Warren Harris <warrensomebody at gmail.com>
>
> On Jun 5, 2012, at 9:57 AM, Johan Tibell wrote:
>
>> I don't think applying == to something that contains floating point
>> values at the leaves makes much sense. You want some approxEq function
>> that uses approximate equality on floating point value or you want to
>> equality function that ignores the floating point values. Probably not
>> the answer you like, but I don't know how to define Eq in a robust way
>> for types that include floating point values.
>
> I buy that in general for comparing floats (those that result from arithmetic operations), but this is a case where attoparsec's parser is munging the value. I would like to have a law that says "parse . print == id" ... which is why this seems more like a bug than the usual floating point concerns. This law seems to hold for haskell's double parser: quickCheck (\d -> read (show d) == d)
>
> Date: Tue, 5 Jun 2012 10:51:08 -0700
> From: "Bryan O'Sullivan" <bos at serpentine.com>
>
> If you need the full precision, use rational instead. The double parser is
> there because parsing floating point numbers is often a bottleneck, and
> double intentionally trades speed for precision.

If I understand the intended meaning of "parse" correctly, what's at
issue is decimal-to-binary conversion. It is hard to defend sloppy
answers for such a fundamental operation. The recommendation of
rational calculation makes little sense for most floating-point
computation, which approximates irrationals. The necessary
imprecision, though, does not justify sloppiness--and especially
not sloppy tests.

It's worth noting that a "law" of input being inverse
to output must fail, though rarely. Different granularity of
the two bases means that there must exist cases where adjacent
values in one base convert to the same value in the other.
(Conceivably the specialization to parse.print could hold
for some hardware. Does anybody know whether the
wish is actually hopeless?)

Last I looked (admittedly quite a while ago), the state of
the art was strtod in http://www.netlib.org/fp/dtoa.c.
(Alas, dtoa.c achieves calculational perfection via a
murmuration of #ifdefs.)

It's disheartening to hear that important Haskell code has
needlessly fallen from perfection--perhaps even deliberately.

Doug McIlroy

```