views:

404

answers:

3

I'd like to play with those traps for educational purpose.

A common problem with the default behavior in numerical calculus is that we "miss" the Nan (or +-inf) that appeared in a wrong operation. Default behavior is propagation through the computation, but some operation (like comparisons) break the chain and loose the Nan, and the rest of the treatment continue without acknowledging the singularity in previous steps of the algorithm.

Sometimes we have ways to react to this kind of event : prolongating a function ("0/0 = 12 in my case"), or in time-domain simulation throwing the step away and trying with other settings (like the predictor, the step size or whatever).

So here is my question : do you know languages that expose the IEEE754 traps to the developer ? I don't feel like messing with ASM for that.

A: 

C and probably most languages derived from it like C++ or python (may be indirect access though). It's probably reasonable to expect that low level languages will have such support.

See http://www.math.utah.edu/~beebe/software/ieee/#c-notes which has numerous scripts and notes on working with IEEE 754 numbers. In particular http://www.math.utah.edu/~beebe/software/ieee/ofl.c">of1.c deals with floating point exceptions. Finally, from the source http://grouper.ieee.org/groups/754/reading.html which includes a bunch of useful info.

Dana the Sane
Can you be a little bit more specific please ?I could not find this in the documentation, I found how to manipulate the flags, but not how to set a trap:http://www.opengroup.org/onlinepubs/000095399/basedefs/fenv.h.html
nraynaud
Updated with links.
Dana the Sane
Thanks for the links.After looking at the C program (I think I looked well, but in all this preprocessor noise it's difficult to be affirmative), I don't see traps exposed as such. I only see flag manipulation.The SIG_FPE handler seems to be a spacial case for one platform.
nraynaud
+1  A: 

As far as I know, you have two choices for floating point exception handling in C and C++:

First, if you disable/mask floating point exceptions (which most environments do by default), you can see whether any floating point exceptions have occurred by calling fetestexcept. fetestexcept isn't available in Visual C++, but you can steal the MinGW Runtime's implementation easily enough. (It's in the public domain.) Once an exception has been flagged, it's not cleared until you call feclearexcept, so you can call fetestexcept at the end of a series of calculations to see if any of them raised an exception. This doesn't give you the traps that you asked for, but it does let you test if problems like NaN or +/-inf have occurred and react as needed.

Second, you can enable/unmask floating point exceptions by calling feenableexcept in Linux or _controlfp in Windows. How the operating system handles a processor-generated floating point exception depends on your operating system.

  • In Linux, the OS sends a SIGFPE signal, so you can install a signal handler to catch that and set a flag that tells your routine to react appropriately.
  • In Windows, the OS invokes Structured Exception Handling to convert the processor exception into a language exception that you can catch using a __try / __catch block in C or try / catch block in C++.
  • Update: For Mac OS X, as described in this answer, you should be able to enable/unmask exceptions using _MM_SET_EXCEPTION_MASK from xmmintrin.h, and as long as you use the default compiler options (i.e., don't disable SSE), you should be able to catch exceptions using SIGFPE.

(I've written a bit more on this and other floating point issues in C and C++ in this blog posting if you're curious.)

Josh Kelley
That's a good point, I was just playing with this, and since I feel lucky, I'm on a mac with 2 platform specifics problems :http://www.gnu.org/software/hello/manual/gnulib/feenableexcept.htmlhttp://lists.apple.com/archives/Darwin-dev/2006/Mar/msg00102.html
nraynaud
The info in the link I added seems to work for me in my limited testing.
Josh Kelley
Thanks for the mac OS X link, this makes a very irregular handling, since it works only for sse types (float and double) but not for long double, which is x87 specific.Moreover, enabling exceptions does it for the whole process, not for the current thread, which makes working with it difficult.
nraynaud
Good points. I don't know of anything else you can try, sorry. For my own knowledge, since I'm far from an expert on floating point, is there any particular reason that using fetestexcept to check for exceptions after the fact won't work?
Josh Kelley
Imagine you are trying to invert a big matrix, you would like to get out of the big computation as soon as it's clear it is not invertible. Carrying it until the end would be a waste of time.
nraynaud
A: 

I'm unsure of what the standard is, but I can tell you what I've seen from experience as it may be useful. I have coded in C++ and NaN's are sometimes my worst nightmare. They appear silently and propogate through the computation all the way to the end, until I just have useless output. I've often had to create additional code to specifically detect the NaN-causing circumstances. I'm using Visual C++ 2008, so I expect that it'd be following the IEEE standard in this manner.

Ray Hidayat
yes it's totally standard. But the standard define 3 levels of use 1) propagating NaN and infs 2) flags you can check 3) software traps. Maybe your usage is too advanced for keeping the default behavior.
nraynaud