Platform-dependent behaviour with functions on NaN
In Haskell, the behaviour of functions on floating-point values which are NaN can be platform dependent. On "SunOS sun 5.9 Generic_118558-09 sun4u sparc SUNW,Sun-Blade-1500": Prelude> ceiling (0/0) 359538626972463141629054847463408713596141135051689993197834953606314521 560057077521179117265533756343080917907028764928468642653778928365536935 093407075033972099821153102564152490980180778657888151737016910267884609 166473806445896331617118664246696549595652408289446337476354361838599762 500808052368249716736 On Windows: Prelude> ceiling (0/0) -26965397022934738615939577861835371004269654684134598591014512173659901 370825144469906271598361130403168017081980709003648818465322162493373927 114595921118656665184013729822791445332940186914117917962442812750865325 722602351369432221086966581124085574502576602687944735992086890771957445 7253034494436336205824 Both machines use the binary distributions of GHC 6.4.1. In our production code, this error (which is actually an error in our program) occured inside a quite complex expression which can be simplified to max 0 (ceiling (0/0)). On Windows, we did not recognize the error in the program, because the complex expression just returned 0. On Solaris, the complex expression returned this large number (which represents in the application "the number of CPUs needed in a certain device" ;-) We develop Haskell programs on Windows and run them in production on Sparc with Solaris. It seems that we have to run special regression tests testing for differences between Sparc Solaris and Windows. The Haskell 98 report http://www.haskell.org/onlinereport/basic.html#sect6.4 states: "The results of exceptional conditions (such as overflow or underflow) on the fixed-precision numeric types are undefined; an implementation may choose error (_|_, semantically), a truncated value, or a special value such as infinity, indefinite, etc." There has been some discussion six years ago and nearly two years ago: http://blog.gmane.org/gmane.comp.lang.haskell.glasgow.user/month=2004080 1 Is there a chance to - properly define the behaviour of functions depending on the function properFraction for values like NaN, Infinity, ...? - get an implementation of this in GHC which computes the same results for all platforms? Perhaps the function properFraction could raise an exception in case of isNaN and isInfinity? Other languages are more portable. E.g., for Java, these cases are defined. http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.h tml#9249 states: "All numeric operations with NaN as an operand produce NaN as a result." Tim
[ CC'ing glasgow-haskell-users@haskell.org ] Geisler, Tim (EXT) wrote:
In Haskell, the behaviour of functions on floating-point values which are NaN can be platform dependent.
On "SunOS sun 5.9 Generic_118558-09 sun4u sparc SUNW,Sun-Blade-1500": Prelude> ceiling (0/0) 359538626972463141629054847463408713596141135051689993197834953606314521560057077521179117265533756343080917907028764928468642653778928365536935093407075033972099821153102564152490980180778657888151737016910267884609166473806445896331617118664246696549595652408289446337476354361838599762500808052368249716736
On Windows:
Prelude> ceiling (0/0) -269653970229347386159395778618353710042696546841345985910145121736599013708251444699062715983611304031680170819807090036488184653221624933739271145959211186566651840137298227914453329401869141179179624428127508653257226023513694322210869665811240855745025766026879447359920868907719574457253034494436336205824
Both machines use the binary distributions of GHC 6.4.1.
I assure you this isn't intentional. In fact, I'm not sure why Sparc should be any different. I don't have any Sparc machines to test on, and on all the platforms I have access to here I get a consistent answer (the same as the Windows answer you quoted above). As far as I can tell, GHC is just using the Prelude definitions of the functions involved, there is no platform-specific code at the Haskell level. What does 'decodeFloat (0/0)' return on your Sparc?
There has been some discussion six years ago and nearly two years ago: http://blog.gmane.org/gmane.comp.lang.haskell.glasgow.user/month=20040801
Is there a chance to - properly define the behaviour of functions depending on the function properFraction for values like NaN, Infinity, ...?
This is a question for haskell-prime, to be answered by people who know more about floating point than I do...
- get an implementation of this in GHC which computes the same results for all platforms?
I would certainly hope so, if we can find the source of the discrepancy and devise a fix.
Perhaps the function properFraction could raise an exception in case of isNaN and isInfinity?
Sounds plausible. Does anyone have any objections? Cheers, Simon
On Thu, Apr 13, 2006 at 04:24:45PM +0100, Simon Marlow wrote:
- get an implementation of this in GHC which computes the same results for all platforms?
I would certainly hope so, if we can find the source of the discrepancy and devise a fix.
I'd just point out that C compilers don't allow you to get the same results on all platforms, and doing so in general requires slow floating point arithmetic, mostly because there don't seem to be any platforms in production that implement IEEE arithmetic. I wouldn't like the standard (or compiler) to enforce special checks every time we do floating point arithmetic. It would be nice, perhaps, as an option, but that would (as I understand it) be considerable effort and a considerable slowdown, for relatively little benefit, which is why gcc hasn't bothered with it either. I imagine that if producing reproducible arithmetic is beyond the means of the gcc development team, it's also beyond that of the ghc development team, especially since you can always get reproducible arithmetic (I presume) by using Rationals. -- David Roundy
Yeah, I think it boils down to different representations of NaN on different platform. I guess I forgot to test for NaN when I wrote (the C code for) decodeFloat. It should generate some consistent result. On the other hand, if you have code that possible divides by 0 and don't check for it, well... It would be nice if Haskell allowed you to turn on signalling NaNs. -- Lennart Geisler, Tim (EXT) wrote:
In Haskell, the behaviour of functions on floating-point values which are NaN can be platform dependent.
On "SunOS sun 5.9 Generic_118558-09 sun4u sparc SUNW,Sun-Blade-1500": Prelude> ceiling (0/0) 359538626972463141629054847463408713596141135051689993197834953606314521560057077521179117265533756343080917907028764928468642653778928365536935093407075033972099821153102564152490980180778657888151737016910267884609166473806445896331617118664246696549595652408289446337476354361838599762500808052368249716736
On Windows:
Prelude> ceiling (0/0) -269653970229347386159395778618353710042696546841345985910145121736599013708251444699062715983611304031680170819807090036488184653221624933739271145959211186566651840137298227914453329401869141179179624428127508653257226023513694322210869665811240855745025766026879447359920868907719574457253034494436336205824
Both machines use the binary distributions of GHC 6.4.1.
In our production code, this error (which is actually an error in our program) occured inside a quite complex expression which can be simplified to max 0 (ceiling (0/0)). On Windows, we did not recognize the error in the program, because the complex expression just returned 0. On Solaris, the complex expression returned this large number (which represents in the application "the number of CPUs needed in a certain device" ;-)
We develop Haskell programs on Windows and run them in production on Sparc with Solaris. It seems that we have to run special regression tests testing for differences between Sparc Solaris and Windows.
The Haskell 98 report http://www.haskell.org/onlinereport/basic.html#sect6.4 states: "The results of exceptional conditions (such as overflow or underflow) on the fixed-precision numeric types are undefined; an implementation may choose error (/_|_/, semantically), a truncated value, or a special value such as infinity, indefinite, etc."
There has been some discussion six years ago and nearly two years ago: http://blog.gmane.org/gmane.comp.lang.haskell.glasgow.user/month=20040801
Is there a chance to - properly define the behaviour of functions depending on the function properFraction for values like NaN, Infinity, ...? - get an implementation of this in GHC which computes the same results for all platforms?
Perhaps the function properFraction could raise an exception in case of isNaN and isInfinity?
Other languages are more portable. E.g., for Java, these cases are defined. http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#... states: "All numeric operations with NaN as an operand produce NaN as a result."
Tim
------------------------------------------------------------------------
_______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
I don't know if it would help, but PLT Scheme has been thru this and Matthew Flatt has a nice test suite that you can see here: http://svn.plt-scheme.org/plt/trunk/collects/tests/mzscheme/number.ss To help read the code, when you see something like: (test a b c ...) that is the same thing as applying the operator "b" to the arguments "c ..." and then comparing the result to "a" (and expecting it to match). A variation (defined in this file) is test-nan.0 that takes the "b" and "c"s above, and passes not-a-number along as the expected result. Sure enough, the bug below would have been caught by the test suite, because it contains: (test-nan.0 ceiling +nan.0) One could probably automate a translation of the test suite to Quickcheck with some Emacs macros or (god forbid!) a Scheme program. :) Anyways, if you do want to use those test cases, I'm happy to explain any Schemeisms you find in there. Just a Schemer's $0.02, Robby At Fri, 14 Apr 2006 10:04:51 -0400, Lennart Augustsson wrote:
Yeah, I think it boils down to different representations of NaN on different platform. I guess I forgot to test for NaN when I wrote (the C code for) decodeFloat. It should generate some consistent result. On the other hand, if you have code that possible divides by 0 and don't check for it, well... It would be nice if Haskell allowed you to turn on signalling NaNs.
-- Lennart
Geisler, Tim (EXT) wrote:
In Haskell, the behaviour of functions on floating-point values which are NaN can be platform dependent.
On "SunOS sun 5.9 Generic_118558-09 sun4u sparc SUNW,Sun-Blade-1500": Prelude> ceiling (0/0)
359538626972463141629054847463408713596141135051689993197834953606314521560057077521179117265 533756343080917907028764928468642653778928365536935093407075033972099821153102564152490980180 778657888151737016910267884609166473806445896331617118664246696549595652408289446337476354361 838599762500808052368249716736
On Windows:
Prelude> ceiling (0/0) -
269653970229347386159395778618353710042696546841345985910145121736599013708251444699062715983 611304031680170819807090036488184653221624933739271145959211186566651840137298227914453329401 869141179179624428127508653257226023513694322210869665811240855745025766026879447359920868907 719574457253034494436336205824
Both machines use the binary distributions of GHC 6.4.1.
In our production code, this error (which is actually an error in our program) occured inside a quite complex expression which can be simplified to max 0 (ceiling (0/0)). On Windows, we did not recognize the error in the program, because the complex expression just returned 0. On Solaris, the complex expression returned this large number (which represents in the application "the number of CPUs needed in a certain device" ;-)
We develop Haskell programs on Windows and run them in production on Sparc with Solaris. It seems that we have to run special regression tests testing for differences between Sparc Solaris and Windows.
The Haskell 98 report http://www.haskell.org/onlinereport/basic.html#sect6.4 states: "The results of exceptional conditions (such as overflow or underflow) on the fixed-precision numeric types are undefined; an implementation may choose error (/_|_/, semantically), a truncated value, or a special value such as infinity, indefinite, etc."
There has been some discussion six years ago and nearly two years ago: http://blog.gmane.org/gmane.comp.lang.haskell.glasgow.user/month=20040801
Is there a chance to - properly define the behaviour of functions depending on the function properFraction for values like NaN, Infinity, ...? - get an implementation of this in GHC which computes the same results for all platforms?
Perhaps the function properFraction could raise an exception in case of isNaN and isInfinity?
Other languages are more portable. E.g., for Java, these cases are defined. http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#... states: "All numeric operations with NaN as an operand produce NaN as a result."
Tim
------------------------------------------------------------------------
_______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
_______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
participants (5)
-
David Roundy -
Geisler, Tim (EXT) -
Lennart Augustsson -
Robby Findler -
Simon Marlow