示例#1
0
double _Complex
__muldc3(double fa, double fb, double fc, double fd)
{
	union ud ua, ub, uc, ud, ux, uy, uac, ubd, uad, ubc;

	ua.f = fa;
	ub.f = fb;
	uc.f = fc;
	ud.f = fd;

	uac.f = ua.f * uc.f;
	ubd.f = ub.f * ud.f;
	uad.f = ua.f * ud.f;
	ubc.f = ub.f * uc.f;

	ux.f=uac.f-ubd.f;
	uy.f=uad.f+ubc.f;


	if (DOUBLE_ISNAN(ux) && DOUBLE_ISNAN(uy)) {
		/* Recover infinities that computed as NaN+iNaN ... */
		int recalc = 0;
		if (DOUBLE_ISINF(ua) || DOUBLE_ISINF(ub) ) { // z is infinite
			/* "Box" the infinity and change NaNs
			   in the other factor to 0 */
			ua.f = pcc_copysign(DOUBLE_ISINF(ua) ? 1.0 : 0.0, ua.f);
			ub.f = pcc_copysign(DOUBLE_ISINF(ub) ? 1.0 : 0.0, ub.f);
			if (DOUBLE_ISNAN(uc)) uc.f = pcc_copysign(0.0, uc.f);
			if (DOUBLE_ISNAN(ud)) ud.f = pcc_copysign(0.0, ud.f);
			recalc = 1;
		}
		if (DOUBLE_ISINF(uc) || DOUBLE_ISINF(ud) ) { // w is infinite
			/* "Box" the infinity and change NaNs
			    in the other factor to 0 */
			uc.f = pcc_copysign(DOUBLE_ISINF(uc) ? 1.0 : 0.0, uc.f);
			ud.f = pcc_copysign(DOUBLE_ISINF(ud) ? 1.0 : 0.0, ud.f);
			if (DOUBLE_ISNAN(ua)) ua.f = pcc_copysign(0.0, ua.f);
			if (DOUBLE_ISNAN(ub)) ub.f = pcc_copysign(0.0, ub.f);
			recalc = 1;
		}
		if (!recalc && (DOUBLE_ISINF(uac) || DOUBLE_ISINF(ubd) ||
		    DOUBLE_ISINF(uad) || DOUBLE_ISINF(ubc))) {
			/* Recover infinities from overflow by
			   changing NaNs to 0 ... */
			if (DOUBLE_ISNAN(ua)) ua.f = pcc_copysign(0.0, ua.f);
			if (DOUBLE_ISNAN(ub)) ub.f = pcc_copysign(0.0, ub.f);
			if (DOUBLE_ISNAN(uc)) uc.f = pcc_copysign(0.0, uc.f);
			if (DOUBLE_ISNAN(ud)) ud.f = pcc_copysign(0.0, ud.f);
			recalc = 1;
		}
		if (recalc) {
			ux.f = __builtin_inf() * ( ua.f * uc.f - ub.f * ud.f );
			uy.f = __builtin_inf() * ( ua.f * ud.f + ub.f * uc.f );
		}
	}
	return ux.f + 1.0iF * uy.f;
}
示例#2
0
static void
check_inf_nan (void)
{
  /* only if nans and infs are available */
#if _GMP_IEEE_FLOATS
  mpfr_t  x;
  double  d;
  long    exp;

  mpfr_init2 (x, 123);

  mpfr_set_inf (x, 1);
  d = mpfr_get_d_2exp (&exp, x, MPFR_RNDZ);
  ASSERT_ALWAYS (d > 0);
  ASSERT_ALWAYS (DOUBLE_ISINF (d));

  mpfr_set_inf (x, -1);
  d = mpfr_get_d_2exp (&exp, x, MPFR_RNDZ);
  ASSERT_ALWAYS (d < 0);
  ASSERT_ALWAYS (DOUBLE_ISINF (d));

  mpfr_set_nan (x);
  d = mpfr_get_d_2exp (&exp, x, MPFR_RNDZ);
  ASSERT_ALWAYS (DOUBLE_ISNAN (d));

  mpfr_clear (x);
#endif
}
示例#3
0
文件: tget_d.c 项目: Canar/mpfr
static void
check_inf_nan (void)
{
  /* only if nans and infs are available */
#if _GMP_IEEE_FLOATS && !defined(MPFR_ERRDIVZERO)
  mpfr_t  x;
  double  d;

  mpfr_init2 (x, 123);

  mpfr_set_inf (x, 1);
  d = mpfr_get_d (x, MPFR_RNDZ);
  ASSERT_ALWAYS (d > 0);
  ASSERT_ALWAYS (DOUBLE_ISINF (d));

  mpfr_set_inf (x, -1);
  d = mpfr_get_d (x, MPFR_RNDZ);
  ASSERT_ALWAYS (d < 0);
  ASSERT_ALWAYS (DOUBLE_ISINF (d));

  mpfr_set_nan (x);
  d = mpfr_get_d (x, MPFR_RNDZ);
  ASSERT_ALWAYS (DOUBLE_ISNAN (d));

  mpfr_clear (x);
#endif
}
示例#4
0
static void
check_inf_nan (void)
{
#if !defined(MPFR_ERRDIVZERO)
  mpfr_t  x;
  double  d;
  long    exp;

  mpfr_init2 (x, 123);

  mpfr_set_inf (x, 1);
  d = (double) mpfr_get_ld_2exp (&exp, x, MPFR_RNDZ);
  MPFR_ASSERTN (d > 0);
  MPFR_ASSERTN (DOUBLE_ISINF (d));

  mpfr_set_inf (x, -1);
  d = (double) mpfr_get_ld_2exp (&exp, x, MPFR_RNDZ);
  MPFR_ASSERTN (d < 0);
  MPFR_ASSERTN (DOUBLE_ISINF (d));

  mpfr_set_nan (x);
  d = (double) mpfr_get_ld_2exp (&exp, x, MPFR_RNDZ);
  MPFR_ASSERTN (DOUBLE_ISNAN (d));

  mpfr_clear (x);
#endif
}
示例#5
0
static double
pcc_scalbn(double x, int exp)
{
	union ud x1, z1, z2;

	x1.f = x;
	if (DOUBLE_ISINF(x1) || DOUBLE_ISNAN(x1))
		return x;
	exp += 1023;
	z1.dil = z2.dil = 0;
	if (exp <= 0) {
		z2.dih = (1023 - 110) << 20;
		x *= z2.f;
		exp += 110;
		if (exp < 0) exp = 0;
	} else if (exp > 2046) {
		z2.dih = (1024 + 55) << 20;
		x *= z2.f;
		exp -= 55;
		if (exp > 2046) exp = 2046;
	}
	z1.dih = exp << 20;
	x *= z1.f;
	return x;
}
示例#6
0
static void
check_get_d_2exp_inf_nan (void)
{
  double var_d;
  long exp;
  mpfr_t var;

  mpfr_init2 (var, MPFR_PREC_MIN);

  mpfr_set_nan (var);
  var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN);
  if (!DOUBLE_ISNAN (var_d))
    {
      printf ("mpfr_get_d_2exp with a NAN mpfr value returned a wrong value :\n"
              " waiting for %g got %g\n", MPFR_DBL_NAN, var_d);
      exit (1);
    }

  mpfr_set_zero (var, 1);
  var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN);
  if ((exp != 0) || (var_d != 0.0))
    {
      printf ("mpfr_get_d_2exp with a +0.0 mpfr value returned a wrong value :\n"
              " double waiting for 0.0 got %g\n exp waiting for 0 got %ld\n",
              var_d, exp);
      exit (1);
    }

  mpfr_set_zero (var, -1);
  var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN);
  if ((exp != 0) || (var_d != DBL_NEG_ZERO))
    {
      printf ("mpfr_get_d_2exp with a +0.0 mpfr value returned a wrong value :\n"
              " double waiting for %g got %g\n exp waiting for 0 got %ld\n",
              DBL_NEG_ZERO, var_d, exp);
      exit (1);
    }

  mpfr_set_inf (var, 1);
  var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN);
  if (var_d != MPFR_DBL_INFP)
    {
      printf ("mpfr_get_d_2exp with a +Inf mpfr value returned a wrong value :\n"
              " waiting for %g got %g\n", MPFR_DBL_INFP, var_d);
      exit (1);
    }

  mpfr_set_inf (var, -1);
  var_d = mpfr_get_d_2exp (&exp, var, MPFR_RNDN);
  if (var_d != MPFR_DBL_INFM)
    {
      printf ("mpfr_get_d_2exp with a -Inf mpfr value returned a wrong value :\n"
              " waiting for %g got %g\n", MPFR_DBL_INFM, var_d);
      exit (1);
    }

  mpfr_clear (var);
}
示例#7
0
int
main (int argc, char *argv[])
{
  mpfr_t x, y, z;
  unsigned long k, n;
  volatile double d;
  double dd;

  tests_start_mpfr ();
  mpfr_test_init ();

#ifndef MPFR_DOUBLE_SPEC
  printf ("Warning! The MPFR_DOUBLE_SPEC macro is not defined. This means\n"
          "that you do not have a conforming C implementation and problems\n"
          "may occur with conversions between MPFR numbers and standard\n"
          "floating-point types. Please contact the MPFR team.\n");
#elif MPFR_DOUBLE_SPEC == 0
  /*
  printf ("The type 'double' of your C implementation does not seem to\n"
          "correspond to the IEEE-754 double precision. Though code has\n"
          "been written to support such implementations, tests have been\n"
          "done only on IEEE-754 double-precision implementations and\n"
          "conversions between MPFR numbers and standard floating-point\n"
          "types may be inaccurate. You may wish to contact the MPFR team\n"
          "for further testing.\n");
  */
  printf ("The type 'double' of your C implementation does not seem to\n"
          "correspond to the IEEE-754 double precision. Such particular\n"
          "implementations are not supported yet, and conversions between\n"
          "MPFR numbers and standard floating-point types may be very\n"
          "inaccurate.\n");
  printf ("FLT_RADIX    = %ld\n", (long) FLT_RADIX);
  printf ("DBL_MANT_DIG = %ld\n", (long) DBL_MANT_DIG);
  printf ("DBL_MIN_EXP  = %ld\n", (long) DBL_MIN_EXP);
  printf ("DBL_MAX_EXP  = %ld\n", (long) DBL_MAX_EXP);
#endif

  mpfr_init (x);

  mpfr_set_nan (x);
  d = mpfr_get_d (x, MPFR_RNDN);
  if (! DOUBLE_ISNAN (d))
    {
      printf ("ERROR for NAN (1)\n");
#ifdef MPFR_NANISNAN
      printf ("The reason is that NAN == NAN. Please look at the configure "
              "output\nand Section \"In case of problem\" of the INSTALL "
              "file.\n");
#endif
      exit (1);
    }
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_set_d (x, d, MPFR_RNDN);
  if (! mpfr_nan_p (x))
    {
      printf ("ERROR for NAN (2)\n");
#ifdef MPFR_NANISNAN
      printf ("The reason is that NAN == NAN. Please look at the configure "
              "output\nand Section \"In case of problem\" of the INSTALL "
              "file.\n");
#endif
      exit (1);
    }

  d = 0.0;
  mpfr_set_d (x, d, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));
  d = -d;
  mpfr_set_d (x, d, MPFR_RNDN);
  if (mpfr_cmp_ui (x, 0) != 0 || MPFR_IS_POS(x))
    {
      printf ("Error in mpfr_set_d on -0\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  d = mpfr_get_d (x, MPFR_RNDN);
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_set_d (x, d, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);

  mpfr_set_inf (x, -1);
  d = mpfr_get_d (x, MPFR_RNDN);
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_set_d (x, d, MPFR_RNDN);
  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) < 0);

  mpfr_set_prec (x, 2);

  /* checks that denormalized are not flushed to zero */
  d = DBL_MIN; /* 2^(-1022) */
  for (n=0; n<52; n++, d /= 2.0)
    if (d != 0.0) /* should be 2^(-1022-n) */
      {
        mpfr_set_d (x, d, MPFR_RNDN);
        if (mpfr_cmp_ui_2exp (x, 1, -1022-n))
          {
            printf ("Wrong result for d=2^(%ld), ", -1022-n);
            printf ("got ");
            mpfr_out_str (stdout, 10, 10, x, MPFR_RNDN);
            printf ("\n");
            mpfr_print_binary (x);
            puts ("");
            exit (1);
          }
      }

   /* checks that rounds to nearest sets the last
     bit to zero in case of equal distance */
   mpfr_set_d (x, 5.0, MPFR_RNDN);
   if (mpfr_cmp_ui (x, 4))
     {
       printf ("Error in tset_d: expected 4.0, got ");
       mpfr_print_binary (x); putchar('\n');
       exit (1);
     }
   mpfr_set_d (x, -5.0, MPFR_RNDN);
   if (mpfr_cmp_si (x, -4))
     {
       printf ("Error in tset_d: expected -4.0, got ");
       mpfr_print_binary (x); putchar('\n');
       exit (1);
     }

   mpfr_set_d (x, 9.84891017624509146344e-01, MPFR_RNDU);
   if (mpfr_cmp_ui (x, 1))
     {
       printf ("Error in tset_d: expected 1.0, got ");
       mpfr_print_binary (x); putchar('\n');
       exit (1);
     }

  mpfr_init2 (z, 32);
  mpfr_set_d (z, 1.0, (mpfr_rnd_t) 0);
  if (mpfr_cmp_ui (z, 1))
    {
      mpfr_print_binary (z); puts ("");
      printf ("Error: 1.0 != 1.0\n");
      exit (1);
    }
  mpfr_set_prec (x, 53);
  mpfr_init2 (y, 53);
  mpfr_set_d (x, d=-1.08007920352320089721e+150, (mpfr_rnd_t) 0);
  if (mpfr_get_d1 (x) != d)
    {
      mpfr_print_binary (x); puts ("");
      printf ("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n",
              d, mpfr_get_d1 (x));
      exit (1);
    }

  mpfr_set_d (x, 8.06294740693074521573e-310, (mpfr_rnd_t) 0);
  d = -6.72658901114033715233e-165;
  mpfr_set_d (x, d, (mpfr_rnd_t) 0);
  if (d != mpfr_get_d1 (x))
    {
      mpfr_print_binary (x);
      puts ("");
      printf ("Error: get_d o set_d <> identity for d = %1.20e %1.20e\n",
              d, mpfr_get_d1 (x));
      exit (1);
    }

  n = (argc==1) ? 500000 : atoi(argv[1]);
  for (k = 1; k <= n; k++)
    {
      do
        {
          d = DBL_RAND ();
        }
#ifdef HAVE_DENORMS
      while (0);
#else
      while (ABS(d) < DBL_MIN);
#endif
      mpfr_set_d (x, d, (mpfr_rnd_t) 0);
      dd = mpfr_get_d1 (x);
      if (d != dd && !(Isnan(d) && Isnan(dd)))
        {
          printf ("Mismatch on : %1.18g != %1.18g\n", d, mpfr_get_d1 (x));
          mpfr_print_binary (x);
          puts ("");
          exit (1);
        }
    }

  mpfr_clear (x);
  mpfr_clear (y);
  mpfr_clear (z);

  tests_end_mpfr ();
  return 0;
}
示例#8
0
double _Complex
__divdc3(double ax, double bx, double cx, double dx)
{
	double denom;
	union ud ua, ub, uc, ud, ur, ulogbw, ux, uy;
	int uci, udi, res, ilogbw = 0;

	ua.f = ax;
	ub.f = bx;
	uc.f = cx;
	ud.f = dx;

	/* fabsf; clear sign */
	uci = uc.dih & DOUBLE_MANTEXP;
	udi = ud.dih & DOUBLE_MANTEXP;

	/* fmaxf; ordinary integer compare */
	if ((uci > udi) || (uci == udi && uc.dil > ud.dil)) {
		ur.dih = uci;
		ur.dil = uc.dil;
	} else {
		ur.dih = udi;
		ur.dil = ud.dil;
	}

	/* logbf */
	res = ur.dih >> 20;
	if (ur.dih == 0 && ur.dil == 0)
		ulogbw.f = (double)-1.0/ur.f;
	else if (res == 2047)
		ulogbw.f = ur.f * ur.f;
	else if (res == 0)
		ulogbw.f = -1022.0;
	else
		ulogbw.f = (res-1023);

	/* isfinite */
	if (DOUBLE_ISFIN(ulogbw)) {
		ilogbw = (int)ulogbw.f;
		uc.f = pcc_scalbn(uc.f, -ilogbw);
		ud.f = pcc_scalbn(ud.f, -ilogbw);
	}
	denom = uc.f * uc.f + ud.f * ud.f;
	ux.f = pcc_scalbn((ua.f * uc.f + ub.f * ud.f) / denom, -ilogbw);
	uy.f = pcc_scalbn((ub.f * uc.f - ua.f * ud.f) / denom, -ilogbw);

	if (DOUBLE_ISNAN(ux) && DOUBLE_ISNAN(uy)) {
		if ((denom == 0.0) &&
		    (!DOUBLE_ISNAN(ua) || !DOUBLE_ISNAN(ub))) {
			ux.f = pcc_copysign(__builtin_inff(), uc.f) * ua.f;
			uy.f = pcc_copysign(__builtin_inff(), uc.f) * ub.f;
		} else if ((DOUBLE_ISINF(ua) || DOUBLE_ISINF(ub)) &&
		    DOUBLE_ISFIN(uc) && DOUBLE_ISFIN(ud)) {
			ua.f = pcc_copysign(DOUBLE_ISINF(ua) ? 1.0 : 0.0, ua.f);
			ub.f = pcc_copysign(DOUBLE_ISINF(ub) ? 1.0 : 0.0, ub.f);
			ux.f = __builtin_inf() * ( ua.f * uc.f + ub.f * ud.f );
			uy.f = __builtin_inf() * ( ub.f * uc.f - ua.f * ud.f );
		} else if (DOUBLE_ISINF(ulogbw) &&
		    DOUBLE_ISFIN(ua) && DOUBLE_ISFIN(ub)) {
			uc.f = pcc_copysign(DOUBLE_ISINF(uc) ? 1.0 : 0.0, uc.f);
			ud.f = pcc_copysign(DOUBLE_ISINF(ud) ? 1.0 : 0.0, ud.f);
			ux.f = 0.0 * ( ua.f * uc.f + ub.f * ud.f );
			uy.f = 0.0 * ( ub.f * uc.f - ua.f * ud.f );
		}
	}
	return ux.f + 1.0iF * uy.f;
}
示例#9
0
static void
check_special (void)
{
  __float128 f;
  mpfr_t x;

  mpfr_init2 (x, 113);

#if !defined(MPFR_ERRDIVZERO)
  /* check NaN */
  f = 0.0 / 0.0;
  mpfr_set_float128 (x, f, MPFR_RNDN);
  if (! mpfr_nan_p (x))
    {
      printf ("Error in mpfr_set_float128(x, NaN)\n");
      exit (1);
    }
  f = mpfr_get_float128 (x, MPFR_RNDN);
  if (! DOUBLE_ISNAN (f))
    {
      printf ("Error in mpfr_get_float128(NaN)\n");
      printf ("got %f\n", (double) f);
      exit (1);
    }

  /* check +Inf */
  f = 1.0 / 0.0;
  mpfr_set_float128 (x, f, MPFR_RNDN);
  if (! mpfr_inf_p (x) || MPFR_IS_NEG (x))
    {
      printf ("Error in mpfr_set_float128(x, +Inf)\n");
      exit (1);
    }
  f = mpfr_get_float128 (x, MPFR_RNDN);
  if (f != (1.0 / 0.0))
    {
      printf ("Error in mpfr_get_float128(+Inf)\n");
      exit (1);
    }

  /* check -Inf */
  f = -1.0 / 0.0;
  mpfr_set_float128 (x, f, MPFR_RNDN);
  if (! mpfr_inf_p (x) || MPFR_IS_POS (x))
    {
      printf ("Error in mpfr_set_float128(x, -Inf)\n");
      exit (1);
    }
  f = mpfr_get_float128 (x, MPFR_RNDN);
  if (f != (-1.0 / 0.0))
    {
      printf ("Error in mpfr_get_float128(-Inf)\n");
      exit (1);
    }
#endif

  /* check +0 */
  f = 0.0;
  mpfr_set_float128 (x, f, MPFR_RNDN);
  if (! mpfr_zero_p (x) || MPFR_IS_NEG (x))
    {
      printf ("Error in mpfr_set_float128(x, +0)\n");
      exit (1);
    }
  f = mpfr_get_float128 (x, MPFR_RNDN);
  if (f != 0.0)  /* the sign is not checked */
    {
      printf ("Error in mpfr_get_float128(+0.0)\n");
      exit (1);
    }
#if !defined(MPFR_ERRDIVZERO) && defined(HAVE_SIGNEDZ)
  if (1 / f != 1 / 0.0)  /* check the sign */
    {
      printf ("Error in mpfr_get_float128(+0.0)\n");
      exit (1);
    }
#endif

  /* check -0 */
  f = -0.0;
  mpfr_set_float128 (x, f, MPFR_RNDN);
  if (! mpfr_zero_p (x))
    {
      printf ("Error in mpfr_set_float128(x, -0)\n");
      exit (1);
    }
#if defined(HAVE_SIGNEDZ)
  if (MPFR_IS_POS (x))
    {
      printf ("Error in mpfr_set_float128(x, -0)\n");
      exit (1);
    }
#endif
  f = mpfr_get_float128 (x, MPFR_RNDN);
  if (f != -0.0)  /* the sign is not checked */
    {
      printf ("Error in mpfr_get_float128(-0.0)\n");
      exit (1);
    }
#if !defined(MPFR_ERRDIVZERO) && defined(HAVE_SIGNEDZ)
  if (1 / f != 1 / -0.0)  /* check the sign */
    {
      printf ("Error in mpfr_get_float128(-0.0)\n");
      exit (1);
    }
#endif

  mpfr_clear (x);
}