Beispiel #1
0
TEST(fenv, fesetround_fegetround_FE_DOWNWARD) {
  fesetround(FE_DOWNWARD);
  ASSERT_EQ(FE_DOWNWARD, fegetround());
  TestRounding(8388609.0f, 1.0f);
}
Beispiel #2
0
/*
 * 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); }
Beispiel #4
0
/*
 * 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;
}
Beispiel #6
0
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);
}
Beispiel #7
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;
}
Beispiel #9
0
void m5_fesetround(int rm)
{
    assert(rm >= 0 && rm < 4);
    fesetround(m5_round_ops[rm]);
}
Beispiel #10
0
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);
}
Beispiel #11
0
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);
}
Beispiel #12
0
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);
}
Beispiel #16
0
void Sys_SetFloatEnv(void)
{
	// rounding toward nearest
	fesetround(FE_TONEAREST);
}
Beispiel #17
0
/*
 * 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);
}
Beispiel #18
0
void Sys_SetFloatEnv(void) {
	// rounding towards 0
	fesetround(FE_TOWARDZERO);
}
Beispiel #19
0
_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;
	}
    }
Beispiel #20
0
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
		}
	}
}
Beispiel #21
0
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;
}
Beispiel #22
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;
}
Beispiel #24
0
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;
}
Beispiel #25
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;
}
Beispiel #26
0
float setRoundingModeAndCast(int mode, double d) {
  fesetround(mode);
  return (float)d;
}
Beispiel #27
0
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.");
     }
 }
Beispiel #29
0
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);
}
Beispiel #30
0
TEST(fenv, fesetround_fegetround_FE_UPWARD) {
  fesetround(FE_UPWARD);
  ASSERT_EQ(FE_UPWARD, fegetround());
  TestRounding(8388610.0f, 2.0f);
}