Dealing with Floating Point Exceptions

I cannot catch and handle floating point exception?

"Floating point exception" is the name of a signal (SIGFPE). You get this signal if you try to divide an integer by 0 (or if you divide INT_MIN by -1). In other words, it has nothing to do with floating point operations or exceptions (in the C++ sense), so the name is a bit unfortunate.

The easiest solution is to check for 0 beforehand:

if (num_2[i] == 0 || (num_1[i] == INT_MIN && num_2[i] == -1)) {
// handle error, or throw your own exception
...
}
int result = num_1[i] / num_2[i];

Dealing with Floating Point exceptions

On Linux you can use the GNU extension feenableexcept (hidden right at the bottom of that page) to turn on trapping on floating point exceptions - if you do this then you'll receive the signal SIGFPE when an exception occurs which you can then catch in your debugger. Watch out though as sometimes the signal gets thrown on the floating point instruction after the one that's actually causing the problem, giving misleading line information in the debugger!

Floating Point Exception C++ Why and what is it?

A "floating point number" is how computers usually represent numbers that are not integers -- basically, a number with a decimal point. In C++ you declare them with float instead of int. A floating point exception is an error that occurs when you try to do something impossible with a floating point number, such as divide by zero.

Returning From Catching A Floating Point Exception

I think you're supposed to mess around with the calling stack frame if you want to skip an instruction or break out of exp or whatever. This is high voodoo and bound to be unportable.

The GNU C library lets you use setjmp() outside of a signal handler to which you can longjmp() from inside. This seems like a better way to go. Here is a self-contained modification of your program showing how to do it:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>
#include <math.h>
#include <errno.h>
#include <float.h>
#include <fenv.h>

sigjmp_buf oh_snap;

void overflow_handler(int signal_number) {
if (feclearexcept(FE_OVERFLOW | FE_UNDERFLOW | FE_DIVBYZERO | FE_INVALID)){
fprintf(stdout, "Nothing Cleared!\n");
}
else{
fprintf(stdout, "All Cleared!\n");
}
siglongjmp(oh_snap, 1);

return;
}

int main(void) {
int failure;
float oops;
failure = 1;
failure = feenableexcept(FE_OVERFLOW | FE_UNDERFLOW | FE_DIVBYZERO | FE_INVALID);
if (failure){
fprintf(stdout, "FE ENABLE EXCEPTIONS FAILED!\n");
}
signal(SIGFPE, overflow_handler);
if (sigsetjmp(oh_snap, 1)) {
printf("Oh snap!\n");
} else {
oops = exp(-708.5);
fprintf(stdout, "Oops: %f\n", oops);
}
return 0;
}


Related Topics



Leave a reply



Submit