Exception for NaN

How do I make my program stop whenever it gets somewhere NaN as a result during a calculation? If there is no appropriate flag for ghc maybe there exist flags for C to use in optc. I don't want NaN to propagate, it is merely stupid, it should be terminated.

On 2011-05-12 21:14 +0400, Grigory Sarnitskiy wrote:
How do I make my program stop whenever it gets somewhere NaN as a result during a calculation? If there is no appropriate flag for ghc maybe there exist flags for C to use in optc.
Under IEEE 754 floating point arithmetic, any operation which produces a quiet NaN from non-NaN inputs will also raise the "invalid" floating point exception. Unfortunately, GHC provides no support whatsoever for IEEE 754 floating point exceptions. You may neverthelesss be able to hack it, assuming appropriate hardware and software support. The result will not be portable. For example, the GNU C library provides the feenableexcept function. Completely untested, but on such systems, if you call feenableexcept(FE_INVALID) from C at the start of your program, your program should receive SIGFPE whenever the "invalid" floating point exception is raised by a floating point operation. This will likely cause the program to terminate. Other systems may provide a similar mechanism. Whether this hack actually works properly with GHC's runtime system is another issue entirely. Furthermore, GHC may perform program transformations that affect the generation of these exceptions in a negative way.
I don't want NaN to propagate, it is merely stupid, it should be terminated.
NaN propagation is not stupid. Frequently, components of a computation that end up being NaN turn out to be irrelevant at a later point, in which case the NaNs can be discarded. Cheers, -- Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)

On 12/05/2011 19:41, Nick Bowler wrote:
On 2011-05-12 21:14 +0400, Grigory Sarnitskiy wrote:
I don't want NaN to propagate, it is merely stupid, it should be terminated.
NaN propagation is not stupid. Frequently, components of a computation that end up being NaN turn out to be irrelevant at a later point, in which case the NaNs can be discarded.
Unfortunately, if a NaN reaches a comparison operation, it can lead to an end result that doesn't contain NaNs, but was still influenced by one. Ganesh

On Friday 13 May 2011 01:19:52, Ganesh Sittampalam wrote:
On 12/05/2011 19:41, Nick Bowler wrote:
On 2011-05-12 21:14 +0400, Grigory Sarnitskiy wrote:
I don't want NaN to propagate, it is merely stupid, it should be terminated.
NaN propagation is not stupid. Frequently, components of a computation that end up being NaN turn out to be irrelevant at a later point, in which case the NaNs can be discarded.
Unfortunately, if a NaN reaches a comparison operation, it can lead to an end result that doesn't contain NaNs, but was still influenced by one.
Ganesh
For example: Prelude Data.List> maximum [0,-1,0/0,-5,-6,-3,0/0,-2] 0.0 Prelude Data.List> minimum [0,-1,0/0,-5,-6,-3,0/0,-2] -2.0 Prelude Data.List> sort [0,-1,0/0,-5,-6,-3,0/0,-2] [-6.0,-5.0,-2.0,NaN,-3.0,NaN,-1.0,0.0] As usual, when dealing with floating point numbers, you have to know what you're doing. There are situations where the appearence of NaNs is harmless, in others, they're poisonous.

On Thu, May 12, 2011 at 5:50 PM, Daniel Fischer < daniel.is.fischer@googlemail.com> wrote:
Prelude Data.List> maximum [0,-1,0/0,-5,-6,-3,0/0,-2] 0.0 Prelude Data.List> minimum [0,-1,0/0,-5,-6,-3,0/0,-2] -2.0 Prelude Data.List> sort [0,-1,0/0,-5,-6,-3,0/0,-2] [-6.0,-5.0,-2.0,NaN,-3.0,NaN,-1.0,0.0]
Wow, that's the best example of NaN poison I've seen. Luke

On Fri, May 13, 2011 at 4:48 PM, Luke Palmer
On Thu, May 12, 2011 at 5:50 PM, Daniel Fischer
wrote: Prelude Data.List> maximum [0,-1,0/0,-5,-6,-3,0/0,-2] 0.0 Prelude Data.List> minimum [0,-1,0/0,-5,-6,-3,0/0,-2] -2.0 Prelude Data.List> sort [0,-1,0/0,-5,-6,-3,0/0,-2] [-6.0,-5.0,-2.0,NaN,-3.0,NaN,-1.0,0.0]
Wow, that's the best example of NaN poison I've seen.
Somewhat less impressive, but would everyone expect these functions to be equivalent up to performance characteristics? f :: (Eq a) => [a] -> [a] f = nub . concatMap (replicate 5) g :: (Eq a) => [a] -> [a] g = nub If the answer that springs to mind is "yes, for any well-behaved instance of Eq", well... Bonus question: Should this function ever return False? h :: (Ord a) => a -> a -> Bool h x y = case compare x y of GT -> x > y EQ -> x == y LT -> x < y - C.

On Friday 13 May 2011 23:41:34, Casey McCann wrote:
On Fri, May 13, 2011 at 4:48 PM, Luke Palmer
wrote: On Thu, May 12, 2011 at 5:50 PM, Daniel Fischer
wrote: Prelude Data.List> maximum [0,-1,0/0,-5,-6,-3,0/0,-2] 0.0 Prelude Data.List> minimum [0,-1,0/0,-5,-6,-3,0/0,-2] -2.0 Prelude Data.List> sort [0,-1,0/0,-5,-6,-3,0/0,-2] [-6.0,-5.0,-2.0,NaN,-3.0,NaN,-1.0,0.0]
Wow, that's the best example of NaN poison I've seen.
Somewhat less impressive, but would everyone expect these functions to be equivalent up to performance characteristics?
f :: (Eq a) => [a] -> [a] f = nub . concatMap (replicate 5)
g :: (Eq a) => [a] -> [a] g = nub
If the answer that springs to mind is "yes, for any well-behaved instance of Eq", well...
My answer is "Yes, for any well-behaved instance of Eq or for lists of Float/Double not containing any NaN (and similar caveats for types using these)" - other types with special cases may exist, none springs to mind. It's (hopefully) well-known that the Eq and Ord instances of Double and Float aren't well-behaved in the presence of NaNs, but you can't have consistent instances which do what you expect on non-NaN values. Not having Eq and Ord instances for Double and Float would be extremely inconvenient (too inconvenient to seriously consider, I think), so one can a) do what's done now b) make NaNs an error c) come up with a brilliant solution. While c) has not been achieved, I consider a) the least evil option.
Bonus question: Should this function ever return False?
h :: (Ord a) => a -> a -> Bool h x y = case compare x y of GT -> x > y EQ -> x == y LT -> x < y
Not for well-behaved Ord instances, nor for Double and Float, provided neither argument is NaN (and derived cases).
- C.

Daniel Fischer
Not having Eq and Ord instances for Double and Float would be extremely inconvenient (too inconvenient to seriously consider, I think), so one can a) do what's done now b) make NaNs an error c) come up with a brilliant solution.
Maybe not terribly brilliant, but wouldn't it improve things slightly if NaN was considered less or greater than any other value (possibly excluding infinities)? -k -- If I haven't seen further, it is by standing in the footprints of giants

On Sat, May 14, 2011 at 9:14 AM, Ketil Malde
Maybe not terribly brilliant, but wouldn't it improve things slightly if NaN was considered less or greater than any other value (possibly excluding infinities)?
It would improve things in the sense of giving well-behaved instances for Eq and Ord, yes. It would not improve things in the sense that it would violate the IEEE floating point spec. The real issue here, I think, is that we're expecting Ord to serve two different purposes: Sometimes a logical ordering on the type according to its semantics, sometimes an essentially arbitrary ordering for the purpose of structuring data (e.g., for use as a key in Data.Map). For most types, either there is no meaningful semantic ordering or the obvious ordering serves both purposes. In the case of floating point values, the semantics of the type are that it is not fully ordered and thus arguably shouldn't be an instance of Ord at all--in particular, there's nothing "compare" can correctly return when given NaN. An arbitrary ordering, on the other hand, could be established easily so that things like Data.Map would work correctly, but only by breaking the semantics of the type (even more than is already the case due to things like "compare", that is). The current situation is an awkward compromise that mostly works and does what you want in most cases except when you get weird silent bugs due to, say, minimum returning a non-minimal value, or Data.Map.lookup returning Nothing for a key that actually exists, or whatever else. Alternative approaches are generally going to be either horribly inconvenient, cause as many problems as they solve, or require massively disruptive changes to the standard library. In short, file this one on the shelf next to "why is Num designed the way it is?" - C.

Casey McCann
It would improve things in the sense of giving well-behaved instances for Eq and Ord, yes. It would not improve things in the sense that it would violate the IEEE floating point spec.
I'm not intimately familiar with IEEE 754, but in any case we'd be in good company: R typically lets you select to sort NaNs as greater or less than any other values, and sorts non-NaN values correctly also in the presence of NaNs, I think. At any rate, I think we already violate the spec by not having the required "unordered" result for comparisons, and just treating every comparison involving a NaN as "GT". I don't think considering NaN as e.g. less than -Inf would violate the spec *more*.
The current situation is an awkward compromise that mostly works and does what you want in most cases except when you get weird silent bugs due to, say, minimum returning a non-minimal value, or Data.Map.lookup returning Nothing for a key that actually exists, or whatever else.
This sounds pretty bad, until you consider that you don't even have proper equality, so using floating point values as keys in a Map is already asking for trouble. But I would like sorting to work more consistently. But I guess it is a matter of lipstick on a pig... -k -- If I haven't seen further, it is by standing in the footprints of giants

On Mon, May 16, 2011 at 3:39 AM, Ketil Malde
I'm not intimately familiar with IEEE 754, but in any case we'd be in good company: R typically lets you select to sort NaNs as greater or less than any other values, and sorts non-NaN values correctly also in the presence of NaNs, I think.
That's interesting. I wasn't aware of any deliberate breaks with the standard, and it being R specifically is particularly striking. Regardless, sticking to the standard behavior is a sensible default. Floating point values are confusing enough to most people without being inconsistent as well.
At any rate, I think we already violate the spec by not having the required "unordered" result for comparisons, and just treating every comparison involving a NaN as "GT". I don't think considering NaN as e.g. less than -Inf would violate the spec *more*.
Well, it'd be insult to injury. If memory serves me, the standard behavior is that NaN =/= NaN evaluates as true, and every other comparison evaluates as false. This is fine (other than not being the expected behavior of Eq and Ord instances) except, yes, the "compare" function, which assumes a complete ordering and thus cannot return a correct result. The slightly more correct thing to do would be having "compare" throw an exception on NaN but I wonder if that wouldn't just cause a different set of headaches. Why don't we have a partial ordering type class, anyway? Lack of obvious utility, I suppose.
This sounds pretty bad, until you consider that you don't even have proper equality, so using floating point values as keys in a Map is already asking for trouble. But I would like sorting to work more consistently.
But I guess it is a matter of lipstick on a pig...
How so? Equality on floating point values other than NaN works just fine and behaves as expected. It's just that they violate all sorts of algebraic laws when arithmetic is involved so sequences of operations that should be equivalent aren't, in ways that are highly dependent on the values being operated on. What it mostly boils down to is that Haskell makes you expect things to be simple and consistent and clearly-defined and floating point values just simply aren't. They're a messy compromise for the sake of computational speed. If you want numbers that act like they should, there's always Integer and Rational. - C.

On 16.05.2011 22:51, Casey McCann wrote:
How so? Equality on floating point values other than NaN works just fine and behaves as expected. It's just that they violate all sorts of algebraic laws when arithmetic is involved so sequences of operations that should be equivalent aren't, in ways that are highly dependent on the values being operated on.
Well not nessesarily. FPU may store intermediate values with more bits
than in memory representation. When value is moved to memory from
registers it loses some accuracy. So when you compare doubles for
equality you may get true or false depending on compiler optimizations.
For example following C program prints 0 if compiled without
optimitizations and 1 with -O2. (gcc 4.6.1)
#include

On Tuesday 17 May 2011 00:22:02, Alexey Khudyakov wrote:
On 16.05.2011 22:51, Casey McCann wrote:
How so? Equality on floating point values other than NaN works just fine and behaves as expected. It's just that they violate all sorts of algebraic laws when arithmetic is involved so sequences of operations that should be equivalent aren't, in ways that are highly dependent on the values being operated on.
Well not nessesarily. FPU may store intermediate values with more bits than in memory representation. When value is moved to memory from registers it loses some accuracy. So when you compare doubles for equality you may get true or false depending on compiler optimizations.
Yes. Well, sophistically, no - in that case, you're not comparing doubles ;) In theory, you have a well-behaved equality and ordering for IEEE-754 floating-point values which aren't NaNs or -0.0 (that too messes some things up). In practice, however, you're often not dealing with 32-bit floats or 64-bit doubles but with what the FPU uses internally and that can also mess things up big time.
For example following C program prints 0 if compiled without optimitizations
Not necessarily. It will (almost certainly, I don't think gcc changed that) print 1 if it's compiled with the pessimisation -ffloat-store. And that's how one gets predictable behaviour of ==, < etc on floating point types, one must make sure that the operands of the comparison are fetched from memory and not from an FPU register. But that's not always easy.
and 1 with -O2. (gcc 4.6.1)
#include
#include #include int main(int argc, char** argv) { double y = 1; double x = tan(y); printf("%i\n", x == tan(y)); return 0; }
At any rate comparing floating points values for equality is asking for trouble.
I wouldn't go that far, but it's not something to do light-heartedly, there be dragons.

Casey McCann
At any rate, I think we already violate the spec by not having the required "unordered" result for comparisons, and just treating every comparison involving a NaN as "GT". I don't think considering NaN as e.g. less than -Inf would violate the spec *more*.
Well, it'd be insult to injury. If memory serves me, the standard behavior is that NaN =/= NaN evaluates as true, and every other comparison evaluates as false.
Okay. I was basing my argument on the Wikipedia page, and it seems to operate with a special "unordered" value for comparisons. You could still preserve this behavior and get sensible sorting behavior, by defining an Ord instance where you explicitly specify 'compare' along with the boolean operators, and base sorting on it, rather than them. But you'd still have inconsistencies, for instance: compare NaN _ = LT NaN < _ = False and minimum xs might not be the same as head (sort xs) And so on. (Of course, the current situation is that Prelude> minimum [1,2,0/0,3] 3.0 or, probably causing this: Prelude> max (0/0) 1 NaN Prelude> max 1 (0/0) 1.0 so again, perhaps there is room for improvement here?)
But I guess it is a matter of lipstick on a pig...
How so?
In that floating point values aren't going to be a pretty sight no matter what. It currently seems to violate almost every "obvious" invariant.
What it mostly boils down to is that Haskell makes you expect things to be simple and consistent and clearly-defined and floating point values just simply aren't.
Exactly. -k -- If I haven't seen further, it is by standing in the footprints of giants

On 16/05/2011, at 7:39 PM, Ketil Malde wrote:
I'm not intimately familiar with IEEE 754, but in any case we'd be in good company: R typically lets you select to sort NaNs as greater or less than any other values, and sorts non-NaN values correctly also in the presence of NaNs, I think.
sort(c(3,1,0/0,4,9)) [1] 1 3 4 9
The default behaviour is that missing (NA) and NaN values disappear from the result. There is a keyword parameter "na.last for controlling the treatment of NAs. If TRUE, missing values in the data are put last; if FALSE, they are put first; if NA, they are removed." The default value is NA. This is *not* a global property of comparison, it is specifically a run-time option of the "sort" function and the closely related "order" function, which returns a permutation vector. It is perfectly possible to provide such a feature in a specific function without violating the IEEE standard in any way, e.g. [x | x <- ys, isNaN x] ++ sort [x | x <- ys, not (isNaN x)]

On Saturday 14 May 2011 15:14:31, Ketil Malde wrote:
Daniel Fischer
writes: Not having Eq and Ord instances for Double and Float would be extremely inconvenient (too inconvenient to seriously consider, I think), so one can a) do what's done now b) make NaNs an error c) come up with a brilliant solution.
Maybe not terribly brilliant, but wouldn't it improve things slightly if NaN was considered less or greater than any other value (possibly excluding infinities)?
On the one hand yes, although it would be arbitrary and still produce undesirable results. On the other hand, the behaviour of (==), (<) etc. with NaNs that we have is what is specified in the Java Language Specification (section 4.2.3) and in the C99 standard (fn. 206, §17.12.14.2 and Appendix F.8.3), if I read that footnote correctly, that behaviour is required by IEC 60559 (by which comparisons involving a NaN must raise an 'invalid' exception). I expect that other languages specify the same behaviour, I think it's what the hardware does. So, is it worth changing? I'm not sure, but I tend towards thinking it's not, we'd need a better solution to make it worth the deviation.

On Sat, 14 May 2011 06:14:31 -0700, Ketil Malde
Daniel Fischer
writes: Not having Eq and Ord instances for Double and Float would be extremely inconvenient (too inconvenient to seriously consider, I think), so one can a) do what's done now b) make NaNs an error c) come up with a brilliant solution.
Maybe not terribly brilliant, but wouldn't it improve things slightly if NaN was considered less or greater than any other value (possibly excluding infinities)?
-k
It has a certain aesthetic appeal, but another concern of this approach would be non-termination. This is perhaps less of a concern for functional methodologies, but still a danger for algorithms that assume total ordering. -- -KQ

On 12/05/2011 06:14 PM, Grigory Sarnitskiy wrote:
How do I make my program stop whenever it gets somewhere NaN as a result during a calculation? If there is no appropriate flag for ghc maybe there exist flags for C to use in optc.
I don't want NaN to propagate, it is merely stupid, it should be terminated.
There is an isNaN function somewhere. You could make a newtype over Double which performs an isNaN after every operations and throws an exception if necessary...

On 5/12/11 3:22 PM, Andrew Coppin wrote:
There is an isNaN function somewhere.
N.B., on Hugs (September 2006), isNaN is flagrantly broken; so is isInfinite. I have a solution available[1], but alas, it seems unlikely to ever make its way back upstream. Moral: double check your compiler before trusting things like that. [1] http://hackage.haskell.org/packages/archive/logfloat/0.12.1/doc/html/Hugs-Re... -- Live well, ~wren

You can set and clear float exception flags directly with ieee-utils: http://hackage.haskell.org/packages/archive/ieee-utils/0.4.0/doc/html/Numeri... It looks like it needs a few tweaks to build with GHC 7, but even then that particularly module should still build fine. So before a complicated numeric calculation, clear the flags. Then, after forcing the result, check to see if any flags have been triggered and take appropriate action. This is more efficient than checking the flags after every operation anyway. Cheers, Sterl. On May 12, 2011, at 1:14 PM, Grigory Sarnitskiy wrote:
How do I make my program stop whenever it gets somewhere NaN as a result during a calculation? If there is no appropriate flag for ghc maybe there exist flags for C to use in optc.
I don't want NaN to propagate, it is merely stupid, it should be terminated.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (13)
-
Alexey Khudyakov
-
Andrew Coppin
-
Casey McCann
-
Daniel Fischer
-
Ganesh Sittampalam
-
Grigory Sarnitskiy
-
Ketil Malde
-
KQ
-
Luke Palmer
-
Nick Bowler
-
Richard O'Keefe
-
Sterling Clover
-
wren ng thornton