fetestexcept fails

R

rembremading

Hi all!

I try to implement floating point error handling, (i.e. trap nan and if
errors in floating point opperations) with gnu c standard library.
However fetestexcept does not give me the expected result.
The following code prints
Floating point error:
without the expected error code

Thank you!

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fenv.h>
#include <setjmp.h>
#include <signal.h>
#include <math.h>


#ifndef __SUPPORT_SNAN__
#define __SUPPORT_SNAN__
#endif

jmp_buf return_to_top_level;


/* floating-point error handler */
void fperror(int sig)
{

int ret;
int set_excepts;
char temp[256];

strcpy(temp, "Floating point error: ");

set_excepts = fetestexcept(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW |
FE_OVERFLOW);

if(set_excepts & FE_INEXACT)
strcat(temp,"[Inexact] ");

if(set_excepts & FE_DIVBYZERO)
strcat(temp,"[Divide by 0] ");

if(set_excepts & FE_UNDERFLOW)
strcat(temp,"[Underflow] ");

if(set_excepts & FE_OVERFLOW)
strcat(temp,"[Overflow] ");

if(set_excepts & FE_INVALID)
strcat(temp,"[Invalid] ");

printf("\a%s\n", temp);

keep_going = 0;
longjmp(return_to_top_level, 1);

}

int main()
{

double test1, test2;
int ret;

/* assigning exception handler */

signal(SIGFPE, fperror);

/* enableing floating point exception signaling */
ret = feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);

/* set-up return address for errors */
if(setjmp(return_to_top_level)){
return 1;
}

test1 = 0.0;
test2 = 3.14/test1;
test1 = -1.0;
test2 = sqrt(test1);

return EXIT_SUCCESS;
}
 
J

jacob navia

rembremading said:

[snip]

You have several errors in your code. I rewrote it
like this, and compiled it with lcc-win32. It should
also compile with gcc since it is pure C99

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fenv.h>
#include <setjmp.h>
#include <signal.h>
#include <math.h>


#ifndef __SUPPORT_SNAN__
#define __SUPPORT_SNAN__
#endif

jmp_buf return_to_top_level;


/* floating-point error handler */
void fperror(int sig)
{

int ret;
int set_excepts;
char temp[256];

strcpy(temp, "Floating point error: ");

set_excepts = fetestexcept(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW |
FE_OVERFLOW);

if(set_excepts & FE_INEXACT)
strcat(temp,"[Inexact] ");

if(set_excepts & FE_DIVBYZERO)
strcat(temp,"[Divide by 0] ");

if(set_excepts & FE_UNDERFLOW)
strcat(temp,"[Underflow] ");

if(set_excepts & FE_OVERFLOW)
strcat(temp,"[Overflow] ");

if(set_excepts & FE_INVALID)
strcat(temp,"[Invalid] ");

printf("\a%s\n", temp);

// NOT DEFINED keep_going = 0;
longjmp(return_to_top_level, 1);

}

int main()
{

double test1, test2;
int ret;
fenv_t env;
fexcept_t flagp;

/* assigning exception handler */

signal(SIGFPE, fperror);

fegetexceptflag(&flagp,FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
/* enableing floating point exception signaling */
fesetexceptflag(&flagp,FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);

/* set-up return address for errors */
if(setjmp(return_to_top_level)){
return 1;
}

test1 = 0.0;
test2 = 3.14/test1;
fperror(0);
test1 = -1.0;
test2 = sqrt(test1);
fperror(0);

return EXIT_SUCCESS;
}
 
R

rembremading

Yes it works!
I conclude, that the main error (appart from improper copy&paste) was, that
I forgot to define
fenv_t env;
fexcept_t flagp;
and to hand over &flagp to fegetexceptflag.
My gcc compiler did not complain. (but I dont wont to blame it)

Thank you.


jacob said:
rembremading said:

[snip]

You have several errors in your code. I rewrote it
like this, and compiled it with lcc-win32. It should
also compile with gcc since it is pure C99

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fenv.h>
#include <setjmp.h>
#include <signal.h>
#include <math.h>


#ifndef __SUPPORT_SNAN__
#define __SUPPORT_SNAN__
#endif

jmp_buf return_to_top_level;


/* floating-point error handler */
void fperror(int sig)
{

int ret;
int set_excepts;
char temp[256];

strcpy(temp, "Floating point error: ");

set_excepts = fetestexcept(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW |
FE_OVERFLOW);

if(set_excepts & FE_INEXACT)
strcat(temp,"[Inexact] ");

if(set_excepts & FE_DIVBYZERO)
strcat(temp,"[Divide by 0] ");

if(set_excepts & FE_UNDERFLOW)
strcat(temp,"[Underflow] ");

if(set_excepts & FE_OVERFLOW)
strcat(temp,"[Overflow] ");

if(set_excepts & FE_INVALID)
strcat(temp,"[Invalid] ");

printf("\a%s\n", temp);

// NOT DEFINED keep_going = 0;
longjmp(return_to_top_level, 1);

}

int main()
{

double test1, test2;
int ret;
fenv_t env;
fexcept_t flagp;

/* assigning exception handler */

signal(SIGFPE, fperror);

fegetexceptflag(&flagp,FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
/* enableing floating point exception signaling */
fesetexceptflag(&flagp,FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);

/* set-up return address for errors */
if(setjmp(return_to_top_level)){
return 1;
}

test1 = 0.0;
test2 = 3.14/test1;
fperror(0);
test1 = -1.0;
test2 = sqrt(test1);
fperror(0);

return EXIT_SUCCESS;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,823
Latest member
Nadia88

Latest Threads

Top