static void test_zeroes(void) { const int rd = (fegetround() == FE_DOWNWARD); testall(0.0, 0.0, 0.0, 0.0, ALL_STD_EXCEPT, 0); testall(1.0, 0.0, 0.0, 0.0, ALL_STD_EXCEPT, 0); testall(0.0, 1.0, 0.0, 0.0, ALL_STD_EXCEPT, 0); testall(0.0, 0.0, 1.0, 1.0, ALL_STD_EXCEPT, 0); testall(-0.0, 0.0, 0.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); testall(0.0, -0.0, 0.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); testall(-0.0, -0.0, 0.0, 0.0, ALL_STD_EXCEPT, 0); testall(0.0, 0.0, -0.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); testall(-0.0, -0.0, -0.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); testall(-0.0, 0.0, -0.0, -0.0, ALL_STD_EXCEPT, 0); testall(0.0, -0.0, -0.0, -0.0, ALL_STD_EXCEPT, 0); testall(-1.0, 1.0, 1.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); testall(1.0, -1.0, 1.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); testall(-1.0, -1.0, -1.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); switch (fegetround()) { case FE_TONEAREST: case FE_TOWARDZERO: test(fmaf, -FLT_MIN, FLT_MIN, 0.0, -0.0, ALL_STD_EXCEPT, FE_INEXACT | FE_UNDERFLOW); test(fma, -DBL_MIN, DBL_MIN, 0.0, -0.0, ALL_STD_EXCEPT, FE_INEXACT | FE_UNDERFLOW); test(fmal, -LDBL_MIN, LDBL_MIN, 0.0, -0.0, ALL_STD_EXCEPT, FE_INEXACT | FE_UNDERFLOW); } }
int main (int argc, char* argv[]) { int errors = 0; int mode_get = fegetround(); std::cout << "fegetround() = " << str(mode_get) << " " << std::endl; for (int i=0; i<4; i++) { int mode_set = modes[i]; fesetround (mode_set); std::cout << "fesetround (" << str(mode_set) << ")" << std::endl; int mode_get = fegetround(); std::cout << "fegetround() = " << str(mode_get) << " "; bool ok_get = mode_get == mode_set; if (!ok_get) errors++; std::cout << (ok_get ? "(ok)" : "(error)") << std::endl; int mode_test = fetestround(); std::cout << "fetestround() = " << str(mode_test) << " "; bool ok_test = mode_test == mode_set; if (!ok_test) errors++; std::cout << (ok_test ? "(ok)" : "(error)") << std::endl; } return errors; }
/* * 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); }
void do_parent(void) { ucontext_t dummy; int s; s = 1; /* Initialize FPU context and verify it's set to round to nearest. */ if (fegetround() != FE_TONEAREST) err(10, 1); /* Now we change the rounding to something else, and this should be preserved between context swaps. */ if (fesetround(FE_UPWARD) != 0) err(10, 2); /* Quick check to make sure that getcontext does not reset the FPU state. */ getcontext(&dummy); if (fegetround() != FE_UPWARD) err(10, 3); while(s < SWAPS) { do_calcs(); if (fegetround() != FE_UPWARD) err(10, 4); s++; if (swapcontext(&ctx[1], &ctx[2]) == -1) err(10, 5); } /* Returning to main thread through uc_link */ }
e_ieee754_rounding fenv_rounding() { #if defined LMI_IEC_559 int z = fegetround(); return (FE_TONEAREST == z) ? fe_tonearest : (FE_DOWNWARD == z) ? fe_downward : (FE_UPWARD == z) ? fe_upward : (FE_TOWARDZERO == z) ? fe_towardzero : throw std::runtime_error("Failed to determine rounding mode.") ; #elif defined __BORLANDC__ unsigned short int rc = (unsigned short int)(MCW_RC) & x87_control_word(); return (RC_NEAR == rc) ? fe_tonearest : (RC_DOWN == rc) ? fe_downward : (RC_UP == rc) ? fe_upward : (RC_CHOP == rc) ? fe_towardzero : throw std::runtime_error("Failed to determine rounding mode.") ; #elif defined LMI_X86 return intel_control_word(x87_control_word()).rc();; #else // Unknown compiler or platform. # error Unknown compiler or platform. #endif // Unknown compiler or platform. }
/* * Fused multiply-add: Compute x * y + z with a single rounding error. * * A double has more than twice as much precision than a float, so * direct double-precision arithmetic suffices, except where double * rounding occurs. */ DLLEXPORT float fmaf(float x, float y, float z) { double xy, result; u_int32_t hr, lr; xy = (double)x * y; result = xy + z; EXTRACT_WORDS(hr, lr, result); /* Common case: The double precision result is fine. */ if ((lr & 0x1fffffff) != 0x10000000 || /* not a halfway case */ (hr & 0x7ff00000) == 0x7ff00000 || /* NaN */ result - xy == z || /* exact */ fegetround() != FE_TONEAREST) /* not round-to-nearest */ return (result); /* * If result is inexact, and exactly halfway between two float values, * we need to adjust the low-order bit in the direction of the error. */ fesetround(FE_TOWARDZERO); volatile double vxy = xy; /* XXX work around gcc CSE bug */ double adjusted_result = vxy + z; fesetround(FE_TONEAREST); if (result == adjusted_result) SET_LOW_WORD(adjusted_result, lr + 1); return (adjusted_result); }
static TACommandVerdict expm1_adv_cmd(TAThread thread,TAInputStream stream) { double x, res; int current, rounding; ta_debug_printf("search for expm1 (182894194848)...\n"); // Prepare x = readDouble(&stream); rounding = readInt(&stream); errno = 0; current = fegetround(); START_TARGET_OPERATION(thread); fesetround(rounding * 1024); // Execute res = expm1(x); fesetround(current); END_TARGET_OPERATION(thread); // Response writeDouble(thread, res); writeInt(thread, errno); sendResponse(thread); return taDefaultVerdict; }
static TACommandVerdict acos_adv_cmd(TAThread thread,TAInputStream stream) { double x, res; int round; x = readDouble(&stream); round = readInt(&stream); START_TARGET_OPERATION(thread); fesetround(round * 1024); ta_debug_printf("search for acos (182894194848)...\n"); printf("Current settings = %d\n", fegetround()); printf("%e\n", x); errno = 0; res = acos(x); printf("%e\n", res); END_TARGET_OPERATION(thread); writeInt(thread, errno); writeDouble(thread, res); sendResponse(thread); return taDefaultVerdict; }
int main () { printf ("rounding using "); switch (fegetround()) { case FE_DOWNWARD: printf ("downward"); break; case FE_TONEAREST: printf ("to-nearest"); break; case FE_TOWARDZERO: printf ("toward-zero"); break; case FE_UPWARD: printf ("upward"); break; default: printf ("unknown"); } printf (" rounding:\n"); printf ( "lrint (2.3) = %ld\n", lrint(2.3) ); printf ( "lrint (3.8) = %ld\n", lrint(3.8) ); printf ( "lrint (-2.3) = %ld\n", lrint(-2.3) ); printf ( "lrint (-3.8) = %ld\n", lrint(-3.8) ); return 0; }
FloatingPointGuard() { oldMode = fegetround(); if (fesetround(FE_TONEAREST)) { throw FailedToSetFloatingPointMode("Failed to set floating point rounding mode to FE_TONEAREST"); } }
void current_rounding (void) { int ROUND_MODE; ROUND_MODE = fegetround(); printf("Current Round Mode = %d \n", ROUND_MODE ); }
int prim_fegetround() { #if !defined(HAVE_FEGETROUND) && !HAVE_DECL_FEGETROUND /* ToDo: stub */ sml_fatal(0, "fegetround is not implemented"); #else return fegetround(); #endif /* !HAVE_FEGETROUND */ }
FloatingStatus::FloatingStatus() { if (first_init) { stdrounding = fegetround(); fesetround(FE_UPWARD); first_init = false; } }
int main(int, char*[]) { std::cerr << "<DartMeasurement name=\"FE_DOWNWARD\" type=\"text/string\">" << FE_DOWNWARD << "</DartMeasurement>\n"; std::cerr << "<DartMeasurement name=\"FE_TONEAREST\" type=\"text/string\">" << FE_TONEAREST << "</DartMeasurement>\n"; std::cerr << "<DartMeasurement name=\"FE_TOWARDZERO\" type=\"text/string\">" << FE_TOWARDZERO << "</DartMeasurement>\n"; std::cerr << "<DartMeasurement name=\"FE_UPWARD\" type=\"text/string\">" << FE_UPWARD << "</DartMeasurement>\n"; std::cerr << "<DartMeasurement name=\"fegetround\" type=\"text/string\">" << fegetround() << "</DartMeasurement>\n"; return 0; }
void do_child(void) { int s; s = 1; /* Initialize FPU context and verify it's set to round to nearest. */ if (fegetround() != FE_TONEAREST) err(9, 1); /* Now we change the rounding to something else, and this should be preserved between context swaps. */ if (fesetround(FE_DOWNWARD) != 0) err(9, 2); while(s < SWAPS) { s++; if (swapcontext(&ctx[2], &ctx[1]) == -1) err(9, 2); do_calcs(); if (fegetround() != FE_DOWNWARD) err(9, 4); } }
NativeFPUControlType changeFPUControl(unsigned long mipsFlag) { NativeFPUControlType oldValue; oldValue = fegetround(); setFPUControl(mipsFlag); return oldValue; }
int m5_fegetround() { int x; int rm = fegetround(); for(x = 0; x < 4; x++) if (m5_round_ops[x] == rm) return x; abort(); return 0; }
int main() { float distance; int n; // parabolic fixed point zp = zpx = zpy*I = 0.5 for c=1/4 float zpx = 0.5; float zpy = 0.0; // z1 = z1x + z1y*I = point of exterior of Julia set but near parabolic fixed point zp float z1x; float z1y = zpy; float cx= 0.25; float cy= 0.0; // Escape Radius ; it defines target set = { z: abs(z)>ER} // all points z in the target set are escaping to infinity float ER=2.0; float ER2; float LastIteration; time_t start,end; float dif; ER2= ER*ER; printf ("Using c with float and Escape Radius = %f \n", ER); printf("FLT_EPSILON = %e = %40.38f \n",FLT_EPSILON , FLT_EPSILON ); printf("Round mode is = %d \n",fegetround()); n=12; //for (n =12; n<101; n++) { time (&start); distance = pow(2.0,-n); z1x = 0.50020; //zpx + distance; printf("n= %d; Zpx = %f; z1x = %f ; z1x2 = %f\n", n,zpx, z1x, z1x*z1x); LastIteration = GiveLastIteration(z1x,z1y, cx,cy,ER2 ); time (&end); dif = difftime (end,start); printf("n= %3d distance = %e = %.10f LI = %10.0f log2(LI) = %3.0f time = %2.0lf seconds\n",n, distance, distance, LastIteration, log2(LastIteration), dif); } return 0; }
// C99 version. This is becoming the most common. static int getrounding(TaskData *) { switch (fegetround()) { case FE_TONEAREST: return POLY_ROUND_TONEAREST; case FE_DOWNWARD: return POLY_ROUND_DOWNWARD; case FE_UPWARD: return POLY_ROUND_UPWARD; case FE_TOWARDZERO: return POLY_ROUND_TOZERO; } return 0; // Keep the compiler happy }
void dmtcp_ProcessInfo_EventHook(DmtcpEvent_t event, DmtcpEventData_t *data) { switch (event) { case DMTCP_EVENT_INIT: dmtcp::ProcessInfo::instance().init(); break; case DMTCP_EVENT_PRE_EXEC: { jalib::JBinarySerializeWriterRaw wr("", data->serializerInfo.fd); dmtcp::ProcessInfo::instance().refresh(); dmtcp::ProcessInfo::instance().serialize(wr); } break; case DMTCP_EVENT_POST_EXEC: { jalib::JBinarySerializeReaderRaw rd("", data->serializerInfo.fd); dmtcp::ProcessInfo::instance().serialize(rd); dmtcp::ProcessInfo::instance().postExec(); } break; case DMTCP_EVENT_DRAIN: dmtcp::ProcessInfo::instance().refresh(); break; case DMTCP_EVENT_RESTART: fesetround(roundingMode); dmtcp::ProcessInfo::instance().restart(); break; case DMTCP_EVENT_REFILL: if (data->refillInfo.isRestart) { dmtcp::ProcessInfo::instance().restoreProcessGroupInfo(); } break; case DMTCP_EVENT_THREADS_SUSPEND: roundingMode = fegetround(); break; case DMTCP_EVENT_THREADS_RESUME: if (data->refillInfo.isRestart) { _real_close(PROTECTED_ENVIRON_FD); } break; default: break; } }
static int do_test (void) { int save_round_mode __attribute__ ((unused)) = fegetround (); int result = 0; #ifdef FE_TONEAREST const int fe_tonearest = FE_TONEAREST; #else const int fe_tonearest = 0; # if defined FE_DOWNWARD || defined FE_TOWARDZERO || defined FE_UPWARD # error "FE_TONEAREST not defined, but another rounding mode is" # endif #endif #ifdef FE_UNDERFLOW feclearexcept (FE_ALL_EXCEPT); dd = d * d; if (fetestexcept (FE_UNDERFLOW)) support_underflow_exception = true; else puts ("underflow exception not supported at runtime, only testing errno"); #endif for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); i++) { result |= test_in_one_mode (tests[i].s, tests[i].c, fe_tonearest, "default rounding mode"); #ifdef FE_DOWNWARD if (!fesetround (FE_DOWNWARD)) { result |= test_in_one_mode (tests[i].s, tests[i].c, FE_DOWNWARD, "FE_DOWNWARD"); fesetround (save_round_mode); } #endif #ifdef FE_TOWARDZERO if (!fesetround (FE_TOWARDZERO)) { result |= test_in_one_mode (tests[i].s, tests[i].c, FE_TOWARDZERO, "FE_TOWARDZERO"); fesetround (save_round_mode); } #endif #ifdef FE_UPWARD if (!fesetround (FE_UPWARD)) { result |= test_in_one_mode (tests[i].s, tests[i].c, FE_UPWARD, "FE_UPWARD"); fesetround (save_round_mode); } #endif } return result; }
/* * Calculates an interval for a + b. * interval[0] <= a + b * a + b <= interval[1] */ void safe_add(volatile double interval[2], volatile double a, volatile double b) { #pragma STDC FENV_ACCESS ON unsigned int orig; orig = fegetround(); fesetround(FE_DOWNWARD); /* round to -infinity */ interval[0] = a + b; fesetround(FE_UPWARD); /* round to +infinity */ interval[1] = a + b; fesetround(orig); }
int main() { #ifdef FE_DOWNWARD fesetround(FE_DOWNWARD); assert(fegetround()==FE_DOWNWARD); #endif #ifdef FE_TONEAREST fesetround(FE_TONEAREST); assert(fegetround()==FE_TONEAREST); #endif #ifdef FE_TOWARDZERO fesetround(FE_TOWARDZERO); assert(fegetround()==FE_TOWARDZERO); #endif #ifdef FE_UPWARD fesetround(FE_UPWARD); assert(fegetround()==FE_UPWARD); #endif }
static void check_fpu() { switch (fegetround()) { case FE_TONEAREST: break; case FE_DOWNWARD: std::cerr << "Floating point precision mode is currently 'downward'"; goto reset_fpu; case FE_TOWARDZERO: std::cerr << "Floating point precision mode is currently 'toward-zero'"; goto reset_fpu; case FE_UPWARD: std::cerr << "Floating point precision mode is currently 'upward'"; goto reset_fpu; default: std::cerr << "Floating point precision mode is currently 'unknown'"; goto reset_fpu; reset_fpu: std::cerr << "setting to 'nearest'"; fesetround(FE_TONEAREST); break; } }
/* * Test fegetenv() and fesetenv(). * * Prerequisites: fetestexcept(), feclearexcept(), fegetround(), fesetround() */ static void test_fegsetenv(void) { fenv_t env1, env2; int excepts, i; for (i = 0; i < 1 << NEXCEPTS; i++) { excepts = std_except_sets[i]; assert(fetestexcept(FE_ALL_EXCEPT) == 0); assert(fegetround() == FE_TONEAREST); assert(fegetenv(&env1) == 0); /* * fe[gs]etenv() should be able to save and restore * exception flags without the spurious inexact * exceptions that afflict raiseexcept(). */ raiseexcept(excepts); if ((excepts & (FE_UNDERFLOW | FE_OVERFLOW)) != 0 && (excepts & FE_INEXACT) == 0) assert(feclearexcept(FE_INEXACT) == 0); fesetround(FE_DOWNWARD); assert(fegetenv(&env2) == 0); assert(fesetenv(&env1) == 0); assert(fetestexcept(FE_ALL_EXCEPT) == 0); assert(fegetround() == FE_TONEAREST); assert(fesetenv(&env2) == 0); assert(fetestexcept(FE_ALL_EXCEPT) == excepts); assert(fegetround() == FE_DOWNWARD); assert(fesetenv(&env1) == 0); assert(fetestexcept(FE_ALL_EXCEPT) == 0); assert(fegetround() == FE_TONEAREST); } }
/* * Tests for cases where z is very large compared to x*y. */ static void test_big_z(void) { /* z positive, x*y positive */ if (fegetround() == FE_UPWARD) { test(fmaf, 0x1.0p-50, 0x1.0p-50, 1.0, 1.0 + FLT_EPSILON, ALL_STD_EXCEPT, FE_INEXACT); test(fma, 0x1.0p-100, 0x1.0p-100, 1.0, 1.0 + DBL_EPSILON, ALL_STD_EXCEPT, FE_INEXACT); test(fmal, 0x1.0p-100, 0x1.0p-100, 1.0, 1.0 + LDBL_EPSILON, ALL_STD_EXCEPT, FE_INEXACT); } else { testall(-0x1.0p-50, -0x1.0p-50, 0x1.0p100, 0x1.0p100, ALL_STD_EXCEPT, FE_INEXACT); } /* z negative, x*y negative */ if (fegetround() == FE_DOWNWARD) { test(fmaf, -0x1.0p-50, 0x1.0p-50, -1.0, -(1.0 + FLT_EPSILON), ALL_STD_EXCEPT, FE_INEXACT); test(fma, -0x1.0p-100, 0x1.0p-100, -1.0, -(1.0 + DBL_EPSILON), ALL_STD_EXCEPT, FE_INEXACT); test(fmal, -0x1.0p-100, 0x1.0p-100, -1.0, -(1.0 + LDBL_EPSILON), ALL_STD_EXCEPT, FE_INEXACT); } else { testall(0x1.0p-50, -0x1.0p-50, -0x1.0p100, -0x1.0p100, ALL_STD_EXCEPT, FE_INEXACT); } /* z negative, x*y positive */ if (fegetround() == FE_UPWARD || fegetround() == FE_TOWARDZERO) { test(fmaf, -0x1.0p-50, -0x1.0p-50, -1.0, -1.0 + FLT_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); test(fma, -0x1.0p-100, -0x1.0p-100, -1.0, -1.0 + DBL_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); test(fmal, -0x1.0p-100, -0x1.0p-100, -1.0, -1.0 + LDBL_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); } else { testall(0x1.0p-50, 0x1.0p-50, -0x1.0p100, -0x1.0p100, ALL_STD_EXCEPT, FE_INEXACT); } /* z positive, x*y negative */ if (fegetround() == FE_DOWNWARD || fegetround() == FE_TOWARDZERO) { test(fmaf, 0x1.0p-50, -0x1.0p-50, 1.0, 1.0 - FLT_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); test(fma, 0x1.0p-100, -0x1.0p-100, 1.0, 1.0 - DBL_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); test(fmal, 0x1.0p-100, -0x1.0p-100, 1.0, 1.0 - LDBL_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); } else { testall(-0x1.0p-50, 0x1.0p-50, 0x1.0p100, 0x1.0p100, ALL_STD_EXCEPT, FE_INEXACT); } }
static T nbint_impl(T value) { switch (fegetround()) { case FE_DOWNWARD: return std::floor(value); case FE_UPWARD: return std::ceil(value); case FE_TOWARDZERO: return mwg::stdm::trunc(value); case FE_TONEAREST: default: if (mwg::stdm::isnan(value)) return value; T const ret = std::floor(value); T const frac = value - ret; return (frac == (T) 0.5? mwg::stdm::trunc(ret * (T) 0.5) == ret * (T) 0.5: frac < (T) 0.5)? ret: ret + T(1.0); } }
static int do_test (void) { #if defined FE_TONEAREST && defined FE_TOWARDZERO if (fesetround (FE_TONEAREST) == 0) { if (setjmp (env) == 0) change_rounding_mode (); else { if (fegetround () == expected_rounding_mode) puts ("PASS: longjmp preserved rounding mode"); else { puts ("FAIL: longjmp changed rounding mode"); result = 1; } } } else puts ("fesetround (FE_TONEAREST) failed, not testing rounding modes"); #else puts ("rounding mode test not supported"); #endif #ifdef FE_INVALID if (feclearexcept (FE_ALL_EXCEPT) == 0) { if (setjmp (env) == 0) raise_exception (); else { if (fetestexcept (FE_INVALID) == expected_exceptions) puts ("PASS: longjmp preserved exceptions"); else { puts ("FAIL: longjmp changed exceptions"); result = 1; } } } else puts ("feclearexcept (FE_ALL_EXCEPT) failed, not testing exceptions"); #else puts ("exception test not supported"); #endif return result; }
static void test_rounding (const char *test_name, int rounding_mode) { int curr_rounding = fegetround (); printf ("Test: %s\n", test_name); if (curr_rounding == rounding_mode) { printf (" Pass: Rounding mode is "); print_rounding (curr_rounding); } else { ++count_errors; printf (" Fail: Rounding mode is "); print_rounding (curr_rounding); } }
/* _lib7_Math_ctlrndmode : int option -> int * * Get/set the rounding mode; the values are interpreted as follows: * * 0 To nearest * 1 To zero * 2 To +Inf * 3 To -Inf */ lib7_val_t _lib7_Math_ctlrndmode (lib7_state_t *lib7_state, lib7_val_t arg) { #ifdef NO_ROUNDING_MODE_CTL return RAISE_ERROR(lib7_state, "Rounding mode control not supported"); #else if (arg == OPTION_NONE) { fe_rnd_mode_t res = fegetround(); return RMODE_CtoLib7(res); } else { fe_rnd_mode_t m = RMODE_LIB7toC(OPTION_get(arg)); fe_rnd_mode_t res = fesetround(m); return RMODE_CtoLib7(res); } #endif } /* end of _lib7_Math_ctlrndmode */