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