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

Date: Tue, 5 Jun 2012 10:25:26 -0700 From: Warren Harris
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"
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

On Wed, Jun 6, 2012 at 6:20 AM, Doug McIlroy
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.)
That was indeed the state of the art for about three decades, until Florian Loitsch showed up in 2010 with an algorithm that is usually far faster: http://www.serpentine.com/blog/2011/06/29/here-be-dragons-advances-in-proble... Unfortunately, although I've written Haskell bindings to his library, said library is written in C++, and our FFI support for C++ libraries is negligible and buggy. As a result, that code is disabled by default. It's disheartening to hear that important Haskell code has
needlessly fallen from perfection--perhaps even deliberately.
Indeed (and yes, it's deliberate). If I had the time to spare, I'd attempt to fix the situation by porting Loitsch's algorithm to Haskell or C, but either one would be a lot of work - the library is 5,600 lines of tricky code.

Bryan, do you remember what the issue is with C++ in this case? I
thought, adding a wrapper with extern "C" definitions should do the
trick for simpler libraries (as this one seems to be). Is the
interaction with the memory allocator the issue? Linker flags?
On 11 June 2012 06:38, Bryan O'Sullivan
On Wed, Jun 6, 2012 at 6:20 AM, Doug McIlroy
wrote: 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.)
That was indeed the state of the art for about three decades, until Florian Loitsch showed up in 2010 with an algorithm that is usually far faster: http://www.serpentine.com/blog/2011/06/29/here-be-dragons-advances-in-proble...
Unfortunately, although I've written Haskell bindings to his library, said library is written in C++, and our FFI support for C++ libraries is negligible and buggy. As a result, that code is disabled by default.
It's disheartening to hear that important Haskell code has needlessly fallen from perfection--perhaps even deliberately.
Indeed (and yes, it's deliberate). If I had the time to spare, I'd attempt to fix the situation by porting Loitsch's algorithm to Haskell or C, but either one would be a lot of work - the library is 5,600 lines of tricky code.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Push the envelope. Watch it bend.

On Mon, Jun 11, 2012 at 10:50 AM, Thomas Schilling
Bryan, do you remember what the issue is with C++ in this case? I thought, adding a wrapper with extern "C" definitions should do the trick for simpler libraries (as this one seems to be). Is the interaction with the memory allocator the issue? Linker flags?
It's specific to ghci, whose object file loader fails to call C++ static initializers. In the case of the double-conversion library, this means that static read-only arrays that it assumes to contain valid data are full of junk. You can join in the fun over at http://hackage.haskell.org/trac/ghc/ticket/5289

On Mon, Jun 11, 2012 at 10:57 AM, Bryan O'Sullivan
In the case of the double-conversion library, this means that static
read-only arrays that it assumes to contain valid data are full of junk. You can join in the fun over at http://hackage.haskell.org/trac/ghc/ticket/5289
Oops, that bug is not actually relevant to this case.
participants (3)
-
Bryan O'Sullivan
-
Doug McIlroy
-
Thomas Schilling