TEST(math, rint) { fesetround(FE_UPWARD); // rint/rintf/rintl obey the rounding mode. feclearexcept(FE_ALL_EXCEPT); // rint/rintf/rintl do set the FE_INEXACT flag. ASSERT_EQ(1234.0, rint(1234.0)); ASSERT_TRUE((fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT) == 0); ASSERT_EQ(1235.0, rint(1234.01)); ASSERT_TRUE((fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT) != 0); feclearexcept(FE_ALL_EXCEPT); // rint/rintf/rintl do set the FE_INEXACT flag. ASSERT_EQ(1234.0f, rintf(1234.0f)); ASSERT_TRUE((fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT) == 0); ASSERT_EQ(1235.0f, rintf(1234.01f)); ASSERT_TRUE((fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT) != 0); feclearexcept(FE_ALL_EXCEPT); // rint/rintf/rintl do set the FE_INEXACT flag. ASSERT_EQ(1234.0, rintl(1234.0)); ASSERT_TRUE((fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT) == 0); ASSERT_EQ(1235.0, rintl(1234.01)); ASSERT_TRUE((fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT) != 0); fesetround(FE_TOWARDZERO); // rint/rintf obey the rounding mode. ASSERT_EQ(1234.0, rint(1234.01)); ASSERT_EQ(1234.0f, rintf(1234.01f)); ASSERT_EQ(1234.0, rintl(1234.01)); }
static int do_test (void) { /* clear all exceptions and test if all are cleared */ feclearexcept (FE_ALL_EXCEPT); test_exceptions ("feclearexcept (FE_ALL_EXCEPT) clears all exceptions", NO_EXC); /* raise all exceptions and test if all are raised */ feraiseexcept (FE_ALL_EXCEPT); if (EXCEPTION_TESTS (float)) test_exceptions ("feraiseexcept (FE_ALL_EXCEPT) raises all exceptions", ALL_EXC); /* Same test, but using double as argument */ feclearexcept ((double)FE_ALL_EXCEPT); test_exceptions ("feclearexcept ((double)FE_ALL_EXCEPT) clears all exceptions", NO_EXC); feraiseexcept ((double)FE_ALL_EXCEPT); if (EXCEPTION_TESTS (float)) test_exceptions ("feraiseexcept ((double)FE_ALL_EXCEPT) raises all exceptions", ALL_EXC); if (EXCEPTION_TESTS (float)) test_exceptionflag (); test_fesetround (); test_feenabledisable (); return count_errors; }
/* * Test fetestexcept() and feclearexcept(). */ static void test_fetestclearexcept(void) { int excepts, i; for (i = 0; i < 1 << NEXCEPTS; i++) assert(fetestexcept(std_except_sets[i]) == 0); for (i = 0; i < 1 << NEXCEPTS; i++) { excepts = std_except_sets[i]; /* FE_ALL_EXCEPT might be special-cased, as on i386. */ raiseexcept(excepts); assert(fetestexcept(excepts) == excepts); assert(feclearexcept(FE_ALL_EXCEPT) == 0); assert(fetestexcept(FE_ALL_EXCEPT) == 0); raiseexcept(excepts); assert(fetestexcept(excepts) == excepts); if ((excepts & (FE_UNDERFLOW | FE_OVERFLOW)) != 0) { excepts |= FE_INEXACT; assert((fetestexcept(ALL_STD_EXCEPT) | FE_INEXACT) == excepts); } else { assert(fetestexcept(ALL_STD_EXCEPT) == excepts); } assert(feclearexcept(excepts) == 0); assert(fetestexcept(ALL_STD_EXCEPT) == 0); } }
/* * Test feraiseexcept(). * * Prerequisites: fetestexcept(), feclearexcept() */ static void test_feraiseexcept(void) { int excepts, i; for (i = 0; i < 1 << NEXCEPTS; i++) { excepts = std_except_sets[i]; assert(fetestexcept(FE_ALL_EXCEPT) == 0); assert(feraiseexcept(excepts) == 0); if ((excepts & (FE_UNDERFLOW | FE_OVERFLOW)) != 0) { excepts |= FE_INEXACT; assert((fetestexcept(ALL_STD_EXCEPT) | FE_INEXACT) == excepts); } else { assert(fetestexcept(ALL_STD_EXCEPT) == excepts); } assert(feclearexcept(FE_ALL_EXCEPT) == 0); } assert(feraiseexcept(FE_INVALID | FE_DIVBYZERO) == 0); assert(fetestexcept(ALL_STD_EXCEPT) == (FE_INVALID | FE_DIVBYZERO)); assert(feraiseexcept(FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) == 0); assert(fetestexcept(ALL_STD_EXCEPT) == ALL_STD_EXCEPT); assert(feclearexcept(FE_ALL_EXCEPT) == 0); }
/* * 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)); }
TEST(math, nearbyint) { auto guard = make_scope_guard([]() { fesetenv(FE_DFL_ENV); }); fesetround(FE_UPWARD); // nearbyint/nearbyintf/nearbyintl obey the rounding mode. feclearexcept(FE_ALL_EXCEPT); // nearbyint/nearbyintf/nearbyintl don't set the FE_INEXACT flag. ASSERT_EQ(1234.0, nearbyint(1234.0)); ASSERT_TRUE((fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT) == 0); ASSERT_EQ(1235.0, nearbyint(1234.01)); ASSERT_TRUE((fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT) == 0); feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(1234.0f, nearbyintf(1234.0f)); ASSERT_TRUE((fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT) == 0); ASSERT_EQ(1235.0f, nearbyintf(1234.01f)); ASSERT_TRUE((fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT) == 0); feclearexcept(FE_ALL_EXCEPT); // nearbyint/nearbyintf/nearbyintl don't set the FE_INEXACT flag. ASSERT_EQ(1234.0, nearbyintl(1234.0L)); ASSERT_TRUE((fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT) == 0); ASSERT_EQ(1235.0, nearbyintl(1234.01L)); ASSERT_TRUE((fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT) == 0); fesetround(FE_TOWARDZERO); // nearbyint/nearbyintf/nearbyintl obey the rounding mode. ASSERT_EQ(1234.0, nearbyint(1234.01)); ASSERT_EQ(1234.0f, nearbyintf(1234.01f)); ASSERT_EQ(1234.0, nearbyintl(1234.01L)); }
static void set_single_exc (const char *test_name, int fe_exc, fexcept_t exception) { char str[200]; /* The standard allows the inexact exception to be set together with the underflow and overflow exceptions. So ignore the inexact flag if the others are raised. */ int ignore_inexact = (fe_exc & (UNDERFLOW_EXC | OVERFLOW_EXC)) != 0; strcpy (str, test_name); strcat (str, ": set flag, with rest not set"); feclearexcept (FE_ALL_EXCEPT); feraiseexcept (exception); test_exceptions (str, fe_exc, ignore_inexact); strcpy (str, test_name); strcat (str, ": clear flag, rest also unset"); feclearexcept (exception); test_exceptions (str, NO_EXC, ignore_inexact); strcpy (str, test_name); strcat (str, ": set flag, with rest set"); feraiseexcept (FE_ALL_EXCEPT ^ exception); feraiseexcept (exception); test_exceptions (str, ALL_EXC, 0); strcpy (str, test_name); strcat (str, ": clear flag, leave rest set"); feclearexcept (exception); test_exceptions (str, ALL_EXC ^ fe_exc, 0); }
static void fe_tests (void) { /* clear all exceptions and test if all are cleared */ feclearexcept (FE_ALL_EXCEPT); test_exceptions ("feclearexcept (FE_ALL_EXCEPT) clears all exceptions", NO_EXC, 0); /* raise all exceptions and test if all are raised */ feraiseexcept (FE_ALL_EXCEPT); test_exceptions ("feraiseexcept (FE_ALL_EXCEPT) raises all exceptions", ALL_EXC, 0); feclearexcept (FE_ALL_EXCEPT); #ifdef FE_DIVBYZERO set_single_exc ("Set/Clear FE_DIVBYZERO", DIVBYZERO_EXC, FE_DIVBYZERO); #endif #ifdef FE_INVALID set_single_exc ("Set/Clear FE_INVALID", INVALID_EXC, FE_INVALID); #endif #ifdef FE_INEXACT set_single_exc ("Set/Clear FE_INEXACT", INEXACT_EXC, FE_INEXACT); #endif #ifdef FE_UNDERFLOW set_single_exc ("Set/Clear FE_UNDERFLOW", UNDERFLOW_EXC, FE_UNDERFLOW); #endif #ifdef FE_OVERFLOW set_single_exc ("Set/Clear FE_OVERFLOW", OVERFLOW_EXC, FE_OVERFLOW); #endif }
void IEEE754ExceptionsPlugin::ieee754Check(UtestShell& test, TestResult& result, int flag, const char* text) { result.countCheck(); if(inexactDisabled_) CHECK(!feclearexcept(FE_INEXACT)); if(fetestexcept(flag)) { CHECK(!feclearexcept(FE_ALL_EXCEPT)); CheckFailure failure(&test, __FILE__, __LINE__, "IEEE754_CHECK_CLEAR", text); result.addFailure(failure); } }
ATF_TC_BODY(infinities_and_nans, tc) { char buf[128]; long double ld = 0.0; double d = 0.0; float f = 0.0; char *endp; ATF_REQUIRE(setlocale(LC_NUMERIC, "C")); sscanf("-Inf", "%le", &d); ATF_REQUIRE(d < 0.0 && isinf(d)); sscanf("iNfInItY and beyond", "%le%s", &d, buf); ATF_REQUIRE(d > 0.0 && isinf(d)); ATF_REQUIRE(strcmp(buf, " and beyond")); sscanf("NaN", "%le", &d); ATF_REQUIRE(isnan(d)); sscanf("NAN(123Y", "%le%s", &d, buf); ATF_REQUIRE(isnan(d)); ATF_REQUIRE(strcmp(buf, "(123Y") == 0); sscanf("nan(f00f)plugh", "%le%s", &d, buf); ATF_REQUIRE(isnan(d)); ATF_REQUIRE(strcmp(buf, "plugh") == 0); sscanf("-nan", "%le", &d); ATF_REQUIRE(isnan(d)); /* Only quiet NaNs should be returned. */ sscanf("NaN", "%e", &f); sscanf("nan", "%le", &d); sscanf("nan", "%Le", &ld); feclearexcept(FE_ALL_EXCEPT); ATF_REQUIRE(f != f); ATF_REQUIRE(d != d); ATF_REQUIRE(ld != ld); ATF_REQUIRE(fetestexcept(FE_INVALID) == 0); sscanf("nan(1234)", "%e", &f); sscanf("nan(1234)", "%le", &d); sscanf("nan(1234)", "%Le", &ld); feclearexcept(FE_ALL_EXCEPT); ATF_REQUIRE(f != f); ATF_REQUIRE(d != d); ATF_REQUIRE(ld != ld); /* POSIX says we should only generate quiet NaNs. */ ATF_REQUIRE(fetestexcept(FE_INVALID) == 0); }
/** * gfs_catch_floating_point_exceptions: * * Catch the default floating-point exceptions set in the Gerris * library. */ void gfs_catch_floating_point_exceptions (void) { #ifdef EXCEPTIONS fedisableexcept (EXCEPTIONS); feclearexcept (EXCEPTIONS); #endif /* EXCEPTIONS */ }
int main(void) { #pragma STDC FENV_ACCESS ON int yi; double y; float d; int e, i, err = 0; struct d_di *p; for (i = 0; i < sizeof t/sizeof *t; i++) { p = t + i; if (p->r < 0) continue; fesetround(p->r); feclearexcept(FE_ALL_EXCEPT); y = frexp(p->x, &yi); e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW); if (!checkexceptall(e, p->e, p->r)) { printf("%s:%d: bad fp exception: %s frexp(%a)=%a,%lld, want %s", p->file, p->line, rstr(p->r), p->x, p->y, p->i, estr(p->e)); printf(" got %s\n", estr(e)); err++; } d = ulperr(y, p->y, p->dy); if (!checkcr(y, p->y, p->r) || (isfinite(p->x) && yi != p->i)) { printf("%s:%d: %s frexp(%a) want %a,%lld got %a,%d ulperr %.3f = %a + %a\n", p->file, p->line, rstr(p->r), p->x, p->y, p->i, y, yi, d, d-p->dy, p->dy); err++; } } return !!err; }
int main(void) { #pragma STDC FENV_ACCESS ON long long yi; int e, i, err = 0; struct f_i *p; for (i = 0; i < sizeof t/sizeof *t; i++) { p = t + i; if (p->r < 0) continue; fesetround(p->r); feclearexcept(FE_ALL_EXCEPT); yi = ___(p->x); e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW); if (!checkexcept(e, p->e, p->r)) { printf("%s:%d: bad fp exception: %s ___(%a)=%lld, want %s", p->file, p->line, rstr(p->r), p->x, p->i, estr(p->e)); printf(" got %s\n", estr(e)); err++; } if (yi != p->i) { printf("%s:%d: %s ___(%a) want %lld got %lld\n", p->file, p->line, rstr(p->r), p->x, p->i, yi); err++; } } return !!err; }
void tests_start_mpfr (void) { test_version (); /* don't buffer, so output is not lost if a test causes a segv etc */ setbuf (stdout, NULL); #if defined HAVE_LOCALE_H && defined HAVE_SETLOCALE /* Added on 2005-07-09. This allows to test MPFR under various locales. New bugs will probably be found, in particular with LC_ALL="tr_TR.ISO8859-9" because of the i/I character... */ setlocale (LC_ALL, ""); #endif #ifdef MPFR_FPU_PREC set_fpu_prec (); #endif #ifdef MPFR_TEST_DIVBYZERO /* Define to test the use of MPFR_ERRDIVZERO */ feclearexcept (FE_ALL_EXCEPT); #endif tests_memory_start (); tests_rand_start (); tests_limit_start (); default_emin = mpfr_get_emin (); default_emax = mpfr_get_emax (); }
int main(void) { #pragma STDC FENV_ACCESS ON float ysin, ycos; float dsin, dcos; int e, i, err = 0; struct f_ff *p; for (i = 0; i < sizeof t/sizeof *t; i++) { p = t + i; if (p->r < 0) continue; fesetround(p->r); feclearexcept(FE_ALL_EXCEPT); sincosf(p->x, &ysin, &ycos); e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW); if (!checkexcept(e, p->e, p->r)) { printf("%s:%d: bad fp exception: %s sincosf(%a)=%a,%a, want %s", p->file, p->line, rstr(p->r), p->x, p->y, p->y2, estr(p->e)); printf(" got %s\n", estr(e)); err++; } dsin = ulperr(ysin, p->y, p->dy); dcos = ulperr(ycos, p->y2, p->dy2); if (!checkulp(dsin, p->r) || !checkulp(dcos, p->r)) { printf("%s:%d: %s sincosf(%a) want %a,%a got %a,%a, ulperr %.3f = %a + %a, %.3f = %a + %a\n", p->file, p->line, rstr(p->r), p->x, p->y, p->y2, ysin, ycos, dsin, dsin-p->dy, p->dy, dcos, dcos-p->dy2, p->dy2); err++; } } return !!err; }
~fpu_reset_guard() { #if defined(_MSC_VER) _clearfp(); // For MSVC, clear the floating point error flags #elif defined(FE_ALL_EXCEPT) feclearexcept(FE_ALL_EXCEPT); #endif }
static int test_in_one_mode (const char *s, enum underflow_case c, int rm, const char *mode_name) { int result = 0; feclearexcept (FE_ALL_EXCEPT); errno = 0; double d = strtod (s, NULL); int got_errno = errno; #ifdef FE_UNDERFLOW bool got_fe_underflow = fetestexcept (FE_UNDERFLOW) != 0; #else bool got_fe_underflow = false; #endif printf ("strtod (%s) (%s) returned %a, errno = %d, %sunderflow exception\n", s, mode_name, d, got_errno, got_fe_underflow ? "" : "no "); bool this_expect_underflow = expect_underflow (c, rm); if (got_errno != 0 && got_errno != ERANGE) { puts ("FAIL: errno neither 0 nor ERANGE"); result = 1; } else if (this_expect_underflow != (errno == ERANGE)) { puts ("FAIL: underflow from errno differs from expectations"); result = 1; } if (support_underflow_exception && got_fe_underflow != this_expect_underflow) { puts ("FAIL: underflow from exceptions differs from expectations"); result = 1; } return result; }
int main(void) { #pragma STDC FENV_ACCESS ON long double y; float d; int e, i, err = 0; struct l_l *p; for (i = 0; i < sizeof t/sizeof *t; i++) { p = t + i; if (p->r < 0) continue; fesetround(p->r); feclearexcept(FE_ALL_EXCEPT); y = erfl(p->x); e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW); if (!checkexcept(e, p->e, p->r)) { printf("%s:%d: bad fp exception: %s erfl(%La)=%La, want %s", p->file, p->line, rstr(p->r), p->x, p->y, estr(p->e)); printf(" got %s\n", estr(e)); err++; } d = ulperrl(y, p->y, p->dy); if (!checkulp(d, p->r)) { printf("%s:%d: %s erfl(%La) want %La got %La ulperr %.3f = %a + %a\n", p->file, p->line, rstr(p->r), p->x, p->y, y, d, d-p->dy, p->dy); err++; } } return !!err; }
void Replay::set_signal_handlers(void) { struct sigaction sa; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (generate_fpe) { // SITL_State::_parse_command_line sets up an FPE handler. We // can do better: feenableexcept(FE_INVALID | FE_OVERFLOW); sa.sa_handler = _replay_sig_fpe; } else { // disable floating point exception generation: int exceptions = FE_OVERFLOW | FE_DIVBYZERO; #ifndef __i386__ // i386 with gcc doesn't work with FE_INVALID exceptions |= FE_INVALID; #endif if (feclearexcept(exceptions)) { ::fprintf(stderr, "Failed to disable floating point exceptions: %s", strerror(errno)); } sa.sa_handler = SIG_IGN; } if (sigaction(SIGFPE, &sa, nullptr) < 0) { ::fprintf(stderr, "Failed to set floating point exceptions' handler: %s", strerror(errno)); } }
static void test_feenabledisable (void) { printf ("Tests for feenableexcepts/fedisableexcept\n"); /* We might have some exceptions still set. */ feclearexcept (FE_ALL_EXCEPT); #ifdef FE_DIVBYZERO feenable_test ("FE_DIVBYZERO", FE_DIVBYZERO); #endif #ifdef FE_INVALID feenable_test ("FE_INVALID", FE_INVALID); #endif #ifdef FE_INEXACT feenable_test ("FE_INEXACT", FE_INEXACT); #endif #ifdef FE_UNDERFLOW feenable_test ("FE_UNDERFLOW", FE_UNDERFLOW); #endif #ifdef FE_OVERFLOW feenable_test ("FE_OVERFLOW", FE_OVERFLOW); #endif fesetenv (FE_DFL_ENV); }
static void MLOCKED_TEXT stress_fpehandler(int num) { (void)num; (void)feclearexcept(FE_ALL_EXCEPT); siglongjmp(jmp_env, 1); /* Ugly, bounce back */ }
int main(void) { #pragma STDC FENV_ACCESS ON int yi; long double y; float d; int e, i, err = 0; struct l_li *p; for (i = 0; i < sizeof t/sizeof *t; i++) { p = t + i; if (p->r < 0) continue; fesetround(p->r); feclearexcept(FE_ALL_EXCEPT); y = lgammal_r(p->x, &yi); e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW); if (!checkexcept(e, p->e, p->r)) { printf("%s:%d: bad fp exception: %s lgammal_r(%La)=%La,%lld, want %s", p->file, p->line, rstr(p->r), p->x, p->y, p->i, estr(p->e)); printf(" got %s\n", estr(e)); err++; } d = ulperrl(y, p->y, p->dy); // TODO: 2 ulp errors allowed if ((p->r==RN && fabs(d)>2) || (!isnan(p->x) && p->x!=-inf && !(p->e&DIVBYZERO) && yi != p->i)) { printf("%s:%d: %s lgammal_r(%La) want %La,%lld got %La,%d ulperr %.3f = %a + %a\n", p->file, p->line, rstr(p->r), p->x, p->y, p->i, y, yi, d, d-p->dy, p->dy); err++; } } return !!err; }
int fpe_enable_trap( unsigned int except ) { if( feclearexcept( (int)except ) < 0 ) return -1; return feenableexcept( (int)except ); }
EXTERN_C_END #undef __FUNCT__ #define __FUNCT__ "PetscSetFPTrap" PetscErrorCode PetscSetFPTrap(PetscFPTrap on) { PetscFunctionBegin; if (on == PETSC_FP_TRAP_ON) { /* Clear any flags that are currently set so that activating trapping will not immediately call the signal handler. */ if (feclearexcept(FE_ALL_EXCEPT)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot clear floating point exception flags\n"); #if defined FE_NOMASK_ENV /* We could use fesetenv(FE_NOMASK_ENV), but that causes spurious exceptions (like gettimeofday() -> PetscLogDouble). */ if (feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) == -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot activate floating point exceptions\n"); #elif defined PETSC_HAVE_XMMINTRIN_H _MM_SET_EXCEPTION_MASK(_MM_MASK_INEXACT); #else /* C99 does not provide a way to modify the environment so there is no portable way to activate trapping. */ #endif if (SIG_ERR == signal(SIGFPE,PetscDefaultFPTrap)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Can't set floating point handler\n"); } else { if (fesetenv(FE_DFL_ENV)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot disable floating point exceptions"); if (SIG_ERR == signal(SIGFPE,SIG_DFL)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Can't clear floating point handler\n"); } _trapmode = on; PetscFunctionReturn(0); }
/* * Test fegetround() and fesetround(). */ static void test_fegsetround(void) { assert(fegetround() == FE_TONEAREST); assert(getround() == FE_TONEAREST); assert(FLT_ROUNDS == 1); assert(fesetround(FE_DOWNWARD) == 0); assert(fegetround() == FE_DOWNWARD); assert(getround() == FE_DOWNWARD); assert(FLT_ROUNDS == 3); assert(fesetround(FE_UPWARD) == 0); assert(getround() == FE_UPWARD); assert(fegetround() == FE_UPWARD); assert(FLT_ROUNDS == 2); assert(fesetround(FE_TOWARDZERO) == 0); assert(getround() == FE_TOWARDZERO); assert(fegetround() == FE_TOWARDZERO); assert(FLT_ROUNDS == 0); assert(fesetround(FE_TONEAREST) == 0); assert(getround() == FE_TONEAREST); assert(FLT_ROUNDS == 1); assert(feclearexcept(FE_ALL_EXCEPT) == 0); }
TEST(fenv, feraiseexcept) { feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT)); ASSERT_EQ(0, feraiseexcept(FE_DIVBYZERO | FE_OVERFLOW)); ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT)); }
int CLuaHandle::RunCallInTraceback(int inArgs, int outArgs, int errfuncIndex, std::string& traceback) { #if defined(__SUPPORT_SNAN__) // do not signal floating point exceptions in user Lua code feclearexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); #endif CLuaHandle* orig = activeHandle; SetActiveHandle(); const int error = lua_pcall(L, inArgs, outArgs, errfuncIndex); SetActiveHandle(orig); if (error == 0) { // pop the error handler if (errfuncIndex != 0) { lua_remove(L, errfuncIndex); } } else { traceback = lua_tostring(L, -1); lua_pop(L, 1); if (errfuncIndex != 0) lua_remove(L, errfuncIndex); // log only errors that lead to a crash callinErrors += (error == 2); } #if defined(__SUPPORT_SNAN__) feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); #endif return error; }
int main(void) { #pragma STDC FENV_ACCESS ON float y; float d; int e, i, err = 0; struct ff_f *p; for (i = 0; i < sizeof t/sizeof *t; i++) { p = t + i; if (p->r < 0) continue; fesetround(p->r); feclearexcept(FE_ALL_EXCEPT); y = fmaxf(p->x, p->x2); e = fetestexcept(INEXACT|INVALID|DIVBYZERO|UNDERFLOW|OVERFLOW); if (!checkexceptall(e, p->e, p->r)) { printf("%s:%d: bad fp exception: %s fmaxf(%a,%a)=%a, want %s", p->file, p->line, rstr(p->r), p->x, p->x2, p->y, estr(p->e)); printf(" got %s\n", estr(e)); err++; } d = ulperrf(y, p->y, p->dy); if (!checkcr(y, p->y, p->r)) { printf("%s:%d: %s fmaxf(%a,%a) want %a got %a ulperr %.3f = %a + %a\n", p->file, p->line, rstr(p->r), p->x, p->x2, p->y, y, d, d-p->dy, p->dy); err++; } } return !!err; }
void Set_Floating_Point_Exception_Handling(const bool enable,const bool division_by_zero,const bool invalid_operation,const bool overflow,const bool underflow,const bool inexact_result) { static bool have_original_action=false; static struct sigaction original_action; if(!have_original_action){ // initialize with original action sigaction(SIGFPE,0,&original_action);} if(enable){ int exceptions=0; if(division_by_zero) exceptions|=FE_DIVBYZERO; if(invalid_operation) exceptions|=FE_INVALID; if(overflow) exceptions|=FE_OVERFLOW; if(underflow) exceptions|=FE_UNDERFLOW; if(inexact_result) exceptions|=FE_INEXACT; // avoid catching delayed exceptions caused by external code fedisableexcept(FE_ALL_EXCEPT); feclearexcept(exceptions); // install new handler struct sigaction action; action.sa_flags=SA_SIGINFO; action.sa_sigaction=Floating_Point_Exception_Handler; sigemptyset(&action.sa_mask); if(sigaction(SIGFPE,&action,0)) PHYSBAM_FATAL_ERROR("Could not register FPE signal handler"); feenableexcept(exceptions);} else{ if(sigaction(SIGFPE,&original_action,0)) PHYSBAM_FATAL_ERROR("Could not restore FPE signal handler"); fedisableexcept(FE_ALL_EXCEPT);} }