TEST(fenv, fesetround_fegetround_FE_DOWNWARD) { fesetround(FE_DOWNWARD); ASSERT_EQ(FE_DOWNWARD, fegetround()); TestRounding(8388609.0f, 1.0f); }
/* * Fused multiply-add: Compute x * y + z with a single rounding error. * * We use scaling to avoid overflow/underflow, along with the * canonical precision-doubling technique adapted from: * * Dekker, T. A Floating-Point Technique for Extending the * Available Precision. Numer. Math. 18, 224-242 (1971). */ long double fmal(long double x, long double y, long double z) { long double xs, ys, zs, adj; struct dd xy, r; int oround; int ex, ey, ez; int spread; /* * Handle special cases. The order of operations and the particular * return values here are crucial in handling special cases involving * infinities, NaNs, overflows, and signed zeroes correctly. */ if (x == 0.0 || y == 0.0) return (x * y + z); if (z == 0.0) return (x * y); if (!isfinite(x) || !isfinite(y)) return (x * y + z); if (!isfinite(z)) return (z); xs = frexpl(x, &ex); ys = frexpl(y, &ey); zs = frexpl(z, &ez); oround = fegetround(); spread = ex + ey - ez; /* * If x * y and z are many orders of magnitude apart, the scaling * will overflow, so we handle these cases specially. Rounding * modes other than FE_TONEAREST are painful. */ if (spread < -LDBL_MANT_DIG) { feraiseexcept(FE_INEXACT); if (!isnormal(z)) feraiseexcept(FE_UNDERFLOW); switch (oround) { case FE_TONEAREST: return (z); case FE_TOWARDZERO: if (x > 0.0 ^ y < 0.0 ^ z < 0.0) return (z); else return (nextafterl(z, 0)); case FE_DOWNWARD: if (x > 0.0 ^ y < 0.0) return (z); else return (nextafterl(z, -INFINITY)); default: /* FE_UPWARD */ if (x > 0.0 ^ y < 0.0) return (nextafterl(z, INFINITY)); else return (z); } } if (spread <= LDBL_MANT_DIG * 2) zs = ldexpl(zs, -spread); else zs = copysignl(LDBL_MIN, zs); fesetround(FE_TONEAREST); /* work around clang bug 8100 */ volatile long double vxs = xs; /* * Basic approach for round-to-nearest: * * (xy.hi, xy.lo) = x * y (exact) * (r.hi, r.lo) = xy.hi + z (exact) * adj = xy.lo + r.lo (inexact; low bit is sticky) * result = r.hi + adj (correctly rounded) */ xy = dd_mul(vxs, ys); r = dd_add(xy.hi, zs); spread = ex + ey; if (r.hi == 0.0) { /* * When the addends cancel to 0, ensure that the result has * the correct sign. */ fesetround(oround); volatile long double vzs = zs; /* XXX gcc CSE bug workaround */ return (xy.hi + vzs + ldexpl(xy.lo, spread)); } if (oround != FE_TONEAREST) { /* * There is no need to worry about double rounding in directed * rounding modes. */ fesetround(oround); /* work around clang bug 8100 */ volatile long double vrlo = r.lo; adj = vrlo + xy.lo; return (ldexpl(r.hi + adj, spread)); } adj = add_adjusted(r.lo, xy.lo); if (spread + ilogbl(r.hi) > -16383) return (ldexpl(r.hi + adj, spread)); else return (add_and_denormalize(r.hi, adj, spread)); }
static void set_rounding_mode(const rounding_mode& mode) { fesetround(mode); }
/* * Fused multiply-add: Compute x * y + z with a single rounding error. * * We use scaling to avoid overflow/underflow, along with the * canonical precision-doubling technique adapted from: * * Dekker, T. A Floating-Point Technique for Extending the * Available Precision. Numer. Math. 18, 224-242 (1971). */ long double fmal(long double x, long double y, long double z) { #if LDBL_MANT_DIG == 64 static const long double split = 0x1p32L + 1.0; #elif LDBL_MANT_DIG == 113 static const long double split = 0x1p57L + 1.0; #endif long double xs, ys, zs; long double c, cc, hx, hy, p, q, tx, ty; long double r, rr, s; int oround; int ex, ey, ez; int spread; if (z == 0.0) return (x * y); if (x == 0.0 || y == 0.0) return (x * y + z); /* Results of frexp() are undefined for these cases. */ if (!isfinite(x) || !isfinite(y) || !isfinite(z)) return (x * y + z); xs = frexpl(x, &ex); ys = frexpl(y, &ey); zs = frexpl(z, &ez); oround = fegetround(); spread = ex + ey - ez; /* * If x * y and z are many orders of magnitude apart, the scaling * will overflow, so we handle these cases specially. Rounding * modes other than FE_TONEAREST are painful. */ if (spread > LDBL_MANT_DIG * 2) { fenv_t env; feraiseexcept(FE_INEXACT); switch(oround) { case FE_TONEAREST: return (x * y); case FE_TOWARDZERO: if (x > 0.0 ^ y < 0.0 ^ z < 0.0) return (x * y); feholdexcept(&env); r = x * y; if (!fetestexcept(FE_INEXACT)) r = nextafterl(r, 0); feupdateenv(&env); return (r); case FE_DOWNWARD: if (z > 0.0) return (x * y); feholdexcept(&env); r = x * y; if (!fetestexcept(FE_INEXACT)) r = nextafterl(r, -INFINITY); feupdateenv(&env); return (r); default: /* FE_UPWARD */ if (z < 0.0) return (x * y); feholdexcept(&env); r = x * y; if (!fetestexcept(FE_INEXACT)) r = nextafterl(r, INFINITY); feupdateenv(&env); return (r); } } if (spread < -LDBL_MANT_DIG) { feraiseexcept(FE_INEXACT); if (!isnormal(z)) feraiseexcept(FE_UNDERFLOW); switch (oround) { case FE_TONEAREST: return (z); case FE_TOWARDZERO: if (x > 0.0 ^ y < 0.0 ^ z < 0.0) return (z); else return (nextafterl(z, 0)); case FE_DOWNWARD: if (x > 0.0 ^ y < 0.0) return (z); else return (nextafterl(z, -INFINITY)); default: /* FE_UPWARD */ if (x > 0.0 ^ y < 0.0) return (nextafterl(z, INFINITY)); else return (z); } } /* * Use Dekker's algorithm to perform the multiplication and * subsequent addition in twice the machine precision. * Arrange so that x * y = c + cc, and x * y + z = r + rr. */ fesetround(FE_TONEAREST); p = xs * split; hx = xs - p; hx += p; tx = xs - hx; p = ys * split; hy = ys - p; hy += p; ty = ys - hy; p = hx * hy; q = hx * ty + tx * hy; c = p + q; cc = p - c + q + tx * ty; zs = ldexpl(zs, -spread); r = c + zs; s = r - c; rr = (c - (r - s)) + (zs - s) + cc; spread = ex + ey; if (spread + ilogbl(r) > -16383) { fesetround(oround); r = r + rr; } else { /* * The result is subnormal, so we round before scaling to * avoid double rounding. */ p = ldexpl(copysignl(0x1p-16382L, r), -spread); c = r + p; s = c - r; cc = (r - (c - s)) + (p - s) + rr; fesetround(oround); r = (c + cc) - p; } return (ldexpl(r, spread)); }
static bool fmaSingle(cpu::Core *state, Instruction instr, float *result) { double a, b, c; if (slotAB == 0) { a = state->fpr[instr.frA].paired0; b = state->fpr[instr.frB].paired0; } else { a = state->fpr[instr.frA].paired1; b = state->fpr[instr.frB].paired1; } if (slotC == 0) { c = state->fpr[instr.frC].paired0; } else { c = state->fpr[instr.frC].paired1; } const double addend = (flags & FMASubtract) ? -b : b; const bool vxsnan = is_signalling_nan(a) || is_signalling_nan(b) || is_signalling_nan(c); const bool vximz = (is_infinity(a) && is_zero(c)) || (is_zero(a) && is_infinity(c)); const bool vxisi = (!vximz && !is_nan(a) && !is_nan(c) && (is_infinity(a) || is_infinity(c)) && is_infinity(b) && (std::signbit(a) ^ std::signbit(c)) != std::signbit(addend)); state->fpscr.vxsnan |= vxsnan; state->fpscr.vxisi |= vxisi; state->fpscr.vximz |= vximz; if ((vxsnan || vxisi || vximz) && state->fpscr.ve) { return false; } float d; if (is_nan(a)) { d = make_quiet(truncate_double(a)); } else if (is_nan(b)) { d = make_quiet(truncate_double(b)); } else if (is_nan(c)) { d = make_quiet(truncate_double(c)); } else if (vxisi || vximz) { d = make_nan<float>(); } else { if (slotC == 0) { roundForMultiply(&a, &c); // Not necessary for slot 1. } double d64 = std::fma(a, c, addend); if (state->fpscr.rn == espresso::FloatingPointRoundMode::Nearest) { d = roundFMAResultToSingle(d64, a, addend, c); } else { d = static_cast<float>(d64); } if (possibleUnderflow<float>(d)) { const int oldRound = fegetround(); fesetround(FE_TOWARDZERO); volatile double addendTemp = addend; volatile float dummy; dummy = (float)std::fma(a, c, addendTemp); fesetround(oldRound); } if (flags & FMANegate) { d = -d; } } *result = d; return true; }
int main(void) { int rmodes[] = { FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO }; unsigned i, j; #if defined(__i386__) printf("1..0 # SKIP all testcases fail on i386\n"); exit(0); #endif j = 1; printf("1..19\n"); for (i = 0; i < nitems(rmodes); i++, j++) { printf("rmode = %d\n", rmodes[i]); fesetround(rmodes[i]); test_zeroes(); printf("ok %d - fma zeroes\n", j); } for (i = 0; i < nitems(rmodes); i++, j++) { #if defined(__amd64__) printf("ok %d # SKIP testcase fails assertion on " "amd64\n", j); continue; #else printf("rmode = %d\n", rmodes[i]); fesetround(rmodes[i]); test_infinities(); printf("ok %d - fma infinities\n", j); #endif } fesetround(FE_TONEAREST); test_nans(); printf("ok %d - fma NaNs\n", j); j++; for (i = 0; i < nitems(rmodes); i++, j++) { printf("rmode = %d\n", rmodes[i]); fesetround(rmodes[i]); test_small_z(); printf("ok %d - fma small z\n", j); } for (i = 0; i < nitems(rmodes); i++, j++) { printf("rmode = %d\n", rmodes[i]); fesetround(rmodes[i]); test_big_z(); printf("ok %d - fma big z\n", j); } fesetround(FE_TONEAREST); test_accuracy(); printf("ok %d - fma accuracy\n", j); j++; test_double_rounding(); printf("ok %d - fma double rounding\n", j); j++; /* * TODO: * - Tests for subnormals * - Cancellation tests (e.g., z = (double)x*y, but x*y is inexact) */ return (0); }
int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { int mode; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: GSL_ERROR ("single precision rounding is not supported by <fenv.h>", GSL_EUNSUP) ; break ; case GSL_IEEE_DOUBLE_PRECISION: GSL_ERROR ("double precision rounding is not supported by <fenv.h>", GSL_EUNSUP) ; break ; case GSL_IEEE_EXTENDED_PRECISION: GSL_ERROR ("extended precision rounding is not supported by <fenv.h>", GSL_EUNSUP) ; break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: #ifdef FE_TONEAREST fesetround (FE_TONEAREST) ; #else GSL_ERROR ("round-to-nearest is not supported by <fenv.h>", GSL_EUNSUP) ; #endif break ; case GSL_IEEE_ROUND_DOWN: #ifdef FE_DOWNWARD fesetround (FE_DOWNWARD) ; #else GSL_ERROR ("round-down is not supported by <fenv.h>", GSL_EUNSUP) ; #endif break ; case GSL_IEEE_ROUND_UP: #ifdef FE_UPWARD fesetround (FE_UPWARD) ; #else GSL_ERROR ("round-up is not supported by <fenv.h>", GSL_EUNSUP) ; #endif break ; case GSL_IEEE_ROUND_TO_ZERO: #ifdef FE_TOWARDZERO fesetround (FE_TOWARDZERO) ; #else GSL_ERROR ("round-toward-zero is not supported by <fenv.h>", GSL_EUNSUP) ; #endif break ; default: #ifdef FE_TONEAREST fesetround (FE_TONEAREST) ; #else GSL_ERROR ("default round-to-nearest mode is not supported by <fenv.h>", GSL_EUNSUP) ; #endif } /* Turn on all the exceptions apart from 'inexact' */ mode = 0; #ifdef FE_INVALID mode |= FE_INVALID; #endif #ifdef FE_DIVBYZERO mode |= FE_DIVBYZERO; #endif #ifdef FE_OVERFLOW mode |= FE_OVERFLOW ; #endif #ifdef FE_UNDERFLOW mode |= FE_UNDERFLOW ; #endif if (exception_mask & GSL_IEEE_MASK_INVALID) { #ifdef FE_INVALID mode &= ~ FE_INVALID ; #else GSL_ERROR ("invalid operation exception not supported by <fenv.h>", GSL_EUNSUP); #endif } if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { /* do nothing */ } else { GSL_ERROR ("denormalized operand exception not supported by <fenv.h>. " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP) ; } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) { #ifdef FE_DIVBYZERO mode &= ~ FE_DIVBYZERO ; #else GSL_ERROR ("division by zero exception not supported by <fenv.h>", GSL_EUNSUP); #endif } if (exception_mask & GSL_IEEE_MASK_OVERFLOW) { #ifdef FE_OVERFLOW mode &= ~ FE_OVERFLOW ; #else GSL_ERROR ("overflow exception not supported by <fenv.h>", GSL_EUNSUP); #endif } if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) { #ifdef FE_UNDERFLOW mode &= ~ FE_UNDERFLOW ; #else GSL_ERROR ("underflow exception not supported by <fenv.h>", GSL_EUNSUP); #endif } if (exception_mask & GSL_IEEE_TRAP_INEXACT) { #ifdef FE_INEXACT mode |= FE_INEXACT ; #else GSL_ERROR ("inexact exception not supported by <fenv.h>", GSL_EUNSUP); #endif } else { #ifdef FE_INEXACT mode &= ~ FE_INEXACT ; #else /* do nothing */ #endif } #if HAVE_DECL_FEENABLEEXCEPT feenableexcept (mode) ; #elif HAVE_DECL_FESETTRAPENABLE fesettrapenable (mode); #else GSL_ERROR ("unknown exception trap method", GSL_EUNSUP) #endif return GSL_SUCCESS ; }
float __ieee754_expf (float x) { static const float himark = 88.72283935546875; static const float lomark = -103.972084045410; /* Check for usual case. */ if (isless (x, himark) && isgreater (x, lomark)) { static const float THREEp42 = 13194139533312.0; static const float THREEp22 = 12582912.0; /* 1/ln(2). */ #undef M_1_LN2 static const float M_1_LN2 = 1.44269502163f; /* ln(2) */ #undef M_LN2 static const double M_LN2 = .6931471805599452862; int tval; double x22, t, result, dx; float n, delta; union ieee754_double ex2_u; fenv_t oldenv; feholdexcept (&oldenv); #ifdef FE_TONEAREST fesetround (FE_TONEAREST); #endif /* Calculate n. */ n = x * M_1_LN2 + THREEp22; n -= THREEp22; dx = x - n*M_LN2; /* Calculate t/512. */ t = dx + THREEp42; t -= THREEp42; dx -= t; /* Compute tval = t. */ tval = (int) (t * 512.0); if (t >= 0) delta = - __exp_deltatable[tval]; else delta = __exp_deltatable[-tval]; /* Compute ex2 = 2^n e^(t/512+delta[t]). */ ex2_u.d = __exp_atable[tval+177]; ex2_u.ieee.exponent += (int) n; /* Approximate e^(dx+delta) - 1, using a second-degree polynomial, with maximum error in [-2^-10-2^-28,2^-10+2^-28] less than 5e-11. */ x22 = (0.5000000496709180453 * dx + 1.0000001192102037084) * dx + delta; /* Return result. */ fesetenv (&oldenv); result = x22 * ex2_u.d + ex2_u.d; return (float) result; } /* Exceptional cases: */ else if (isless (x, himark)) { if (__isinff (x)) /* e^-inf == 0, with no error. */ return 0; else /* Underflow */ return TWOM100 * TWOM100; } else /* Return x, if x is a NaN or Inf; or overflow, otherwise. */ return TWO127*x; }
void m5_fesetround(int rm) { assert(rm >= 0 && rm < 4); fesetround(m5_round_ops[rm]); }
long double sqrtl(long double x) { union IEEEl2bits u; int k, r; long double lo, xn; fenv_t env; u.e = x; /* If x = NaN, then sqrt(x) = NaN. */ /* If x = Inf, then sqrt(x) = Inf. */ /* If x = -Inf, then sqrt(x) = NaN. */ if (u.bits.exp == LDBL_MAX_EXP * 2 - 1) return (x * x + x); /* If x = +-0, then sqrt(x) = +-0. */ if ((u.bits.manh | u.bits.manl | u.bits.exp) == 0) return (x); /* If x < 0, then raise invalid and return NaN */ if (u.bits.sign) return ((x - x) / (x - x)); feholdexcept(&env); if (u.bits.exp == 0) { /* Adjust subnormal numbers. */ u.e *= 0x1.0p514; k = -514; } else { k = 0; } /* * u.e is a normal number, so break it into u.e = e*2^n where * u.e = (2*e)*2^2k for odd n and u.e = (4*e)*2^2k for even n. */ if ((u.bits.exp - 0x3ffe) & 1) { /* n is odd. */ k += u.bits.exp - 0x3fff; /* 2k = n - 1. */ u.bits.exp = 0x3fff; /* u.e in [1,2). */ } else { k += u.bits.exp - 0x4000; /* 2k = n - 2. */ u.bits.exp = 0x4000; /* u.e in [2,4). */ } /* * Newton's iteration. * Split u.e into a high and low part to achieve additional precision. */ xn = sqrt(u.e); /* 53-bit estimate of sqrtl(x). */ #if LDBL_MANT_DIG > 100 xn = (xn + (u.e / xn)) * 0.5; /* 106-bit estimate. */ #endif lo = u.e; u.bits.manl = 0; /* Zero out lower bits. */ lo = (lo - u.e) / xn; /* Low bits divided by xn. */ xn = xn + (u.e / xn); /* High portion of estimate. */ u.e = xn + lo; /* Combine everything. */ u.bits.exp += (k >> 1) - 1; feclearexcept(FE_INEXACT); r = fegetround(); fesetround(FE_TOWARDZERO); /* Set to round-toward-zero. */ xn = x / u.e; /* Chopped quotient (inexact?). */ if (!fetestexcept(FE_INEXACT)) { /* Quotient is exact. */ if (xn == u.e) { fesetenv(&env); return (u.e); } /* Round correctly for inputs like x = y**2 - ulp. */ xn = dec(xn); /* xn = xn - ulp. */ } if (r == FE_TONEAREST) { xn = inc(xn); /* xn = xn + ulp. */ } else if (r == FE_UPWARD) { u.e = inc(u.e); /* u.e = u.e + ulp. */ xn = inc(xn); /* xn = xn + ulp. */ } u.e = u.e + xn; /* Chopped sum. */ feupdateenv(&env); /* Restore env and raise inexact */ u.bits.exp--; return (u.e); }
long double __rintl (long double x) { double xh, xl, hi, lo; ldbl_unpack (x, &xh, &xl); /* Return Inf, Nan, +/-0 unchanged. */ if (__builtin_expect (xh != 0.0 && __builtin_isless (__builtin_fabs (xh), __builtin_inf ()), 1)) { double orig_xh; int save_round = fegetround (); /* Long double arithmetic, including the canonicalisation below, only works in round-to-nearest mode. */ fesetround (FE_TONEAREST); /* Convert the high double to integer. */ orig_xh = xh; hi = ldbl_nearbyint (xh); /* Subtract integral high part from the value. If the low double happens to be exactly 0.5 or -0.5, you might think that this subtraction could result in an incorrect conversion. For instance, subtracting an odd number would cause this function to round in the wrong direction. However, if we have a canonical long double with the low double 0.5 or -0.5, then the high double must be even. */ xh -= hi; ldbl_canonicalize (&xh, &xl); /* Now convert the low double, adjusted for any remainder from the high double. */ lo = ldbl_nearbyint (xh); xh -= lo; ldbl_canonicalize (&xh, &xl); switch (save_round) { case FE_TONEAREST: if (xl > 0.0 && xh == 0.5) lo += 1.0; else if (xl < 0.0 && -xh == 0.5) lo -= 1.0; break; case FE_TOWARDZERO: if (orig_xh < 0.0) goto do_up; /* Fall thru */ case FE_DOWNWARD: if (xh < 0.0 || (xh == 0.0 && xl < 0.0)) lo -= 1.0; break; case FE_UPWARD: do_up: if (xh > 0.0 || (xh == 0.0 && xl > 0.0)) lo += 1.0; break; } /* Ensure the final value is canonical. In certain cases, rounding causes hi,lo calculated so far to be non-canonical. */ xh = hi; xl = lo; ldbl_canonicalize (&xh, &xl); /* Ensure we return -0 rather than +0 when appropriate. */ if (orig_xh < 0.0) xh = -__builtin_fabs (xh); fesetround (save_round); } return ldbl_pack (xh, xl); }
void contractor_gsl::prune(box & b, SMTConfig & config) { // TODO(soonhok): add timeout fesetround(FE_TONEAREST); // Without this, GSL might cause a segmentation fault due to problems in floating point lib gsl_odeiv2_step_reset(m_step); gsl_odeiv2_evolve_reset(m_evolve); double const T_lb = b[m_time_t].lb(); double const T_ub = b[m_time_t].ub(); double t = 0.0, old_t = 0.0; /* initialize t */ double T_next = 0.0; double h = 1e-10; /* starting step size for ode solver */ DREAL_LOG_INFO << "GSL: prune begin " << m_time_t << " = [" << T_lb << ", " << T_ub << "]" << "\t" << b.max_diam(); DREAL_LOG_INFO << m_ctr->get_ic(); if (b.max_diam() < config.nra_precision) { return; } bool need_to_run = false; for (Enode * e : m_vars_0) { if (b[e].diam() > config.nra_precision) { need_to_run = true; break; } } if (b[m_time_t].diam() > config.nra_precision) { need_to_run = true; } if (!need_to_run) { return; } extract_sample_point(b, m_vars_0, m_values); extract_sample_point(b, m_pars_0, m_params); for (unsigned i = 0; i < m_vars_0.size(); i++) { b[m_vars_0[i]] = m_values[i]; } for (unsigned i = 0; i < m_pars_0.size(); i++) { b[m_pars_0[i]] = m_params[i]; } // First move to T_lb without checking m_values while (t < T_lb) { interruption_point(); T_next = T_lb; // T_next = min(t + config.nra_precision, T_lb); int status = gsl_odeiv2_evolve_apply(m_evolve, m_control, m_step, &m_system, &t, T_next, &h, m_values); if (status != GSL_SUCCESS) { DREAL_LOG_INFO << "GSL: error, return value " << status; throw contractor_exception("GSL FAILED"); } } // Now we're in the range in [T_lb, T_ub], need to check m_values. while (t < T_ub) { interruption_point(); T_next = min(t + config.nra_precision, T_ub); // T_next = T_ub; // Copy m_values to m_old_values, and t to old_t for (unsigned i = 0; i < m_dim; i++) { m_old_values[i] = m_values[i]; } old_t = t; int status = gsl_odeiv2_evolve_apply(m_evolve, m_control, m_step, &m_system, &t, T_next, &h, m_values); if (status != GSL_SUCCESS) { DREAL_LOG_INFO << "GSL: error, return value " << status; throw contractor_exception("GSL FAILED"); } // print_values(t, m_values, m_dim); /* print at t */ bool values_good = true; unsigned i = 0; for (Enode * e : m_vars_t) { double const old_v_i = m_old_values[i]; double const v_i = m_values[i]; auto iv = (old_v_i < v_i) ? ibex::Interval(old_v_i, v_i) : ibex::Interval(v_i, old_v_i); auto const & iv_X_t = b[e]; iv &= iv_X_t; if (iv.is_empty()) { values_good = false; DREAL_LOG_INFO << "GSL Not in Range: " << e << " : " << m_values[i] << " not in " << b[e] << " at t = " << t; break; } i++; } if (values_good) { thread_local static box old_box(b); old_box = b; // Update X_t with m_values i = 0; for (Enode * e : m_vars_t) { double const old_v_i = m_old_values[i]; double const v_i = m_values[i]; auto iv = (old_v_i < v_i) ? ibex::Interval(old_v_i, v_i) : ibex::Interval(v_i, old_v_i); auto const & iv_X_t = b[e]; iv &= iv_X_t; DREAL_LOG_INFO << "GSL Update: " << e << " : " << b[e] << " ==> " << iv; b[e] = iv; i++; } // Update Time with T double const new_t = t/2.0 + old_t/2.0; DREAL_LOG_INFO << "GSL Update: time: " << b[m_time_t] << " ==> " << new_t; b[m_time_t] = new_t; m_eval_ctc.prune(b, config); if (!b.is_empty()) { DREAL_LOG_INFO << "This box satisfies other non-linear constraints"; return; } else { DREAL_LOG_INFO << "This box failed to satisfy other non-linear constraints"; b = old_box; } } } DREAL_LOG_INFO << "GSL failed in the end"; throw contractor_exception("GSL failed"); }
static void set_rounding_mode(rounding_mode mode) { fesetround(mode); }
void SetRoundMode(int mode) { // Convert PowerPC to native rounding mode. static const int rounding_mode_lut[] = {FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD, FE_DOWNWARD}; fesetround(rounding_mode_lut[mode]); }
int main(int argc, char *argv[]) { setvbuf(stdout, NULL, _IONBF, 0); printf("1..11\n"); assert(setlocale(LC_NUMERIC, "C")); #if __ANDROID__ && __x86_64__ && __clang__ /* Print of long double values broken on Android/x86_64 when being built by clang. * See https://tracker.crystax.net/issues/830 for details. */ #define LONG_DOUBLE_PRINT_BROKEN 1 #else #define LONG_DOUBLE_PRINT_BROKEN 0 #endif /* * Basic tests of decimal output functionality. */ testfmt(" 1.000000E+00", "%13E", 1.0); testfmt(" 1.000000", "%13f", 1.0); testfmt(" 1", "%13G", 1.0); #if !LONG_DOUBLE_PRINT_BROKEN testfmt(" 1.000000E+00", "%13LE", 1.0L); testfmt(" 1.000000", "%13Lf", 1.0L); testfmt(" 1", "%13LG", 1.0L); #endif /* !LONG_DOUBLE_PRINT_BROKEN */ testfmt("2.718282", "%.*f", -2, 2.7182818); testfmt("1.234568e+06", "%e", 1234567.8); testfmt("1234567.800000", "%f", 1234567.8); testfmt("1.23457E+06", "%G", 1234567.8); #if !LONG_DOUBLE_PRINT_BROKEN testfmt("1.234568e+06", "%Le", 1234567.8L); testfmt("1234567.800000", "%Lf", 1234567.8L); testfmt("1.23457E+06", "%LG", 1234567.8L); #endif /* !LONG_DOUBLE_PRINT_BROKEN */ #if (LDBL_MANT_DIG > DBL_MANT_DIG) && !defined(__i386__) #if !LONG_DOUBLE_PRINT_BROKEN testfmt("123456789.864210", "%Lf", 123456789.8642097531L); testfmt("-1.23457E+08", "%LG", -123456789.8642097531L); testfmt("123456789.8642097531", "%.10Lf", 123456789.8642097531L); #if !__gnu_linux__ testfmt(" 3.141592653589793238e-4000", "%L27.18Le", 3.14159265358979323846e-4000L); #endif #endif /* !LONG_DOUBLE_PRINT_BROKEN */ #endif printf("ok 1 - printfloat\n"); /* * Infinities and NaNs */ testfmt("nan", "%e", NAN); testfmt("NAN", "%F", NAN); testfmt("nan", "%g", NAN); #if !__ANDROID__ /* Temporarily disable this test since it's broken. * See https://tracker.crystax.net/issues/817. */ testfmt("NAN", "%LE", (long double)NAN); #endif #if !__APPLE__ || defined(__MAC_10_7) testfmt(" nan", "%05e", NAN); #endif testfmt("INF", "%E", HUGE_VAL); testfmt("-inf", "%f", -HUGE_VAL); testfmt("+inf", "%+g", HUGE_VAL); #if !__ANDROID__ /* Temporarily disable these tests since they are broken. * See https://tracker.crystax.net/issues/818. */ testfmt(" inf", "%4.2Le", HUGE_VALL); testfmt("-inf", "%Lf", -HUGE_VALL); #endif #if !__APPLE__ || defined(__MAC_10_7) testfmt(" inf", "%05e", HUGE_VAL); testfmt(" -inf", "%05e", -HUGE_VAL); #endif printf("ok 2 - printfloat\n"); /* * Padding */ testfmt("0.000000e+00", "%e", 0.0); testfmt("0.000000", "%F", (double)0.0); testfmt("0", "%G", 0.0); testfmt(" 0", "%3.0Lg", 0.0L); testfmt(" 0", "%5.0f", 0.001); printf("ok 3 - printfloat\n"); /* * Precision specifiers */ testfmt("1.0123e+00", "%.4e", 1.0123456789); testfmt("1.0123", "%.4f", 1.0123456789); testfmt("1.012", "%.4g", 1.0123456789); testfmt("1.2346e-02", "%.4e", 0.0123456789); testfmt("0.0123", "%.4f", 0.0123456789); testfmt("0.01235", "%.4g", 0.0123456789); printf("ok 4 - printfloat\n"); /* * Thousands' separators and other locale fun */ testfmt("12345678.0625", "%'.04f", 12345678.0625); testfmt("0012345678.0625", "%'015.4F", 12345678.0625); #if !__gnu_linux__ assert(setlocale(LC_NUMERIC, "hi_IN.ISCII-DEV")); /* grouping == 2;3 */ testfmt("123,456,78.0625", "%'.4f", 12345678.0625); testfmt("00123,456,78.0625", "%'017.4F", 12345678.0625); testfmt(" 90,00", "%'6.0f", 9000.0); testfmt("90,00.0", "%'.1f", 9000.0); assert(setlocale(LC_NUMERIC, "ru_RU.ISO8859-5")); /* decimalpoint==, */ testfmt("3,1415", "%g", 3.1415); /* thousands=. decimalpoint=, grouping=3;3 */ assert(setlocale(LC_NUMERIC, "el_GR.ISO8859-7")); /* decimalpoint==, */ testfmt("1.234,00", "%'.2f", 1234.00); testfmt("123.456,789", "%'.3f", 123456.789); #endif /* !__gnu_linux__ */ assert(setlocale(LC_NUMERIC, "C")); testfmt("12345678.062500", "%'f", 12345678.0625); testfmt("9000.000000", "%'f", 9000.0); printf("ok 5 - printfloat\n"); /* * Signed conversions */ testfmt("+2.500000e-01", "%+e", 0.25); testfmt("+0.000000", "%+F", 0.0); testfmt("-1", "%+g", -1.0); testfmt("-1.000000e+00", "% e", -1.0); testfmt("+1.000000", "% +f", 1.0); testfmt(" 1", "% g", 1.0); testfmt(" 0", "% g", 0.0); printf("ok 6 - printfloat\n"); /* * ``Alternate form'' */ testfmt("1.250e+00", "%#.3e", 1.25); testfmt("123.000000", "%#f", 123.0); testfmt(" 12345.", "%#7.5g", 12345.0); testfmt(" 1.00000", "%#8g", 1.0); testfmt("0.0", "%#.2g", 0.0); printf("ok 7 - printfloat\n"); /* * Padding and decimal point placement */ testfmt("03.2E+00", "%08.1E", 3.25); testfmt("003.25", "%06.2F", 3.25); testfmt("0003.25", "%07.4G", 3.25); testfmt("3.14159e-05", "%g", 3.14159e-5); testfmt("0.000314159", "%g", 3.14159e-4); testfmt("3.14159e+06", "%g", 3.14159e6); testfmt("314159", "%g", 3.14159e5); testfmt("314159.", "%#g", 3.14159e5); testfmt(" 9.000000e+03", "%13e", 9000.0); testfmt(" 9000.000000", "%12f", 9000.0); testfmt(" 9000", "%5g", 9000.0); testfmt(" 900000.", "%#8g", 900000.0); testfmt(" 9e+06", "%6g", 9000000.0); testfmt(" 9.000000e-04", "%13e", 0.0009); testfmt(" 0.000900", "%9f", 0.0009); testfmt(" 0.0009", "%7g", 0.0009); testfmt(" 9e-05", "%6g", 0.00009); testfmt(" 9.00000e-05", "%#12g", 0.00009); testfmt(" 9.e-05", "%#7.1g", 0.00009); testfmt(" 0.0", "%4.1f", 0.0); testfmt("90.0", "%4.1f", 90.0); testfmt(" 100", "%4.0f", 100.0); testfmt("9.0e+01", "%4.1e", 90.0); testfmt("1e+02", "%4.0e", 100.0); printf("ok 8 - printfloat\n"); #if __ANDROID__ /* Temporarily disable some tests since they are broken. * See https://tracker.crystax.net/issues/819 for details. */ #define FLOAT_DECIMAL_ROUNDING_DOWNWARD_BROKEN 1 #define FLOAT_DECIMAL_ROUNDING_UPWARD_BROKEN 1 #define FLOAT_DECIMAL_ROUNDING_TOWARDZERO_BROKEN 1 #define FLOAT_DECIMAL_ROUNDING_TONEAREST_BROKEN 0 #elif defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 15 #define FLOAT_DECIMAL_ROUNDING_DOWNWARD_BROKEN 1 #define FLOAT_DECIMAL_ROUNDING_UPWARD_BROKEN 1 #define FLOAT_DECIMAL_ROUNDING_TOWARDZERO_BROKEN 1 #define FLOAT_DECIMAL_ROUNDING_TONEAREST_BROKEN 0 #else #define FLOAT_DECIMAL_ROUNDING_DOWNWARD_BROKEN 0 #define FLOAT_DECIMAL_ROUNDING_UPWARD_BROKEN 0 #define FLOAT_DECIMAL_ROUNDING_TOWARDZERO_BROKEN 0 #define FLOAT_DECIMAL_ROUNDING_TONEAREST_BROKEN 0 #endif #if !FLOAT_DECIMAL_ROUNDING_DOWNWARD_BROKEN /* * Decimal rounding */ fesetround(FE_DOWNWARD); testfmt("4.437", "%.3f", 4.4375); testfmt("-4.438", "%.3f", -4.4375); testfmt("4.437", "%.3Lf", 4.4375L); #if !__APPLE__ || defined(__MAC_10_7) testfmt("-4.438", "%.3Lf", -4.4375L); #endif #endif /* !FLOAT_DECIMAL_ROUNDING_DOWNWARD_BROKEN */ #if !FLOAT_DECIMAL_ROUNDING_UPWARD_BROKEN fesetround(FE_UPWARD); testfmt("4.438", "%.3f", 4.4375); testfmt("-4.437", "%.3f", -4.4375); testfmt("4.438", "%.3Lf", 4.4375L); #if !__APPLE__ || defined(__MAC_10_7) testfmt("-4.437", "%.3Lf", -4.4375L); #endif #endif /* !FLOAT_DECIMAL_ROUNDING_UPWARD_BROKEN */ #if !FLOAT_DECIMAL_ROUNDING_TOWARDZERO_BROKEN fesetround(FE_TOWARDZERO); testfmt("4.437", "%.3f", 4.4375); testfmt("-4.437", "%.3f", -4.4375); testfmt("4.437", "%.3Lf", 4.4375L); testfmt("-4.437", "%.3Lf", -4.4375L); #endif /* !FLOAT_DECIMAL_ROUNDING_TOWARDZERO_BROKEN */ #if !FLOAT_DECIMAL_ROUNDING_TONEAREST_BROKEN fesetround(FE_TONEAREST); testfmt("4.438", "%.3f", 4.4375); testfmt("-4.438", "%.3f", -4.4375); #if !LONG_DOUBLE_PRINT_BROKEN testfmt("4.438", "%.3Lf", 4.4375L); testfmt("-4.438", "%.3Lf", -4.4375L); #endif /* !LONG_DOUBLE_PRINT_BROKEN */ #endif /* !FLOAT_DECIMAL_ROUNDING_TONEAREST_BROKEN */ printf("ok 9 - printfloat\n"); /* * Hexadecimal floating point (%a, %A) tests. Some of these * are only valid if the implementation converts to hex digits * on nibble boundaries. */ testfmt("0x0p+0", "%a", 0x0.0p0); testfmt("0X0.P+0", "%#LA", 0x0.0p0L); #if !LONG_DOUBLE_PRINT_BROKEN testfmt("inf", "%La", (long double)INFINITY); #endif testfmt("+INF", "%+A", INFINITY); #if !LONG_DOUBLE_PRINT_BROKEN testfmt("nan", "%La", (long double)NAN); #endif testfmt("NAN", "%A", NAN); testfmt(" 0x1.23p+0", "%10a", 0x1.23p0); testfmt(" 0x1.23p-500", "%12a", 0x1.23p-500); testfmt(" 0x1.2p+40", "%10.1a", 0x1.23p40); testfmt(" 0X1.230000000000000000000000P-4", "%32.24A", 0x1.23p-4); #if !__gnu_linux__ testfmt("0x1p-1074", "%a", 0x1p-1074); testfmt("0x1.2345p-1024", "%a", 0x1.2345p-1024); #endif /* !__gnu_linux__ */ #if !__APPLE__ && !__gnu_linux__ #if (LDBL_MANT_DIG == 64) && !defined(__i386__) testfmt("0x1.921fb54442d18468p+1", "%La", 0x3.243f6a8885a308dp0L); testfmt("0x1p-16445", "%La", 0x1p-16445L); testfmt("0x1.30ecap-16381", "%La", 0x9.8765p-16384L); #elif (LDBL_MANT_DIG == 113) testfmt("0x1.921fb54442d18469898cc51701b8p+1", "%La", 0x3.243f6a8885a308d313198a2e037p0L); testfmt("0x1p-16494", "%La", 0x1p-16494L); testfmt("0x1.2345p-16384", "%La", 0x1.2345p-16384L); #else testfmt("0x1.921fb54442d18p+1", "%La", 0x3.243f6a8885a31p0L); testfmt("0x1p-1074", "%La", 0x1p-1074L); testfmt("0x1.30ecap-1021", "%La", 0x9.8765p-1024L); #endif #endif /* !__APPLE__ && !__gnu_linux__ */ printf("ok 10 - printfloat\n"); #if __ANDROID__ && __arm__ && __SOFTFP__ /* Temporarily disable this test for ARM soft float since it's broken. * See https://tracker.crystax.net/issues/820 for details. */ #define FLOAT_HEX_ROUNDING_BROKEN 1 #elif defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 15 #define FLOAT_HEX_ROUNDING_BROKEN 1 #else #define FLOAT_HEX_ROUNDING_BROKEN 0 #endif #if __CRYSTAX__ && __i386__ /* This test fails on x86 emulator so temporarily disable it for such case. * See https://tracker.crystax.net/issues/820 for details. */ if (crystax_device_type() != CRYSTAX_DEVICE_TYPE_EMULATOR) { #endif #if !FLOAT_HEX_ROUNDING_BROKEN /* * Hexadecimal rounding */ fesetround(FE_TOWARDZERO); testfmt("0X1.23456789ABCP+0", "%.11A", 0x1.23456789abcdep0); testfmt("-0x1.23456p+0", "%.5a", -0x1.23456789abcdep0); testfmt("0x1.23456p+0", "%.5a", 0x1.23456789abcdep0); testfmt("0x1.234567p+0", "%.6a", 0x1.23456789abcdep0); testfmt("-0x1.234566p+0", "%.6a", -0x1.23456689abcdep0); fesetround(FE_DOWNWARD); testfmt("0X1.23456789ABCP+0", "%.11A", 0x1.23456789abcdep0); testfmt("-0x1.23457p+0", "%.5a", -0x1.23456789abcdep0); testfmt("0x1.23456p+0", "%.5a", 0x1.23456789abcdep0); testfmt("0x1.234567p+0", "%.6a", 0x1.23456789abcdep0); testfmt("-0x1.234567p+0", "%.6a", -0x1.23456689abcdep0); fesetround(FE_UPWARD); testfmt("0X1.23456789ABDP+0", "%.11A", 0x1.23456789abcdep0); testfmt("-0x1.23456p+0", "%.5a", -0x1.23456789abcdep0); testfmt("0x1.23457p+0", "%.5a", 0x1.23456789abcdep0); testfmt("0x1.234568p+0", "%.6a", 0x1.23456789abcdep0); testfmt("-0x1.234566p+0", "%.6a", -0x1.23456689abcdep0); #endif /* !FLOAT_HEX_ROUNDING_BROKEN */ #if __CRYSTAX__ && __i386__ } #endif fesetround(FE_TONEAREST); testfmt("0x1.23456789abcdep+4", "%a", 0x1.23456789abcdep4); testfmt("0X1.23456789ABDP+0", "%.11A", 0x1.23456789abcdep0); testfmt("-0x1.23456p+0", "%.5a", -0x1.23456789abcdep0); testfmt("0x1.23456p+0", "%.5a", 0x1.23456789abcdep0); testfmt("0x1.234568p+0", "%.6a", 0x1.23456789abcdep0); #if !__APPLE__ || defined(__MAC_10_7) testfmt("-0x1.234567p+0", "%.6a", -0x1.23456689abcdep0); #endif #if !__APPLE__ && !__gnu_linux__ testfmt("0x1.00p-1029", "%.2a", 0x1.fffp-1030); testfmt("0x1.00p-1026", "%.2a", 0xf.fffp-1030); #endif /* !__APPLE__ && !__gnu_linux__ */ #if !__APPLE__ || defined(__MAC_10_7) testfmt("0x1.83p+0", "%.2a", 1.51); #endif printf("ok 11 - printfloat\n"); return (0); }
void Sys_SetFloatEnv(void) { // rounding toward nearest fesetround(FE_TONEAREST); }
/* * Test feholdexcept() and feupdateenv(). * * Prerequisites: fetestexcept(), fegetround(), fesetround(), * fedisableexcept(), feenableexcept() */ static void test_feholdupdate(void) { fenv_t env; struct sigaction act; int except, i, pass, status, raise; sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = trap_handler; for (pass = 0; pass < 2; pass++) { for (i = 0; i < NEXCEPTS; i++) { except = std_excepts[i]; /* over/underflow may also raise inexact */ if (except == FE_INEXACT) raise = FE_DIVBYZERO | FE_INVALID; else raise = ALL_STD_EXCEPT ^ except; /* * We need to fork a child process because * there isn't a portable way to recover from * a floating-point exception. */ switch(fork()) { case 0: /* child */ /* * We don't want to cause a fatal exception in * the child until the second pass, so we can * check other properties of feupdateenv(). */ if (pass == 1) assert((feenableexcept(except) & ALL_STD_EXCEPT) == 0); raiseexcept(raise); assert(fesetround(FE_DOWNWARD) == 0); assert(feholdexcept(&env) == 0); assert(fetestexcept(FE_ALL_EXCEPT) == 0); raiseexcept(except); assert(fesetround(FE_UPWARD) == 0); if (pass == 1) assert(sigaction(SIGFPE, &act, NULL) == 0); assert(feupdateenv(&env) == 0); assert(fegetround() == FE_DOWNWARD); assert(fetestexcept(ALL_STD_EXCEPT) == (except | raise)); assert(pass == 0); _exit(0); default: /* parent */ assert(wait(&status) > 0); /* * Avoid assert() here so that it's possible * to examine a failed child's core dump. */ if (!WIFEXITED(status)) errx(1, "child aborted\n"); assert(WEXITSTATUS(status) == 0); break; case -1: /* error */ assert(0); } } } assert(fetestexcept(FE_ALL_EXCEPT) == 0); }
void Sys_SetFloatEnv(void) { // rounding towards 0 fesetround(FE_TOWARDZERO); }
_Float128 __ieee754_expl (_Float128 x) { /* Check for usual case. */ if (isless (x, himark) && isgreater (x, lomark)) { int tval1, tval2, unsafe, n_i; _Float128 x22, n, t, result, xl; union ieee854_long_double ex2_u, scale_u; fenv_t oldenv; feholdexcept (&oldenv); #ifdef FE_TONEAREST fesetround (FE_TONEAREST); #endif /* Calculate n. */ n = x * M_1_LN2 + THREEp111; n -= THREEp111; x = x - n * M_LN2_0; xl = n * M_LN2_1; /* Calculate t/256. */ t = x + THREEp103; t -= THREEp103; /* Compute tval1 = t. */ tval1 = (int) (t * TWO8); x -= __expl_table[T_EXPL_ARG1+2*tval1]; xl -= __expl_table[T_EXPL_ARG1+2*tval1+1]; /* Calculate t/32768. */ t = x + THREEp96; t -= THREEp96; /* Compute tval2 = t. */ tval2 = (int) (t * TWO15); x -= __expl_table[T_EXPL_ARG2+2*tval2]; xl -= __expl_table[T_EXPL_ARG2+2*tval2+1]; x = x + xl; /* Compute ex2 = 2^n_0 e^(argtable[tval1]) e^(argtable[tval2]). */ ex2_u.d = __expl_table[T_EXPL_RES1 + tval1] * __expl_table[T_EXPL_RES2 + tval2]; n_i = (int)n; /* 'unsafe' is 1 iff n_1 != 0. */ unsafe = abs(n_i) >= 15000; ex2_u.ieee.exponent += n_i >> unsafe; /* Compute scale = 2^n_1. */ scale_u.d = 1; scale_u.ieee.exponent += n_i - (n_i >> unsafe); /* Approximate e^x2 - 1, using a seventh-degree polynomial, with maximum error in [-2^-16-2^-53,2^-16+2^-53] less than 4.8e-39. */ x22 = x + x*x*(P1+x*(P2+x*(P3+x*(P4+x*(P5+x*P6))))); /* Return result. */ fesetenv (&oldenv); result = x22 * ex2_u.d + ex2_u.d; /* Now we can test whether the result is ultimate or if we are unsure. In the later case we should probably call a mpn based routine to give the ultimate result. Empirically, this routine is already ultimate in about 99.9986% of cases, the test below for the round to nearest case will be false in ~ 99.9963% of cases. Without proc2 routine maximum error which has been seen is 0.5000262 ulp. union ieee854_long_double ex3_u; #ifdef FE_TONEAREST fesetround (FE_TONEAREST); #endif ex3_u.d = (result - ex2_u.d) - x22 * ex2_u.d; ex2_u.d = result; ex3_u.ieee.exponent += LDBL_MANT_DIG + 15 + IEEE854_LONG_DOUBLE_BIAS - ex2_u.ieee.exponent; n_i = abs (ex3_u.d); n_i = (n_i + 1) / 2; fesetenv (&oldenv); #ifdef FE_TONEAREST if (fegetround () == FE_TONEAREST) n_i -= 0x4000; #endif if (!n_i) { return __ieee754_expl_proc2 (origx); } */ if (!unsafe) return result; else { result *= scale_u.d; math_check_force_underflow_nonneg (result); return result; } }
void CPS2VM::EmuThread() { fesetround(FE_TOWARDZERO); CProfiler::GetInstance().SetWorkThread(); while(1) { while(m_mailBox.IsPending()) { m_mailBox.ReceiveCall(); } if(m_nEnd) break; if(m_nStatus == PAUSED) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } if(m_nStatus == RUNNING) { #ifdef PROFILE CProfilerZone profilerZone(m_otherProfilerZone); #endif if(m_spuUpdateTicks <= 0) { UpdateSpu(); m_spuUpdateTicks += SPU_UPDATE_TICKS; } //EE execution { //Check vblank stuff if(m_vblankTicks <= 0) { m_inVblank = !m_inVblank; if(m_inVblank) { m_vblankTicks += VBLANK_TICKS; m_ee->NotifyVBlankStart(); m_iop->NotifyVBlankStart(); if(m_ee->m_gs != NULL) { #ifdef PROFILE CProfilerZone profilerZone(m_gsSyncProfilerZone); #endif m_ee->m_gs->SetVBlank(); } if(m_pad != NULL) { m_pad->Update(m_ee->m_ram); } #ifdef PROFILE { auto stats = CProfiler::GetInstance().GetStats(); ProfileFrameDone(stats); CProfiler::GetInstance().Reset(); } #endif } else { m_vblankTicks += ONSCREEN_TICKS; m_ee->NotifyVBlankEnd(); m_iop->NotifyVBlankEnd(); if(m_ee->m_gs != NULL) { m_ee->m_gs->ResetVBlank(); } } } //EE CPU is 8 times faster than the IOP CPU static const int tickStep = 480; m_eeExecutionTicks += tickStep; m_iopExecutionTicks += tickStep / 8; UpdateEe(); UpdateIop(); m_ee->m_vif.ExecuteVu0(m_singleStepVu0); m_ee->m_vif.ExecuteVu1(m_singleStepVu1); } #ifdef DEBUGGER_INCLUDED if( m_ee->m_executor.MustBreak() || m_iop->m_executor.MustBreak() || m_ee->m_vif.MustVu1Break() || m_singleStepEe || m_singleStepIop || m_singleStepVu0 || m_singleStepVu1) { m_nStatus = PAUSED; m_singleStepEe = false; m_singleStepIop = false; m_singleStepVu0 = false; m_singleStepVu1 = false; OnRunningStateChange(); OnMachineStateChange(); } #endif } } }
int main(int argc, const char **argv) { const char *prog = *argv++; int to_linear = 0, to_gray = 0, to_color = 0; int channels = 0; double c[4]; /* FE_TONEAREST is the IEEE754 round to nearest, preferring even, mode; i.e. * everything rounds to the nearest value except that '.5' rounds to the * nearest even value. */ fesetround(FE_TONEAREST); c[3] = c[2] = c[1] = c[0] = 0; while (--argc > 0 && **argv == '-') { const char *arg = 1 + *argv++; if (strcmp(arg, "sRGB") == 0) to_linear = 0; else if (strcmp(arg, "linear") == 0) to_linear = 1; else if (strcmp(arg, "gray") == 0) to_gray = 1, to_color = 0; else if (strcmp(arg, "color") == 0) to_gray = 0, to_color = 1; else usage(prog); } switch (argc) { default: usage(prog); break; case 4: c[3] = component(prog, argv[3], to_linear); ++channels; case 3: c[2] = component(prog, argv[2], to_linear); ++channels; case 2: c[1] = component(prog, argv[1], to_linear); ++channels; case 1: c[0] = component(prog, argv[0], to_linear); ++channels; break; } if (to_linear) { int i; int components = channels; if ((components & 1) == 0) --components; for (i = 0; i < components; ++i) c[i] = linear_from_sRGB(c[i] / 255); if (components < channels) c[components] = c[components] / 255; } else { int i; for (i = 0; i < 4; ++i) c[i] /= 65535; if ((channels & 1) == 0) { double alpha = c[channels - 1]; if (alpha > 0) for (i = 0; i < channels - 1; ++i) c[i] /= alpha; else for (i = 0; i < channels - 1; ++i) c[i] = 1; } } if (to_gray) { if (channels < 3) { fprintf(stderr, "%s: too few channels (%d) for -gray\n", prog, channels); usage(prog); } c[0] = YfromRGB(c[0], c[1], c[2]); channels -= 2; } if (to_color) { if (channels > 2) { fprintf(stderr, "%s: too many channels (%d) for -color\n", prog, channels); usage(prog); } c[3] = c[1]; /* alpha, if present */ c[2] = c[1] = c[0]; } if (to_linear) { int i; if ((channels & 1) == 0) { double alpha = c[channels - 1]; for (i = 0; i < channels - 1; ++i) c[i] *= alpha; } for (i = 0; i < channels; ++i) c[i] = nearbyint(c[i] * 65535); } else /* to sRGB */ { int i = (channels + 1) & ~1; while (--i >= 0) c[i] = sRGB_from_linear(c[i]); for (i = 0; i < channels; ++i) c[i] = nearbyint(c[i] * 255); } { int i; for (i = 0; i < channels; ++i) printf(" %g", c[i]); } printf("\n"); return 0; }
static __attribute__ ((noinline)) int sse_tests (void) { int ret = 0; fenv_t base_env; if (fegetenv (&base_env) != 0) { puts ("fegetenv (&base_env) failed"); return 1; } if (fesetround (FE_UPWARD) != 0) { puts ("fesetround (FE_UPWARD) failed"); return 1; } if (fesetenv (&base_env) != 0) { puts ("fesetenv (&base_env) failed"); return 1; } volatile float a = 1.0f, b = FLT_MIN, c; c = a + b; if (c != 1.0f) { puts ("fesetenv did not restore rounding mode"); ret = 1; } if (fesetround (FE_DOWNWARD) != 0) { puts ("fesetround (FE_DOWNWARD) failed"); return 1; } if (feupdateenv (&base_env) != 0) { puts ("feupdateenv (&base_env) failed"); return 1; } volatile float d = -FLT_MIN, e; e = a + d; if (e != 1.0f) { puts ("feupdateenv did not restore rounding mode"); ret = 1; } if (fesetround (FE_UPWARD) != 0) { puts ("fesetround (FE_UPWARD) failed"); return 1; } fenv_t upward_env; if (feholdexcept (&upward_env) != 0) { puts ("feholdexcept (&upward_env) failed"); return 1; } if (fesetround (FE_DOWNWARD) != 0) { puts ("fesetround (FE_DOWNWARD) failed"); return 1; } if (fesetenv (&upward_env) != 0) { puts ("fesetenv (&upward_env) failed"); return 1; } e = a + d; if (e != 1.0f) { puts ("fesetenv did not restore rounding mode from feholdexcept"); ret = 1; } if (fesetround (FE_UPWARD) != 0) { puts ("fesetround (FE_UPWARD) failed"); return 1; } if (fesetenv (FE_DFL_ENV) != 0) { puts ("fesetenv (FE_DFL_ENV) failed"); return 1; } c = a + b; if (c != 1.0f) { puts ("fesetenv (FE_DFL_ENV) did not restore rounding mode"); ret = 1; } return ret; }
static bool psArithSingle(cpu::Core *state, Instruction instr, float *result) { double a, b; if (slotA == 0) { a = state->fpr[instr.frA].paired0; } else { a = state->fpr[instr.frA].paired1; } if (slotB == 0) { b = state->fpr[op == PSMul ? instr.frC : instr.frB].paired0; } else { b = state->fpr[op == PSMul ? instr.frC : instr.frB].paired1; } const bool vxsnan = is_signalling_nan(a) || is_signalling_nan(b); bool vxisi, vximz, vxidi, vxzdz, zx; switch (op) { case PSAdd: vxisi = is_infinity(a) && is_infinity(b) && std::signbit(a) != std::signbit(b); vximz = false; vxidi = false; vxzdz = false; zx = false; break; case PSSub: vxisi = is_infinity(a) && is_infinity(b) && std::signbit(a) == std::signbit(b); vximz = false; vxidi = false; vxzdz = false; zx = false; break; case PSMul: vxisi = false; vximz = (is_infinity(a) && is_zero(b)) || (is_zero(a) && is_infinity(b)); vxidi = false; vxzdz = false; zx = false; break; case PSDiv: vxisi = false; vximz = false; vxidi = is_infinity(a) && is_infinity(b); vxzdz = is_zero(a) && is_zero(b); zx = !(vxzdz || vxsnan) && is_zero(b); break; } state->fpscr.vxsnan |= vxsnan; state->fpscr.vxisi |= vxisi; state->fpscr.vximz |= vximz; state->fpscr.vxidi |= vxidi; state->fpscr.vxzdz |= vxzdz; state->fpscr.zx |= zx; const bool vxEnabled = (vxsnan || vxisi || vximz || vxidi || vxzdz) && state->fpscr.ve; const bool zxEnabled = zx && state->fpscr.ze; if (vxEnabled || zxEnabled) { return false; } float d; if (is_nan(a)) { d = make_quiet(truncate_double(a)); } else if (is_nan(b)) { d = make_quiet(truncate_double(b)); } else if (vxisi || vximz || vxidi || vxzdz) { d = make_nan<float>(); } else { switch (op) { case PSAdd: d = static_cast<float>(a + b); break; case PSSub: d = static_cast<float>(a - b); break; case PSMul: if (slotB == 0) { roundForMultiply(&a, &b); // Not necessary for slot 1. } d = static_cast<float>(a * b); break; case PSDiv: d = static_cast<float>(a / b); break; } if (possibleUnderflow<float>(d)) { const int oldRound = fegetround(); fesetround(FE_TOWARDZERO); volatile double bTemp = b; volatile float dummy; switch (op) { case PSAdd: dummy = static_cast<float>(a + bTemp); break; case PSSub: dummy = static_cast<float>(a - bTemp); break; case PSMul: dummy = static_cast<float>(a * bTemp); break; case PSDiv: dummy = static_cast<float>(a / bTemp); break; } fesetround(oldRound); } } *result = d; return true; }
int main(int argc, char **argv) { if(argc != 3) { fprintf(stderr, "Wrong number of arguments. Provide rounding mode and event number [0-50].\n"); fprintf(stderr, "Possible rounding modes:\n\t0 - to nearest\n\t1 - upward\n\t2 - downward\n\t3 - toward zero\n"); fprintf(stderr, "Execution: program_name <rounding_mode> <event_number>\n"); exit(-1); } int choosen = atoi(argv[1]); int rounding_mode; if(choosen == 0) { rounding_mode = FE_TONEAREST; } else if(choosen == 1) { rounding_mode = FE_UPWARD; } else if(choosen == 2) { rounding_mode = FE_DOWNWARD; } else if(choosen == 3) { rounding_mode = FE_TOWARDZERO; } else { fprintf(stderr, "Incorrect rounding mode. Should be one of [0, 1, 2, 3]\n"); exit(-2); } const int EVENTS_SIZE = 50; int option = atoi(argv[2]); if (option < 0 || option >= EVENTS_SIZE) { fprintf(stderr, "Incorrect option chosen.\n"); exit(-2); } int check = fesetround(rounding_mode); if(check != 0) { fprintf(stderr, "Unable to set rounding mode.\n"); exit(-3); } double *A; int i, j, n, ret; n = 3; A = calloc(n * n, sizeof(double)); assert(A != NULL); A[IDX(0, 0, n)] = 4.0; A[IDX(0, 1, n)] = 12.0; A[IDX(0, 2, n)] = -16.0; A[IDX(1, 0, n)] = 12.0; A[IDX(1, 1, n)] = 37.0; A[IDX(1, 2, n)] = -43.0; A[IDX(2, 0, n)] = -16.0; A[IDX(2, 1, n)] = -43.0; A[IDX(2, 2, n)] = 98.0; /* init lib */ int events[] = {PAPI_L1_DCM, PAPI_L1_ICM, PAPI_L2_DCM, PAPI_L2_ICM, PAPI_L1_TCM, PAPI_L2_TCM, PAPI_L3_TCM, PAPI_TLB_DM, PAPI_TLB_IM, PAPI_L1_LDM, PAPI_L1_STM, PAPI_L2_STM, PAPI_STL_ICY, PAPI_BR_UCN, PAPI_BR_CN, PAPI_BR_TKN, PAPI_BR_NTK, PAPI_BR_MSP, PAPI_BR_PRC, PAPI_TOT_INS, PAPI_FP_INS, PAPI_LD_INS, PAPI_SR_INS, PAPI_BR_INS, PAPI_TOT_CYC, PAPI_L2_DCH, PAPI_L2_DCA, PAPI_L3_DCA, PAPI_L2_DCR, PAPI_L3_DCR, PAPI_L2_DCW, PAPI_L3_DCW, PAPI_L2_ICH, PAPI_L2_ICA, PAPI_L3_ICA, PAPI_L2_ICR, PAPI_L3_ICR, PAPI_L2_TCA, PAPI_L3_TCA, PAPI_L2_TCR, PAPI_L3_TCR, PAPI_L2_TCW, PAPI_L3_TCW, PAPI_FDV_INS, PAPI_FP_OPS, PAPI_SP_OPS, PAPI_DP_OPS, PAPI_VEC_SP, PAPI_VEC_DP, PAPI_REF_CYC}; char *event_names[] = {"PAPI_L1_DCM", "PAPI_L1_ICM", "PAPI_L2_DCM", "PAPI_L2_ICM", "PAPI_L1_TCM", "PAPI_L2_TCM", "PAPI_L3_TCM", "PAPI_TLB_DM", "PAPI_TLB_IM", "PAPI_L1_LDM", "PAPI_L1_STM", "PAPI_L2_STM", "PAPI_STL_ICY", "PAPI_BR_UCN", "PAPI_BR_CN", "PAPI_BR_TKN", "PAPI_BR_NTK", "PAPI_BR_MSP", "PAPI_BR_PRC", "PAPI_TOT_INS", "PAPI_FP_INS", "PAPI_LD_INS", "PAPI_SR_INS", "PAPI_BR_INS", "PAPI_TOT_CYC", "PAPI_L2_DCH", "PAPI_L2_DCA", "PAPI_L3_DCA", "PAPI_L2_DCR", "PAPI_L3_DCR", "PAPI_L2_DCW", "PAPI_L3_DCW", "PAPI_L2_ICH", "PAPI_L2_ICA", "PAPI_L3_ICA", "PAPI_L2_ICR", "PAPI_L3_ICR", "PAPI_L2_TCA", "PAPI_L3_TCA", "PAPI_L2_TCR", "PAPI_L3_TCR", "PAPI_L2_TCW", "PAPI_L3_TCW", "PAPI_FDV_INS", "PAPI_FP_OPS", "PAPI_SP_OPS", "PAPI_DP_OPS", "PAPI_VEC_SP", "PAPI_VEC_DP", "PAPI_REF_CYC"}; long long values[1] = {0}; int eventSet = PAPI_NULL; int papi_err; bool papi_supported = true; if (PAPI_library_init(PAPI_VER_CURRENT) != PAPI_VER_CURRENT) { fprintf(stderr, "PAPI is unsupported.\n"); papi_supported = false; } // if (PAPI_num_counters() < EVENTS_SIZE) { // fprintf(stderr, "PAPI is unsupported.\n"); // papi_supported = false; // } if ((papi_err = PAPI_create_eventset(&eventSet)) != PAPI_OK) { fprintf(stderr, "Could not create event set: %s\n", PAPI_strerror(papi_err)); } if ((papi_err = PAPI_add_event(eventSet, events[option])) != PAPI_OK) { fprintf(stderr, "Could not add event %d: %s\n", i, PAPI_strerror(papi_err)); } /* start counters */ if (papi_supported) { if ((papi_err = PAPI_start(eventSet)) != PAPI_OK) { fprintf(stderr, "Could not start counters: %s\n", PAPI_strerror(papi_err)); } } check = chol(A, n); /* stop conuters */ if (papi_supported) { if ((papi_err = PAPI_stop(eventSet, values)) != PAPI_OK) { fprintf(stderr, "Could not get values: %s\n", PAPI_strerror(papi_err)); } printf("Performance counters for factorization stage: \n"); printf("%s: %lld\n", event_names[option], values[0]); } if (check != 0) { fprintf(stderr, "Error: matrix is either not symmetric or not positive definite.\n"); } else { fprintf(stdout, "Tri(L) = \n"); for (i = 0; i < n; i++) { for (j = 0; j <= i; j++) printf("%2.8lf\t", A[IDX(i, j, n)]); printf("\n"); } } free(A); return 0; }
static int check_centering(double a, double b, double c, double al, double be, double ga, LatticeType latt, char cen, char ua, gsl_rng *rng) { UnitCell *cell, *cref; UnitCell *n; UnitCellTransformation *t; int fail = 0; int i; double asx, asy, asz; double bsx, bsy, bsz; double csx, csy, csz; double ax, ay, az; double bx, by, bz; double cx, cy, cz; STATUS(" ---------------> " "Checking %s %c (ua %c) %5.2e %5.2e %5.2e %5.2f %5.2f %5.2f\n", str_lattice(latt), cen, ua, a, b, c, al, be, ga); cref = cell_new_from_parameters(a, b, c, deg2rad(al), deg2rad(be), deg2rad(ga)); cell_set_lattice_type(cref, latt); cell_set_centering(cref, cen); cell_set_unique_axis(cref, ua); cell = cell_rotate(cref, random_quaternion(rng)); if ( cell == NULL ) return 1; cell_free(cref); check_cell(cell, "Input"); n = uncenter_cell(cell, &t); if ( n != NULL ) { STATUS("Transformation was:\n"); tfn_print(t); if ( check_cell(n, "Output") ) fail = 1; if ( !fail ) cell_print(n); } else { fail = 1; } cell_get_reciprocal(cell, &asx, &asy, &asz, &bsx, &bsy, &bsz, &csx, &csy, &csz); cell_get_cartesian(n, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz); fesetround(1); /* Round towards nearest */ for ( i=0; i<100; i++ ) { signed int h, k, l; double x, y, z; double nh, nk, nl; double dh, dk, dl; int f = 0; do { h = gsl_rng_uniform_int(rng, 30); k = gsl_rng_uniform_int(rng, 30); l = gsl_rng_uniform_int(rng, 30); } while ( forbidden_reflection(cell, h, k, l) ); x = h*asx + k*bsx + l*csx; y = h*asy + k*bsy + l*csy; z = h*asz + k*bsz + l*csz; nh = x*ax + y*ay + z*az; nk = x*bx + y*by + z*bz; nl = x*cx + y*cy + z*cz; dh = nh - lrint(nh); dk = nk - lrint(nk); dl = nl - lrint(nl); if ( fabs(dh) > 0.1 ) f++; if ( fabs(dk) > 0.1 ) f++; if ( fabs(dl) > 0.1 ) f++; if ( f ) { STATUS("Centered %3i %3i %3i -> " "Primitive %7.2f %7.2f %7.2f\n", h, k, l, nh, nk, nl); fail = 1; } } cell_get_reciprocal(n, &asx, &asy, &asz, &bsx, &bsy, &bsz, &csx, &csy, &csz); cell_get_cartesian(cell, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz); for ( i=0; i<100; i++ ) { signed int h, k, l; double x, y, z; double nh, nk, nl; double dh, dk, dl; int f = 0; long int ih, ik, il; h = gsl_rng_uniform_int(rng, 30); k = gsl_rng_uniform_int(rng, 30); l = gsl_rng_uniform_int(rng, 30); x = h*asx + k*bsx + l*csx; y = h*asy + k*bsy + l*csy; z = h*asz + k*bsz + l*csz; nh = x*ax + y*ay + z*az; nk = x*bx + y*by + z*bz; nl = x*cx + y*cy + z*cz; dh = nh - lrint(nh); dk = nk - lrint(nk); dl = nl - lrint(nl); if ( fabs(dh) > 0.1 ) f++; if ( fabs(dk) > 0.1 ) f++; if ( fabs(dl) > 0.1 ) f++; ih = lrint(nh); ik = lrint(nk); il = lrint(nl); if ( forbidden_reflection(cell, ih, ik, il) ) { STATUS("Primitive %3i %3i %3i -> " "Centered %3li %3li %3li, " "which is forbidden\n", h, k, l, ih, ik, il); fail = 1; } if ( f ) { STATUS("Primitive %3i %3i %3i -> " "Centered %7.2f %7.2f %7.2f\n", h, k, l, nh, nk, nl); fail = 1; } } return fail; }
float setRoundingModeAndCast(int mode, double d) { fesetround(mode); return (float)d; }
int main (void) { int passes = 0; int fails = 0; size_t i; for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i++) { size_t j; for (j = 0; j < 4; j++) { if (fesetround (rounding_modes[j]) != 0) { printf ("fesetround (%s) failed.\n", mode_names[j]); abort (); } #define DO_TEST(SU, SZ, PR) \ do { \ SU##int##SZ##_t expret = tests[i].res[j].SU##SZ; \ int experr = tests[i].res[j].e##SU##SZ; \ size_t explen = strlen (tests[i].s) - tests[i].njunk; \ SU##int##SZ##_t ret0, ret1; \ int reterr; \ size_t retlen; \ char *ep; \ errno = 0; \ ret0 = strto##SU##fix##SZ (tests[i].s, &ep); \ reterr = errno; \ retlen = ep - tests[i].s; \ if (ret0 == expret) \ passes++; \ else \ { \ fails++; \ printf ("strto"#SU"fix"#SZ" (\"%s\") in mode %s " \ "returned %0"PR"x, expected %0"PR"x.\n", \ tests[i].s, mode_names[j], ret0, expret); \ } \ if (reterr == experr) \ passes++; \ else \ { \ fails++; \ printf ("strto"#SU"fix"#SZ" (\"%s\") in mode %s " \ "left errno as %d, expected %d.\n", \ tests[i].s, mode_names[j], reterr, experr); \ } \ if (retlen == explen) \ passes++; \ else \ { \ fails++; \ printf ("strto"#SU"fix"#SZ" (\"%s\") in mode %s " \ "consumed %zu characters, expected %zu.\n", \ tests[i].s, mode_names[j], retlen, explen); \ } \ if (experr == 0) \ { \ ret1 = ato##SU##fix##SZ (tests[i].s); \ if (ret1 == expret) \ passes++; \ else \ { \ fails++; \ printf ("ato"#SU"fix"#SZ" (\"%s\") in mode %s " \ "returned %0"PR"x, expected %0"PR"x.\n", \ tests[i].s, mode_names[j], ret1, expret); \ } \ } \ } while (0) DO_TEST (s, 16, "4h"); DO_TEST (s, 32, "8"); DO_TEST (s, 64, "16ll"); DO_TEST (u, 16, "4h"); DO_TEST (u, 32, "8"); DO_TEST (u, 64, "16ll"); } } printf ("Number of passes: %d\nNumber of failures: %d\n", passes, fails); return fails != 0; }
~FloatingPointGuard() { if (fesetround(oldMode)) { throw FailedToSetFloatingPointMode("Failed to reset floating point rounding mode to its original value."); } }
int main(int argc, char *argv[]) { printf("1..11\n"); assert(setlocale(LC_NUMERIC, "C")); /* * Basic tests of decimal output functionality. */ testfmt(" 1.000000E+00", "%13E", 1.0); testfmt(" 1.000000", "%13f", 1.0); testfmt(" 1", "%13G", 1.0); testfmt(" 1.000000E+00", "%13LE", 1.0L); testfmt(" 1.000000", "%13Lf", 1.0L); testfmt(" 1", "%13LG", 1.0L); testfmt("2.718282", "%.*f", -2, 2.7182818); testfmt("1.234568e+06", "%e", 1234567.8); testfmt("1234567.800000", "%f", 1234567.8); testfmt("1.23457E+06", "%G", 1234567.8); testfmt("1.234568e+06", "%Le", 1234567.8L); testfmt("1234567.800000", "%Lf", 1234567.8L); testfmt("1.23457E+06", "%LG", 1234567.8L); #if (LDBL_MANT_DIG > DBL_MANT_DIG) && !defined(__i386__) testfmt("123456789.864210", "%Lf", 123456789.8642097531L); testfmt("-1.23457E+08", "%LG", -123456789.8642097531L); testfmt("123456789.8642097531", "%.10Lf", 123456789.8642097531L); testfmt(" 3.141592653589793238e-4000", "%L27.18Le", 3.14159265358979323846e-4000L); #endif printf("ok 1 - printfloat\n"); /* * Infinities and NaNs */ testfmt("nan", "%e", NAN); testfmt("NAN", "%F", NAN); testfmt("nan", "%g", NAN); testfmt("NAN", "%LE", (long double)NAN); testfmt(" nan", "%05e", NAN); testfmt("INF", "%E", HUGE_VAL); testfmt("-inf", "%f", -HUGE_VAL); testfmt("+inf", "%+g", HUGE_VAL); testfmt(" inf", "%4.2Le", HUGE_VALL); testfmt("-inf", "%Lf", -HUGE_VALL); testfmt(" inf", "%05e", HUGE_VAL); testfmt(" -inf", "%05e", -HUGE_VAL); printf("ok 2 - printfloat\n"); /* * Padding */ testfmt("0.000000e+00", "%e", 0.0); testfmt("0.000000", "%F", (double)0.0); testfmt("0", "%G", 0.0); testfmt(" 0", "%3.0Lg", 0.0L); testfmt(" 0", "%5.0f", 0.001); printf("ok 3 - printfloat\n"); /* * Precision specifiers */ testfmt("1.0123e+00", "%.4e", 1.0123456789); testfmt("1.0123", "%.4f", 1.0123456789); testfmt("1.012", "%.4g", 1.0123456789); testfmt("1.2346e-02", "%.4e", 0.0123456789); testfmt("0.0123", "%.4f", 0.0123456789); testfmt("0.01235", "%.4g", 0.0123456789); printf("ok 4 - printfloat\n"); /* * Thousands' separators and other locale fun */ testfmt("12345678.0625", "%'.04f", 12345678.0625); testfmt("0012345678.0625", "%'015.4F", 12345678.0625); assert(setlocale(LC_NUMERIC, "hi_IN.ISCII-DEV")); /* grouping == 2;3 */ testfmt("123,456,78.0625", "%'.4f", 12345678.0625); testfmt("00123,456,78.0625", "%'017.4F", 12345678.0625); testfmt(" 90,00", "%'6.0f", 9000.0); testfmt("90,00.0", "%'.1f", 9000.0); assert(setlocale(LC_NUMERIC, "ru_RU.ISO8859-5")); /* decimalpoint==, */ testfmt("3,1415", "%g", 3.1415); /* thousands=. decimalpoint=, grouping=3;3 */ assert(setlocale(LC_NUMERIC, "el_GR.ISO8859-7")); /* decimalpoint==, */ testfmt("1.234,00", "%'.2f", 1234.00); testfmt("123.456,789", "%'.3f", 123456.789); assert(setlocale(LC_NUMERIC, "C")); testfmt("12345678.062500", "%'f", 12345678.0625); testfmt("9000.000000", "%'f", 9000.0); printf("ok 5 - printfloat\n"); /* * Signed conversions */ testfmt("+2.500000e-01", "%+e", 0.25); testfmt("+0.000000", "%+F", 0.0); testfmt("-1", "%+g", -1.0); testfmt("-1.000000e+00", "% e", -1.0); testfmt("+1.000000", "% +f", 1.0); testfmt(" 1", "% g", 1.0); testfmt(" 0", "% g", 0.0); printf("ok 6 - printfloat\n"); /* * ``Alternate form'' */ testfmt("1.250e+00", "%#.3e", 1.25); testfmt("123.000000", "%#f", 123.0); testfmt(" 12345.", "%#7.5g", 12345.0); testfmt(" 1.00000", "%#8g", 1.0); testfmt("0.0", "%#.2g", 0.0); printf("ok 7 - printfloat\n"); /* * Padding and decimal point placement */ testfmt("03.2E+00", "%08.1E", 3.25); testfmt("003.25", "%06.2F", 3.25); testfmt("0003.25", "%07.4G", 3.25); testfmt("3.14159e-05", "%g", 3.14159e-5); testfmt("0.000314159", "%g", 3.14159e-4); testfmt("3.14159e+06", "%g", 3.14159e6); testfmt("314159", "%g", 3.14159e5); testfmt("314159.", "%#g", 3.14159e5); testfmt(" 9.000000e+03", "%13e", 9000.0); testfmt(" 9000.000000", "%12f", 9000.0); testfmt(" 9000", "%5g", 9000.0); testfmt(" 900000.", "%#8g", 900000.0); testfmt(" 9e+06", "%6g", 9000000.0); testfmt(" 9.000000e-04", "%13e", 0.0009); testfmt(" 0.000900", "%9f", 0.0009); testfmt(" 0.0009", "%7g", 0.0009); testfmt(" 9e-05", "%6g", 0.00009); testfmt(" 9.00000e-05", "%#12g", 0.00009); testfmt(" 9.e-05", "%#7.1g", 0.00009); testfmt(" 0.0", "%4.1f", 0.0); testfmt("90.0", "%4.1f", 90.0); testfmt(" 100", "%4.0f", 100.0); testfmt("9.0e+01", "%4.1e", 90.0); testfmt("1e+02", "%4.0e", 100.0); printf("ok 8 - printfloat\n"); /* * Decimal rounding */ fesetround(FE_DOWNWARD); testfmt("4.437", "%.3f", 4.4375); testfmt("-4.438", "%.3f", -4.4375); testfmt("4.437", "%.3Lf", 4.4375L); testfmt("-4.438", "%.3Lf", -4.4375L); fesetround(FE_UPWARD); testfmt("4.438", "%.3f", 4.4375); testfmt("-4.437", "%.3f", -4.4375); testfmt("4.438", "%.3Lf", 4.4375L); testfmt("-4.437", "%.3Lf", -4.4375L); fesetround(FE_TOWARDZERO); testfmt("4.437", "%.3f", 4.4375); testfmt("-4.437", "%.3f", -4.4375); testfmt("4.437", "%.3Lf", 4.4375L); testfmt("-4.437", "%.3Lf", -4.4375L); fesetround(FE_TONEAREST); testfmt("4.438", "%.3f", 4.4375); testfmt("-4.438", "%.3f", -4.4375); testfmt("4.438", "%.3Lf", 4.4375L); testfmt("-4.438", "%.3Lf", -4.4375L); printf("ok 9 - printfloat\n"); /* * Hexadecimal floating point (%a, %A) tests. Some of these * are only valid if the implementation converts to hex digits * on nibble boundaries. */ testfmt("0x0p+0", "%a", 0x0.0p0); testfmt("0X0.P+0", "%#LA", 0x0.0p0L); testfmt("inf", "%La", (long double)INFINITY); testfmt("+INF", "%+A", INFINITY); testfmt("nan", "%La", (long double)NAN); testfmt("NAN", "%A", NAN); testfmt(" 0x1.23p+0", "%10a", 0x1.23p0); testfmt(" 0x1.23p-500", "%12a", 0x1.23p-500); testfmt(" 0x1.2p+40", "%10.1a", 0x1.23p40); testfmt(" 0X1.230000000000000000000000P-4", "%32.24A", 0x1.23p-4); testfmt("0x1p-1074", "%a", 0x1p-1074); testfmt("0x1.2345p-1024", "%a", 0x1.2345p-1024); #if (LDBL_MANT_DIG == 64) && !defined(__i386__) testfmt("0x1.921fb54442d18468p+1", "%La", 0x3.243f6a8885a308dp0L); testfmt("0x1p-16445", "%La", 0x1p-16445L); testfmt("0x1.30ecap-16381", "%La", 0x9.8765p-16384L); #elif (LDBL_MANT_DIG == 113) testfmt("0x1.921fb54442d18469898cc51701b8p+1", "%La", 0x3.243f6a8885a308d313198a2e037p0L); testfmt("0x1p-16494", "%La", 0x1p-16494L); testfmt("0x1.2345p-16384", "%La", 0x1.2345p-16384L); #else testfmt("0x1.921fb54442d18p+1", "%La", 0x3.243f6a8885a31p0L); testfmt("0x1p-1074", "%La", 0x1p-1074L); testfmt("0x1.30ecap-1021", "%La", 0x9.8765p-1024L); #endif printf("ok 10 - printfloat\n"); /* * Hexadecimal rounding */ fesetround(FE_TOWARDZERO); testfmt("0X1.23456789ABCP+0", "%.11A", 0x1.23456789abcdep0); testfmt("-0x1.23456p+0", "%.5a", -0x1.23456789abcdep0); testfmt("0x1.23456p+0", "%.5a", 0x1.23456789abcdep0); testfmt("0x1.234567p+0", "%.6a", 0x1.23456789abcdep0); testfmt("-0x1.234566p+0", "%.6a", -0x1.23456689abcdep0); fesetround(FE_DOWNWARD); testfmt("0X1.23456789ABCP+0", "%.11A", 0x1.23456789abcdep0); testfmt("-0x1.23457p+0", "%.5a", -0x1.23456789abcdep0); testfmt("0x1.23456p+0", "%.5a", 0x1.23456789abcdep0); testfmt("0x1.234567p+0", "%.6a", 0x1.23456789abcdep0); testfmt("-0x1.234567p+0", "%.6a", -0x1.23456689abcdep0); fesetround(FE_UPWARD); testfmt("0X1.23456789ABDP+0", "%.11A", 0x1.23456789abcdep0); testfmt("-0x1.23456p+0", "%.5a", -0x1.23456789abcdep0); testfmt("0x1.23457p+0", "%.5a", 0x1.23456789abcdep0); testfmt("0x1.234568p+0", "%.6a", 0x1.23456789abcdep0); testfmt("-0x1.234566p+0", "%.6a", -0x1.23456689abcdep0); fesetround(FE_TONEAREST); testfmt("0x1.23456789abcdep+4", "%a", 0x1.23456789abcdep4); testfmt("0X1.23456789ABDP+0", "%.11A", 0x1.23456789abcdep0); testfmt("-0x1.23456p+0", "%.5a", -0x1.23456789abcdep0); testfmt("0x1.23456p+0", "%.5a", 0x1.23456789abcdep0); testfmt("0x1.234568p+0", "%.6a", 0x1.23456789abcdep0); testfmt("-0x1.234567p+0", "%.6a", -0x1.23456689abcdep0); testfmt("0x1.00p-1029", "%.2a", 0x1.fffp-1030); testfmt("0x1.00p-1026", "%.2a", 0xf.fffp-1030); testfmt("0x1.83p+0", "%.2a", 1.51); printf("ok 11 - printfloat\n"); return (0); }
TEST(fenv, fesetround_fegetround_FE_UPWARD) { fesetround(FE_UPWARD); ASSERT_EQ(FE_UPWARD, fegetround()); TestRounding(8388610.0f, 2.0f); }