Important Notice
The pages on this site contain documentation for very old MS-DOS software,
purely for historical purposes.
If you're looking for up-to-date documentation, particularly for programming,
you should not rely on the information found here, as it will be woefully
out of date.
SIGFP.C
◄Up► ◄Contents► ◄Index► ◄Back►
────────────────────────────────────────────────────────────────────────────
/* SIGFP.C illustrates setting up floating-point signal routines.
* Functions illustrated include:
* signal _fpreset setjmp longjmp
*
* For another example of setting up signal routines, see SIGNAL.C.
*/
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>
#include <string.h>
jmp_buf mark; /* Address for long jump to jump to */
int fperr; /* Global error number */
void fphandler( int sig, int num ); /* Prototypes */
void fpcheck( void );
void main()
{
double n1, n2, r;
int jmpret;
/* Set up floating-point error handler. */
if( signal( SIGFPE, fphandler ) == SIG_ERR )
{
fprintf( stderr, "Couldn't set SIGFPE\n" );
abort();
}
/* Save stack environment for return in case of error. First time
* through, jmpret is 0, so true conditional is executed. If an
* error occurs, jmpret will be set to -1 and false conditional
* will be executed.
*/
jmpret = setjmp( mark );
if( jmpret == 0 )
{
printf( "Test for invalid operation - " );
printf( "enter two numbers: " );
scanf( "%lf %lf", &n1, &n2 );
r = n1 / n2;
/* This won't be reached if error occurs. */
printf( "\n\n%4.3g / %4.3g = %4.3g\n", n1, n2, r );
r = n1 * n2;
/* This won't be reached if error occurs. */
printf( "\n\n%4.3g * %4.3g = %4.3g\n", n1, n2, r );
}
else
fpcheck();
}
/* Handles SIGFPE (floating-point error) interrupt. */
void fphandler( int sig, int num )
{
/* Set global for outside check, since we don't want to do I/O in the
* handler.
*/
fperr = num;
/* Initialize floating-point package. */
_fpreset();
/* Restore calling environment and jump back to setjmp. Return -1
* so that setjmp will return false for conditional test.
*/
longjmp( mark, -1 );
}
void fpcheck()
{
char fpstr[30];
switch( fperr )
{
case FPE_INVALID:
strcpy( fpstr, "Invalid number" );
break;
case FPE_OVERFLOW:
strcpy( fpstr, "Overflow" );
break;
case FPE_UNDERFLOW:
strcpy( fpstr, "Underflow" );
break;
case FPE_ZERODIVIDE:
strcpy( fpstr, "Divide by zero" );
break;
default:
strcpy( fpstr, "Other floating point error" );
break;
}
printf( "Error %d: %s\n", fperr, fpstr );
}