1 /* $OpenBSD: except.c,v 1.5 2003/09/02 23:52:16 david Exp $ */ 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <signal.h> 6 #include <assert.h> 7 #include <ieeefp.h> 8 #include <float.h> 9 10 volatile sig_atomic_t signal_cought; 11 12 static volatile const double one = 1.0; 13 static volatile const double zero = 0.0; 14 static volatile const double huge = DBL_MAX; 15 static volatile const double tiny = DBL_MIN; 16 17 static void 18 sigfpe(int signo) 19 { 20 signal_cought = 1; 21 } 22 23 int 24 main(int argc, char *argv[]) 25 { 26 volatile double x; 27 28 /* 29 * check to make sure that all exceptions are masked and 30 * that the accumulated exception status is clear. 31 */ 32 assert(fpgetmask() == 0); 33 assert(fpgetsticky() == 0); 34 35 /* set up signal handler */ 36 signal (SIGFPE, sigfpe); 37 signal_cought = 0; 38 39 /* trip divide by zero */ 40 x = one / zero; 41 assert (fpgetsticky() & FP_X_DZ); 42 assert (signal_cought == 0); 43 fpsetsticky(0); 44 45 /* trip invalid operation */ 46 x = zero / zero; 47 assert (fpgetsticky() & FP_X_INV); 48 assert (signal_cought == 0); 49 fpsetsticky(0); 50 51 /* trip overflow */ 52 x = huge * huge; 53 assert (fpgetsticky() & FP_X_OFL); 54 assert (signal_cought == 0); 55 fpsetsticky(0); 56 57 /* trip underflow */ 58 x = tiny * tiny; 59 assert (fpgetsticky() & FP_X_UFL); 60 assert (signal_cought == 0); 61 fpsetsticky(0); 62 63 #if 0 64 /* unmask and then trip divide by zero */ 65 fpsetmask(FP_X_DZ); 66 x = one / zero; 67 assert (signal_cought == 1); 68 signal_cought = 0; 69 70 /* unmask and then trip invalid operation */ 71 fpsetmask(FP_X_INV); 72 x = zero / zero; 73 assert (signal_cought == 1); 74 signal_cought = 0; 75 76 /* unmask and then trip overflow */ 77 fpsetmask(FP_X_OFL); 78 x = huge * huge; 79 assert (signal_cought == 1); 80 signal_cought = 0; 81 82 /* unmask and then trip underflow */ 83 fpsetmask(FP_X_UFL); 84 x = tiny * tiny; 85 assert (signal_cought == 1); 86 signal_cought = 0; 87 #endif 88 89 exit(0); 90 } 91 92