/* Test that program aborts with no masked interrupts */ static void feenv_nomask_test (const char *flag_name, int fe_exc) { #if defined FE_NOMASK_ENV int status; pid_t pid; if (!EXCEPTION_ENABLE_SUPPORTED (FE_ALL_EXCEPT) && fesetenv (FE_NOMASK_ENV) != 0) { printf ("Test: not testing FE_NOMASK_ENV, it isn't implemented.\n"); return; } printf ("Test: after fesetenv (FE_NOMASK_ENV) processes will abort\n"); printf (" when feraiseexcept (%s) is called.\n", flag_name); pid = fork (); if (pid == 0) { #ifdef RLIMIT_CORE /* Try to avoid dumping core. */ struct rlimit core_limit; core_limit.rlim_cur = 0; core_limit.rlim_max = 0; setrlimit (RLIMIT_CORE, &core_limit); #endif fesetenv (FE_NOMASK_ENV); feraiseexcept (fe_exc); exit (2); } else if (pid < 0) { if (errno != ENOSYS) { printf (" Fail: Could not fork.\n"); ++count_errors; } else printf (" `fork' not implemented, test ignored.\n"); } else { if (waitpid (pid, &status, 0) != pid) { printf (" Fail: waitpid call failed.\n"); ++count_errors; } else if (WIFSIGNALED (status) && WTERMSIG (status) == SIGFPE) printf (" Pass: Process received SIGFPE.\n"); else { printf (" Fail: Process didn't receive signal and exited with status %d.\n", status); ++count_errors; } } #endif }
void ygl_fpemask(int on) { ygl_valid_fenv = (ygl_valid_fenv || !fegetenv(&ygl_fenv)); if (ygl_valid_fenv) { if (on) { if (on != 1) ygl_depth_fenv = 1; if (ygl_depth_fenv && !--ygl_depth_fenv) fesetenv(&ygl_fenv); } else { if (!ygl_depth_fenv++) fesetenv(FE_DFL_ENV); } } }
int feupdateenv(const fenv_t *envp) { int ex = fetestexcept(FE_ALL_EXCEPT); fesetenv(envp); feraiseexcept(ex); return 0; }
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)); }
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); }
static int fpequal_tol(long double x, long double y, long double tol) { fenv_t env; int ret; if (isnan(x) && isnan(y)) return (1); if (!signbit(x) != !signbit(y) && tol == 0) return (0); if (x == y) return (1); if (tol == 0) return (0); /* Hard case: need to check the tolerance. */ feholdexcept(&env); /* * For our purposes here, if y=0, we interpret tol as an absolute * tolerance. This is to account for roundoff in the input, e.g., * cos(Pi/2) ~= 0. */ if (y == 0.0) ret = fabsl(x - y) <= fabsl(tol); else ret = fabsl(x - y) <= fabsl(y * tol); fesetenv(&env); return (ret); }
static void test_fesetenv (void) { #if defined FE_NOMASK_ENV && defined FE_ALL_EXCEPT int res; fedisableexcept (FE_ALL_EXCEPT); res = fesetenv (FE_NOMASK_ENV); if (!EXCEPTION_ENABLE_SUPPORTED (FE_ALL_EXCEPT) && (res != 0)) { puts ("fesetenv (FE_NOMASK_ENV) not supported, cannot test."); return; } else if (res != 0) { puts ("fesetenv (FE_NOMASK_ENV) failed"); count_errors++; } if (fegetexcept () != FE_ALL_EXCEPT) { puts ("fesetenv did not set all exceptions"); count_errors++; } #endif }
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); }
int feupdateenv(const fenv_t *envp) { #pragma STDC FENV_ACCESS ON int ex = fetestexcept(FE_ALL_EXCEPT); fesetenv(envp); feraiseexcept(ex); return 0; }
void fixup_float_environment (void) { #ifdef HAVE_FESETENV if (scheme_fenv_p) (void) fesetenv (&scheme_fenv); #endif }
void ResumeFPE() { // Clear all exception flags. feclearexcept(FE_ALL_EXCEPT); // Now restore the previous floating point environment. fesetenv(&fpe_env); }
TEST(math, llround) { auto guard = make_scope_guard([]() { fesetenv(FE_DFL_ENV); }); fesetround(FE_UPWARD); // llround ignores the rounding mode. ASSERT_EQ(1234L, llround(1234.01)); ASSERT_EQ(1234L, llroundf(1234.01f)); ASSERT_EQ(1234L, llroundl(1234.01L)); }
int feupdateenv(const fenv_t *p) { unsigned long fsr; __fenv_getfsr(&fsr); (void) fesetenv(p); (void) feraiseexcept((int)__fenv_get_ex(fsr)); return 0; }
TEST(math_expf, expf_intel) { #if defined(__BIONIC__) fesetenv(FE_DFL_ENV); for (size_t i = 0; i < sizeof(g_expf_intel_data)/sizeof(expf_intel_data_t); i++) { EXPECT_FLOAT_EQ(g_expf_intel_data[i].expected, expf(g_expf_intel_data[i].call_data)) << "Failed on element " << i; } #else // __BIONIC__ GTEST_LOG_(INFO) << "This test does nothing."; #endif // __BIONIC__ }
int feclearexcept(int e) { fenv_t ft; fegetenv(&ft); ft.__status &= ~e; fesetenv(&ft); return 0; }
double nearbyint( double x ) { fenv_t oldEnv; feholdexcept( &oldEnv ); double result = rint( x ); fesetenv( &oldEnv ); return result; }
_STD_BEGIN int (feupdateenv)(const fenv_t *penv) { /* merge in stored floating-point environment */ int except = fetestexcept(FE_ALL_EXCEPT); fesetenv(penv); feraiseexcept(except); return (0); }
FlushToZero::~FlushToZero() { #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) unsigned int new_state; _controlfp_s(&new_state, _MCW_DN, previous_state); #elif defined(__APPLE__) fesetenv(&previous_state); #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) _mm_setcsr(_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK); #endif }
void FloatingPointEnvironment::enableDenormalSupport() { RELEASE_ASSERT(isUIThread()); #if defined _ARM_ARCH_7 fenv_t env; fegetenv(&env); env.__fpscr &= ~0x01000000U; fesetenv(&env); #endif // Supporting denormal mode is already the default on x86, x86_64, and ARM64. }
FlushToZero::FlushToZero() { #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) _controlfp_s(&previous_state, _MCW_DN, _DN_FLUSH); #elif defined(__APPLE__) fegetenv(&previous_state); fesetenv(FE_DFL_DISABLE_SSE_DENORMS_ENV); #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) previous_state = _mm_getcsr() & _MM_DENORMALS_ZERO_MASK; _mm_setcsr(_mm_getcsr() | (_MM_DENORMALS_ZERO_ON)); #endif }
TEST(math, roundf) { auto guard = make_scope_guard([]() { fesetenv(FE_DFL_ENV); }); fesetround(FE_TOWARDZERO); // roundf ignores the rounding mode and always rounds away from zero. ASSERT_FLOAT_EQ(1.0f, roundf(0.5f)); ASSERT_FLOAT_EQ(-1.0f, roundf(-0.5f)); ASSERT_FLOAT_EQ(0.0f, roundf(0.0f)); ASSERT_FLOAT_EQ(-0.0f, roundf(-0.0f)); ASSERT_TRUE(isnanf(roundf(nanf("")))); ASSERT_FLOAT_EQ(HUGE_VALF, roundf(HUGE_VALF)); }
TEST(math, roundl) { auto guard = make_scope_guard([]() { fesetenv(FE_DFL_ENV); }); fesetround(FE_TOWARDZERO); // roundl ignores the rounding mode and always rounds away from zero. ASSERT_DOUBLE_EQ(1.0L, roundl(0.5L)); ASSERT_DOUBLE_EQ(-1.0L, roundl(-0.5L)); ASSERT_DOUBLE_EQ(0.0L, roundl(0.0L)); ASSERT_DOUBLE_EQ(-0.0L, roundl(-0.0L)); ASSERT_TRUE(isnan(roundl(nanl("")))); ASSERT_DOUBLE_EQ(HUGE_VALL, roundl(HUGE_VALL)); }
static int fedisableexcept( unsigned int excepts ) { fenv_t fenv; unsigned int still_on = ~( (excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT ), old_excepts; // previous masks if ( fegetenv (&fenv) ) return -1; old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT; fenv &= still_on; return ( fesetenv (&fenv) ? -1 : old_excepts ); }
static int feenableexcept( unsigned int excepts ) { fenv_t fenv; unsigned int new_excepts = (excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT, old_excepts; // all previous masks if ( fegetenv (&fenv) ) return -1; old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT; fenv = (fenv & ~new_excepts) | new_excepts; return ( fesetenv (&fenv) ? -1 : old_excepts ); }
TEST(math, trunc) { auto guard = make_scope_guard([]() { fesetenv(FE_DFL_ENV); }); fesetround(FE_UPWARD); // trunc ignores the rounding mode and always rounds toward zero. ASSERT_DOUBLE_EQ(1.0, trunc(1.5)); ASSERT_DOUBLE_EQ(-1.0, trunc(-1.5)); ASSERT_DOUBLE_EQ(0.0, trunc(0.0)); ASSERT_DOUBLE_EQ(-0.0, trunc(-0.0)); ASSERT_TRUE(isnan(trunc(nan("")))); ASSERT_DOUBLE_EQ(HUGE_VAL, trunc(HUGE_VAL)); }
TEST(math, truncf) { auto guard = make_scope_guard([]() { fesetenv(FE_DFL_ENV); }); fesetround(FE_UPWARD); // truncf ignores the rounding mode and always rounds toward zero. ASSERT_FLOAT_EQ(1.0f, truncf(1.5f)); ASSERT_FLOAT_EQ(-1.0f, truncf(-1.5f)); ASSERT_FLOAT_EQ(0.0f, truncf(0.0f)); ASSERT_FLOAT_EQ(-0.0f, truncf(-0.0f)); ASSERT_TRUE(isnan(truncf(nanf("")))); ASSERT_FLOAT_EQ(HUGE_VALF, truncf(HUGE_VALF)); }
int fesetexceptflag(const fexcept_t *f, int e) { fenv_t ft; unsigned short sw; fegetenv(&ft); sw = *f; sw &= e; ft.__status_uint16_t = sw; fesetenv(&ft); return 0; }
/* * The feupdateenv() function saves the currently raised floating-point * exceptions in its automatic storage, installs the floating-point environment * represented by the object pointed to by `envp', and then raises the saved * floating-point exceptions. The argument `envp' shall point to an object set * by a call to feholdexcept() or fegetenv(), or equal a floating-point * environment macro. */ int feupdateenv(const fenv_t *envp) { int excepts = _softfloat_float_exception_flags; /* Install new floating-point environment */ fesetenv(envp); /* Raise any previously accumulated exceptions */ feraiseexcept(excepts); return (0); }
int fedisableexcept(unsigned int excepts) { static fenv_t fenv; unsigned int new_excepts = excepts & FE_ALL_EXCEPT, old_excepts; if (fegetenv(&fenv)) return -1; old_excepts = fenv.__control & FE_ALL_EXCEPT; // mask fenv.__control |= new_excepts; fenv.__mxcsr |= new_excepts << 7; return (fesetenv(&fenv) ? -1 : old_excepts); }
void primitive_reset_float_environment(void) { feclearexcept(FE_ALL_EXCEPT); #if defined OPEN_DYLAN_PLATFORM_FREEBSD || defined OPEN_DYLAN_PLATFORM_LINUX feenableexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INVALID); #elif defined OPEN_DYLAN_PLATFORM_DARWIN \ && (defined OPEN_DYLAN_ARCH_X86 || defined OPEN_DYLAN_ARCH_X86_64) fenv_t fenv; fegetenv(&fenv); fenv.__control &= ~(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INVALID); fenv.__mxcsr &= ~((FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INVALID) << 7); fesetenv(&fenv); #endif }