home *** CD-ROM | disk | FTP | other *** search
-
- /* This code attempts to figure out what the default
- floating point exception handling does.
- */
-
- /* $Log: fpe_check.c,v $
- * Revision 1.7 1996/08/30 00:07:14 mike
- * Modifications to the test and implementation of the bug fix for
- * solaris overflow in strtod.
- *
- * Revision 1.6 1996/08/25 19:25:46 mike
- * Added test for solaris strtod overflow bug.
- *
- * Revision 1.5 1996/08/11 22:10:39 mike
- * Some systems blow the !(d==d) test for a NAN. Added a work around.
- *
- * Revision 1.4 1995/01/09 01:22:28 mike
- * check sig handler ret type to make fpe_check.c more robust
- *
- * Revision 1.3 1994/12/18 20:54:00 mike
- * check NetBSD mathlib defines
- *
- * Revision 1.2 1994/12/14 14:37:26 mike
- * add messages to user
- *
- */
-
- #include <setjmp.h>
- #include <signal.h>
- #include <math.h>
-
- /* Sets up NetBSD 1.0A for ieee floating point */
- #if defined(_LIB_VERSION_TYPE) && defined(_LIB_VERSION) && defined(_IEEE_)
- _LIB_VERSION_TYPE _LIB_VERSION = _IEEE_;
- #endif
-
- void message(s)
- char *s ;
- {
- printf("\t%s\n", s) ;
- }
-
- jmp_buf jbuff ;
- int may_be_safe_to_look_at_why = 0 ;
- int why_v ;
- int checking_for_strtod_ovf_bug = 0 ;
-
- RETSIGTYPE fpe_catch() ;
- int is_nan() ;
- void check_strtod_ovf() ;
- double strtod() ;
-
- double
- div_by(x,y)
- double x ;
- double y ;
- {
- return x/y ;
- }
-
- double overflow(x)
- double x ;
- {
- double y ;
-
- do
- {
- y = x ;
- x *= x ;
- } while( y != x ) ;
- return x ;
- }
-
-
- void check_fpe_traps()
- {
- int traps = 0 ;
-
- if (setjmp(jbuff) == 0)
- {
- div_by(44.0, 0.0) ;
- message("division by zero does not generate an exception") ;
- }
- else
- {
- traps = 1 ;
- message("division by zero generates an exception") ;
- signal(SIGFPE, fpe_catch) ; /* set again if sysV */
- }
-
- if ( setjmp(jbuff) == 0 )
- {
- overflow(1000.0) ;
- message("overflow does not generate an exception") ;
- }
- else
- {
- traps |= 2 ;
- message("overflow generates an exception") ;
- signal(SIGFPE, fpe_catch) ;
- }
-
- if ( traps == 0 )
- {
- double maybe_nan = log(-8.0) ;
-
- if (is_nan(maybe_nan))
- {
- message("math library supports ieee754") ;
- }
- else
- {
- traps |= 4 ;
- message("math library does not support ieee754") ;
- }
- }
-
- exit(traps) ;
- }
-
- int is_nan(d)
- double d ;
- {
- char command[128] ;
-
- if (!(d==d)) return 1 ;
-
- /* on some systems with an ieee754 bug, we need to make another check */
- sprintf(command,
- "echo '%f' | egrep '[nN][aA][nN]|\\?' >/dev/null", d) ;
- return system(command)==0 ;
- }
-
- /*
- Only get here if we think we have Berkeley type signals so we can
- look at a second argument to fpe_catch() to get the reason for
- an exception
- */
- void
- get_fpe_codes()
- {
- int divz ;
- int ovf ;
-
- may_be_safe_to_look_at_why = 1 ;
-
- if( setjmp(jbuff) == 0 ) div_by(1000.0, 0.0) ;
- else
- {
- divz = why_v ;
- signal(SIGFPE, fpe_catch) ;
- }
-
- if( setjmp(jbuff) == 0 ) overflow(1000.0) ;
- else
- {
- ovf = why_v ;
- signal(SIGFPE, fpe_catch) ;
- }
-
-
- /* make some guesses if sane values */
- if ( divz>0 && ovf>0 && divz != ovf )
- {
- printf("X FPE_ZERODIVIDE %d\n", divz) ;
- printf("X FPE_OVERFLOW %d\n", ovf) ;
- exit(0) ;
- }
- else exit(1) ;
- }
-
- int
- main(argc)
- int argc ;
- {
-
- signal(SIGFPE, fpe_catch) ;
- switch(argc) {
- case 1 :
- check_fpe_traps() ;
- break ;
- case 2 :
- get_fpe_codes() ;
- break ;
- default:
- check_strtod_ovf() ;
- break ;
- }
- /* not reached */
- return 0 ;
- }
-
- /* put this down here in attempt to defeat ambitious compiler that
- may have seen a prototype without 2nd argument */
-
- RETSIGTYPE fpe_catch(signal, why)
- int signal ;
- int why ;
- {
- if (checking_for_strtod_ovf_bug) exit(1) ;
- if ( may_be_safe_to_look_at_why ) why_v = why ;
- longjmp(jbuff,1) ;
- }
-
- char longstr[] =
- "1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890\
- 1234567890" ;
-
- #ifdef USE_IEEEFP_H
- #include <ieeefp.h>
- #endif
-
- void
- check_strtod_ovf()
- {
- double x ;
-
- #ifdef USE_IEEEFP_H
- fpsetmask(fpgetmask()|FP_X_OFL|FP_X_DZ) ;
- #endif
-
- checking_for_strtod_ovf_bug = 1 ;
- strtod(longstr,(char**)0) ;
- exit(0) ;
- }
-