/* * Test fegetexceptflag() and fesetexceptflag(). * * Prerequisites: fetestexcept(), feclearexcept() */ static void test_fegsetexceptflag(void) { fexcept_t flag; int excepts, i; assert(fetestexcept(FE_ALL_EXCEPT) == 0); for (i = 0; i < 1 << NEXCEPTS; i++) { excepts = std_except_sets[i]; assert(fegetexceptflag(&flag, excepts) == 0); raiseexcept(ALL_STD_EXCEPT); assert(fesetexceptflag(&flag, excepts) == 0); assert(fetestexcept(ALL_STD_EXCEPT) == (ALL_STD_EXCEPT ^ excepts)); assert(fegetexceptflag(&flag, FE_ALL_EXCEPT) == 0); assert(feclearexcept(FE_ALL_EXCEPT) == 0); assert(fesetexceptflag(&flag, excepts) == 0); assert(fetestexcept(ALL_STD_EXCEPT) == 0); assert(fesetexceptflag(&flag, ALL_STD_EXCEPT ^ excepts) == 0); assert(fetestexcept(ALL_STD_EXCEPT) == (ALL_STD_EXCEPT ^ excepts)); assert(feclearexcept(FE_ALL_EXCEPT) == 0); } }
TEST(fenv, fegetexceptflag_fesetexceptflag) { // Set three flags. feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(0, feraiseexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)); ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT)); fexcept_t all; // FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW fexcept_t two; // FE_OVERFLOW | FE_UNDERFLOW ASSERT_EQ(0, fegetexceptflag(&all, FE_ALL_EXCEPT)); ASSERT_EQ(0, fegetexceptflag(&two, FE_OVERFLOW | FE_UNDERFLOW)); // Check we can restore all. feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(0, fesetexceptflag(&all, FE_ALL_EXCEPT)); ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT)); // Check that `two` only stored a subset. feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(0, fesetexceptflag(&two, FE_ALL_EXCEPT)); ASSERT_EQ(FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT)); // Check that we can restore a single flag. feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(0, fesetexceptflag(&all, FE_DIVBYZERO)); ASSERT_EQ(FE_DIVBYZERO, fetestexcept(FE_ALL_EXCEPT)); // Check that we can restore a subset of flags. feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(0, fesetexceptflag(&all, FE_OVERFLOW | FE_UNDERFLOW)); ASSERT_EQ(FE_OVERFLOW | FE_UNDERFLOW, fetestexcept(FE_ALL_EXCEPT)); }
/* ------------------------------------------------------------------------------- Clears the system's IEC/IEEE floating-point exception flags. Returns the previous value of the flags. ------------------------------------------------------------------------------- */ int8 syst_float_flags_clear( void ) { fexcept_t flags; fegetexceptflag(&flags, FE_ALL_EXCEPT); feclearexcept(FE_ALL_EXCEPT); return (flags >> 5); }
/* The fetestexcept function determines which of a specified subset of the floatingpoint exception flags are currently set. The excepts argument specifies the floatingpoint status flags to be queried. Returns: the value of the bitwise OR of the floating-point exception macros corresponding to the currently set floating-point exceptions included in excepts. */ _WCRTLINK int fetestexcept( int excepts ) /***************************************/ { fexcept_t curr; fegetexceptflag( &curr, excepts ); return( curr ); }
int feraiseexcept(int e) { fexcept_t f; fegetexceptflag(&f, e); fesetexceptflag(&f, e); return 0; }
static void test_exceptionflag (void) { printf ("Test: fegetexceptionflag (FE_ALL_EXCEPT)\n"); #if FE_ALL_EXCEPT fexcept_t excepts; feclearexcept (FE_ALL_EXCEPT); feraiseexcept (FE_INVALID); fegetexceptflag (&excepts, FE_ALL_EXCEPT); feclearexcept (FE_ALL_EXCEPT); feraiseexcept (FE_OVERFLOW | FE_INEXACT); fesetexceptflag (&excepts, FE_ALL_EXCEPT); test_single_exception_fp_int (INVALID_EXC, INVALID_EXC, FE_INVALID, "INVALID (int)"); test_single_exception_fp_int (INVALID_EXC, OVERFLOW_EXC, FE_OVERFLOW, "OVERFLOW (int)"); test_single_exception_fp_int (INVALID_EXC, INEXACT_EXC, FE_INEXACT, "INEXACT (int)"); /* Same test, but using double as argument */ feclearexcept (FE_ALL_EXCEPT); feraiseexcept (FE_INVALID); fegetexceptflag (&excepts, (double)FE_ALL_EXCEPT); feclearexcept (FE_ALL_EXCEPT); feraiseexcept (FE_OVERFLOW | FE_INEXACT); fesetexceptflag (&excepts, (double)FE_ALL_EXCEPT); test_single_exception_fp_double (INVALID_EXC, INVALID_EXC, FE_INVALID, "INVALID (double)"); test_single_exception_fp_double (INVALID_EXC, OVERFLOW_EXC, FE_OVERFLOW, "OVERFLOW (double)"); test_single_exception_fp_double (INVALID_EXC, INEXACT_EXC, FE_INEXACT, "INEXACT (double)"); #endif }
fpu_guard() { fegetexceptflag(&m_flags, FE_ALL_EXCEPT); feclearexcept(FE_ALL_EXCEPT); }