static void
huge (void)
{
  mpfr_t x, y, z;
  int inex;

  /* TODO: extend the exponent range and use mpfr_get_emax (). */
  mpfr_inits2 (32, x, y, z, (mpfr_ptr) 0);
  mpfr_set_ui_2exp (x, 1, 1073741822, MPFR_RNDN);
  inex = mpfr_acosh (y, x, MPFR_RNDN);
  mpfr_set_str_binary (z, "0.10110001011100100001011111110101E30");
  if (!mpfr_equal_p (y, z))
    {
      printf ("Error in huge:\nexpected ");
      mpfr_dump (z);
      printf ("got      ");
      mpfr_dump (y);
      exit (1);
    }
  MPFR_ASSERTN (inex < 0);

  mpfr_clears (x, y, z, (mpfr_ptr) 0);
}
Beispiel #2
0
/* expx is the value of exp(X) rounded towards -infinity */
static void
check_worst_case (const char *Xs, const char *expxs)
{
  mpfr_t x, y;

  mpfr_inits2(53, x, y, NULL);
  mpfr_set_str1(x, Xs);
  mpfr_exp(y, x, GMP_RNDD);
  if (mpfr_cmp_str1 (y, expxs))
    {
      printf ("exp(x) rounded towards -infinity is wrong\n");
      exit(1);
    }
  mpfr_set_str1(x, Xs);
  mpfr_exp(x, x, GMP_RNDU);
  mpfr_add_one_ulp(y, GMP_RNDN);
  if (mpfr_cmp(x,y))
    {
      printf ("exp(x) rounded towards +infinity is wrong\n");
      exit(1);
    }
  mpfr_clears(x,y,NULL);
}
Beispiel #3
0
/* Worst case incorrectly rounded in r5573, found with the bad_cases test */
static void
bad_case1 (void)
{
  mpfr_t x, y, z;

  mpfr_init2 (x, 72);
  mpfr_inits2 (6, y, z, (mpfr_ptr) 0);
  mpfr_set_str (x, "1.08310518720928b30e@-120", 16, GMP_RNDN);
  mpfr_set_str (z, "f.8@59", 16, GMP_RNDN);
  /* z = rec_sqrt(x) rounded on 6 bits toward 0, the exact value
     being ~= f.bffffffffffffffffa11@59. */
  mpfr_rec_sqrt (y, x, GMP_RNDZ);
  if (mpfr_cmp0 (y, z) != 0)
    {
      printf ("Error in bad_case1\nexpected ");
      mpfr_out_str (stdout, 16, 0, z, GMP_RNDN);
      printf ("\ngot      ");
      mpfr_out_str (stdout, 16, 0, y, GMP_RNDN);
      printf ("\n");
      exit (1);
    }
  mpfr_clears (x, y, z, (mpfr_ptr) 0);
}
Beispiel #4
0
/* expx is the value of exp(X) rounded toward -infinity */
static void
check_worst_case (const char *Xs, const char *expxs)
{
  mpfr_t x, y;

  mpfr_inits2 (53, x, y, (mpfr_ptr) 0);
  mpfr_set_str1(x, Xs);
  test_exp(y, x, MPFR_RNDD);
  if (mpfr_cmp_str1 (y, expxs))
    {
      printf ("exp(x) rounded toward -infinity is wrong\n");
      exit(1);
    }
  mpfr_set_str1(x, Xs);
  test_exp(x, x, MPFR_RNDU);
  mpfr_nexttoinf (y);
  if (mpfr_cmp(x,y))
    {
      printf ("exp(x) rounded toward +infinity is wrong\n");
      exit(1);
    }
  mpfr_clears (x, y, (mpfr_ptr) 0);
}
Beispiel #5
0
static void
check_overflow (void)
{
  mpfr_t x, y;
  int inex, r;

  mpfr_inits2 (8, x, y, (mpfr_ptr) 0);
  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_setmax (x, mpfr_get_emax ());

  RND_LOOP(r)
    {
      mpfr_clear_overflow ();
      inex = mpfr_hypot (y, x, x, (mpfr_rnd_t) r);
      if (!mpfr_overflow_p ())
        {
          printf ("No overflow in check_overflow for %s%s\n",
                  mpfr_print_rnd_mode ((mpfr_rnd_t) r),
                  ext ? ", extended exponent range" : "");
          exit (1);
        }
      MPFR_ASSERTN (MPFR_IS_POS (y));
      if (r == MPFR_RNDZ || r == MPFR_RNDD)
        {
          MPFR_ASSERTN (inex < 0);
          MPFR_ASSERTN (!mpfr_inf_p (y));
          mpfr_nexttoinf (y);
        }
      else
        {
          MPFR_ASSERTN (inex > 0);
        }
      MPFR_ASSERTN (mpfr_inf_p (y));
    }

  mpfr_clears (x, y, (mpfr_ptr) 0);
}
Beispiel #6
0
static void
check_random (mpfr_prec_t p)
{
  mpfr_t x,y,z;
  int r;
  int i, inexact1, inexact2;

  mpfr_inits2 (p, x, y, z, (mpfr_ptr) 0);
  for(i = 0 ; i < 500 ; i++)
    {
      mpfr_urandomb (x, RANDS);
      if (MPFR_IS_PURE_FP(x))
        for (r = 0 ; r < MPFR_RND_MAX ; r++)
          {
            inexact1 = mpfr_mul (y, x, x, (mpfr_rnd_t) r);
            inexact2 = mpfr_sqr (z, x, (mpfr_rnd_t) r);
            if (mpfr_cmp (y, z))
              error1 ((mpfr_rnd_t) r,p,x,y,z);
            if (inexact_sign (inexact1) != inexact_sign (inexact2))
              error2 ((mpfr_rnd_t) r,p,x,y,inexact1,inexact2);
          }
    }
  mpfr_clears (x, y, z, (mpfr_ptr) 0);
}
Beispiel #7
0
/* FastTwoSum: if EXP(x) >= EXP(y), u = o(x+y), v = o(u-x), w = o(y-v),
               then x + y = u + w
thus if u = o(y-x), v = o(u+x), w = o(v-y), then y-x = u-w */
static void
check_two_sum (mpfr_prec_t p)
{
  unsigned int x;
  mpfr_t y, u, v, w;
  mpfr_rnd_t rnd;
  int inexact;

  mpfr_inits2 (p, y, u, v, w, (mpfr_ptr) 0);
  do
    {
      x = randlimb ();
    }
  while (x < 1);
  mpfr_urandomb (y, RANDS);
  rnd = MPFR_RNDN;
  inexact = mpfr_sub_ui (u, y, x, rnd);
  mpfr_add_ui (v, u, x, rnd);
  mpfr_sub (w, v, y, rnd);
  /* as u - (y-x) = w, we should have inexact and w of same sign */
  if (((inexact == 0) && mpfr_cmp_ui (w, 0)) ||
      ((inexact > 0) && (mpfr_cmp_ui (w, 0) <= 0)) ||
      ((inexact < 0) && (mpfr_cmp_ui (w, 0) >= 0)))
    {
      printf ("Wrong inexact flag for prec=%u, rnd=%s\n",
              (unsigned int) p, mpfr_print_rnd_mode (rnd));
      printf ("x=%u\n", x);
      printf ("y="); mpfr_print_binary(y); puts ("");
      printf ("u="); mpfr_print_binary(u); puts ("");
      printf ("v="); mpfr_print_binary(v); puts ("");
      printf ("w="); mpfr_print_binary(w); puts ("");
      printf ("inexact = %d\n", inexact);
      exit (1);
    }
  mpfr_clears (y, u, v, w, (mpfr_ptr) 0);
}
Beispiel #8
0
static void
check_64(void)
{
  mpfr_t x,y,z;

  mpfr_inits2 (64, x, y, z, (mpfr_ptr) 0);

  mpfr_set_str_binary(x, "1.00100100110110101001010010101111000001011100100101010000000000E54");
  mpfr_set_str_binary(y, "1.00000000000000000000000000000000000000000000000000000000000000E584");
  test_div(z, x, y, MPFR_RNDU);
  if (mpfr_cmp_str (z, "0.1001001001101101010010100101011110000010111001001010100000000000E-529", 2, MPFR_RNDN))
    {
      printf("Error for tdiv for MPFR_RNDU and p=64\nx=");
      mpfr_print_binary(x);
      printf("\ny=");
      mpfr_print_binary(y);
      printf("\ngot      ");
      mpfr_print_binary(z);
      printf("\nexpected 0.1001001001101101010010100101011110000010111001001010100000000000E-529\n");
      exit(1);
    }

  mpfr_clears (x, y, z, (mpfr_ptr) 0);
}
Beispiel #9
0
int main (int argc, char** argv)
{
  mpfr_t a;
  mpfr_t b;
  mpfr_t c;
  char* lpsz;
  mpfr_exp_t exp = 0;

  int num = 100 * MPFR_VERSION_MAJOR + 10 * MPFR_VERSION_MINOR + MPFR_VERSION_PATCHLEVEL;
  if (!(num >= 312 && strlen(mpfr_get_version()) > 0))
  {
    return 1;
  }
  mpfr_inits2(32, a, b, c, NULL);
  mpfr_set_str(a, "3.1415926535897932384626433832795028841971693993751058209749445923078164062862", 10, MPFR_RNDN);
  mpfr_set_si(b, 12345678, MPFR_RNDN);
  mpfr_mul(c, a, b, MPFR_RNDN);
  lpsz = mpfr_get_str(NULL, &exp, 10, 13, c, MPFR_RNDN);
  if (strcmp(lpsz, "3878509131250") != 0)
  {
    return 1;
  }
  return 0;
}
Beispiel #10
0
static int
hexadecimal (void)
{
    mpfr_t x, z;
    mpfr_inits2 (64, x, z, (mpfr_ptr) 0);

    /* special */
    mpfr_set_inf (x, 1);
    check_sprintf (pinf_str, "%Ra", x);
    check_sprintf (pinf_str, "%RUa", x);
    check_sprintf (pinf_str, "%RDa", x);
    check_sprintf (pinf_uc_str, "%RA", x);
    check_sprintf (pinf_uc_str, "%RYA", x);
    check_sprintf (pinf_uc_str, "%RZA", x);
    check_sprintf (pinf_uc_str, "%RNA", x);

    mpfr_set_inf (x, -1);
    check_sprintf (minf_str, "%Ra", x);
    check_sprintf (minf_str, "%RYa", x);
    check_sprintf (minf_str, "%RZa", x);
    check_sprintf (minf_str, "%RNa", x);
    check_sprintf (minf_uc_str, "%RA", x);
    check_sprintf (minf_uc_str, "%RUA", x);
    check_sprintf (minf_uc_str, "%RDA", x);

    mpfr_set_nan (x);
    check_sprintf (nan_str, "%Ra", x);
    check_sprintf (nan_uc_str, "%RA", x);

    /* regular numbers */
    mpfr_set_str (x, "FEDCBA9.87654321", 16, MPFR_RNDN);
    mpfr_set_ui (z, 0, MPFR_RNDZ);

    /* simplest case right justified */
    check_sprintf ("   0xf.edcba987654321p+24", "%25Ra", x);
    check_sprintf ("   0xf.edcba987654321p+24", "%25RUa", x);
    check_sprintf ("   0xf.edcba987654321p+24", "%25RDa", x);
    check_sprintf ("   0xf.edcba987654321p+24", "%25RYa", x);
    check_sprintf ("   0xf.edcba987654321p+24", "%25RZa", x);
    check_sprintf ("   0xf.edcba987654321p+24", "%25RNa", x);
    check_sprintf ("                  0x1p+28", "%25.0Ra", x);
    check_sprintf ("                   0x0p+0", "%25.0Ra", z);
    /* sign or space, pad with leading zeros */
    check_sprintf (" 0X00F.EDCBA987654321P+24", "% 025RA", x);
    check_sprintf (" 0X000000000000000001P+28", "% 025.0RA", x);
    check_sprintf (" 0X0000000000000000000P+0", "% 025.0RA", z);
    /* sign + or -, left justified */
    check_sprintf ("+0xf.edcba987654321p+24  ", "%+-25Ra", x);
    check_sprintf ("+0x1p+28                 ", "%+-25.0Ra", x);
    check_sprintf ("+0x0p+0                  ", "%+-25.0Ra", z);
    /* decimal point, left justified, precision and rounding parameter */
    check_vsprintf ("0XF.FP+24 ", "%#-10.*R*A", 1, MPFR_RNDN, x);
    check_vsprintf ("0X1.P+28  ", "%#-10.*R*A", 0, MPFR_RNDN, x);
    check_vsprintf ("0X0.P+0   ", "%#-10.*R*A", 0, MPFR_RNDN, z);
    /* sign or space */
    check_sprintf (" 0xf.eddp+24", "% .3RNa", x);
    check_sprintf (" 0x1p+28",     "% .0RNa", x);
    /* sign + or -, decimal point, pad with leading zeros */
    check_sprintf ("+0X0F.EP+24", "%0+#11.1RZA", x);
    check_sprintf ("+0X00F.P+24", "%0+#11.0RZA", x);
    check_sprintf ("+0X000.0P+0", "%0+#11.1RZA", z);
    /* pad with leading zero */
    check_sprintf ("0x0000f.edcba987654321p+24", "%026RDa", x);
    check_sprintf ("0x0000000000000000000fp+24", "%026.0RDa", x);
    /* sign or space, decimal point, left justified */
    check_sprintf (" 0XF.EP+24 " , "%- #11.1RDA", x);
    check_sprintf (" 0XF.P+24  " , "%- #11.0RDA", x);

    mpfr_mul_si (x, x, -1, MPFR_RNDD);
    mpfr_mul_si (z, z, -1, MPFR_RNDD);

    /* sign + or - */
    check_sprintf ("-0xf.ep+24", "%+10.1RUa", x);
    check_sprintf ("  -0xfp+24", "%+10.0RUa", x);
    check_sprintf ("   -0x0p+0", "%+10.0RUa", z);

    /* rounding bit is zero */
    mpfr_set_str (x, "0xF.7", 16, MPFR_RNDN);
    check_sprintf ("0XFP+0", "%.0RNA", x);
    /* tie case in round to nearest mode */
    mpfr_set_str (x, "0x0.8800000000000000p+3", 16, MPFR_RNDN);
    check_sprintf ("0x9.p-1", "%#.0RNa", x);
    mpfr_set_str (x, "-0x0.9800000000000000p+3", 16, MPFR_RNDN);
    check_sprintf ("-0xap-1", "%.0RNa", x);
    /* trailing zeros in fractional part */
    check_sprintf ("-0X4.C0000000000000000000P+0", "%.20RNA", x);
    /* rounding bit is one and the first non zero bit is far away */
    mpfr_set_prec (x, 1024);
    mpfr_set_ui_2exp (x, 29, -1, MPFR_RNDN);
    mpfr_nextabove (x);
    check_sprintf ("0XFP+0", "%.0RNA", x);

    /* with more than one limb */
    mpfr_set_prec (x, 300);
    mpfr_set_str (x, "0xf.ffffffffffffffffffffffffffffffffffffffffffffffffffff"
                  "fffffffffffffffff", 16, MPFR_RNDN);
    check_sprintf ("0x1p+4 [300]", "%.0RNa [300]", x);
    check_sprintf ("0xfp+0 [300]", "%.0RZa [300]", x);
    check_sprintf ("0x1p+4 [300]", "%.0RYa [300]", x);
    check_sprintf ("0xfp+0 [300]", "%.0RDa [300]", x);
    check_sprintf ("0x1p+4 [300]", "%.0RUa [300]", x);
    check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
                   "%.40RNa", x);
    check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffffffp+0",
                   "%.40RZa", x);
    check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
                   "%.40RYa", x);
    check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffffffp+0",
                   "%.40RDa", x);
    check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
                   "%.40RUa", x);

    mpfr_set_str (x, "0xf.7fffffffffffffffffffffffffffffffffffffffffffffffffff"
                  "ffffffffffffffffff", 16, MPFR_RNDN);
    check_sprintf ("0XFP+0", "%.0RNA", x);
    check_sprintf ("0XFP+0", "%.0RZA", x);
    check_sprintf ("0X1P+4", "%.0RYA", x);
    check_sprintf ("0XFP+0", "%.0RDA", x);
    check_sprintf ("0X1P+4", "%.0RUA", x);
    check_sprintf ("0XF.8P+0", "%.1RNA", x);
    check_sprintf ("0XF.7P+0", "%.1RZA", x);
    check_sprintf ("0XF.8P+0", "%.1RYA", x);
    check_sprintf ("0XF.7P+0", "%.1RDA", x);
    check_sprintf ("0XF.8P+0", "%.1RUA", x);

    /* do not round up to the next power of the base */
    mpfr_set_str (x, "0xf.fffffffffffffffffffffffffffffffffffffeffffffffffffff"
                  "ffffffffffffffffff", 16, MPFR_RNDN);
    check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
                   "%.40RNa", x);
    check_sprintf ("0xf.fffffffffffffffffffffffffffffffffffffeffp+0",
                   "%.40RZa", x);
    check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
                   "%.40RYa", x);
    check_sprintf ("0xf.fffffffffffffffffffffffffffffffffffffeffp+0",
                   "%.40RDa", x);
    check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
                   "%.40RUa", x);

    mpfr_clears (x, z, (mpfr_ptr) 0);
    return 0;
}
Beispiel #11
0
static void
special_atan2 (void)
{
    mpfr_t x, y, z;

    mpfr_inits2 (4, x, y, z, (mpfr_ptr) 0);

    /* Anything with NAN should be set to NAN */
    mpfr_set_ui (y, 0, MPFR_RNDN);
    mpfr_set_nan (x);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (MPFR_IS_NAN (z));
    mpfr_swap (x, y);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (MPFR_IS_NAN (z));

    /* 0+ 0+ --> 0+ */
    mpfr_set_ui (y, 0, MPFR_RNDN);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));
    /* 0- 0+ --> 0- */
    MPFR_CHANGE_SIGN (y);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z));
    /* 0- 0- --> -PI */
    MPFR_CHANGE_SIGN (x);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0);
    /* 0+ 0- --> +PI */
    MPFR_CHANGE_SIGN (y);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0);
    /* 0+ -1 --> PI */
    mpfr_set_si (x, -1, MPFR_RNDN);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0);
    /* 0- -1 --> -PI */
    MPFR_CHANGE_SIGN (y);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0);
    /* 0- +1 --> 0- */
    mpfr_set_ui (x, 1, MPFR_RNDN);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z));
    /* 0+ +1 --> 0+ */
    MPFR_CHANGE_SIGN (y);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));
    /* +1 0+ --> PI/2 */
    mpfr_swap (x, y);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0);
    /* +1 0- --> PI/2 */
    MPFR_CHANGE_SIGN (x);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0);
    /* -1 0- --> -PI/2 */
    MPFR_CHANGE_SIGN (y);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0);
    /* -1 0+ --> -PI/2 */
    MPFR_CHANGE_SIGN (x);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0);

    /* -1 +INF --> -0 */
    MPFR_SET_INF (x);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z));
    /* +1 +INF --> +0 */
    MPFR_CHANGE_SIGN (y);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));
    /* +1 -INF --> +PI */
    MPFR_CHANGE_SIGN (x);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0);
    /* -1 -INF --> -PI */
    MPFR_CHANGE_SIGN (y);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0);
    /* -INF -1 --> -PI/2 */
    mpfr_swap (x, y);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0);
    /* +INF -1  --> PI/2 */
    MPFR_CHANGE_SIGN (y);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0);
    /* +INF -INF --> 3*PI/4 */
    MPFR_SET_INF (x);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "2.356194490192344928", 10, MPFR_RNDN) == 0);
    /* +INF +INF --> PI/4 */
    MPFR_CHANGE_SIGN (x);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "0.785375", 10, MPFR_RNDN) == 0);
    /* -INF +INF --> -PI/4 */
    MPFR_CHANGE_SIGN (y);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "-0.785375", 10, MPFR_RNDN) == 0);
    /* -INF -INF --> -3*PI/4 */
    MPFR_CHANGE_SIGN (x);
    mpfr_atan2 (z, y, x, MPFR_RNDN);
    MPFR_ASSERTN (mpfr_cmp_str (z, "-2.356194490192344928", 10, MPFR_RNDN) == 0);
    mpfr_set_prec (z, 905); /* exercises Ziv's loop */
    mpfr_atan2 (z, y, x, MPFR_RNDZ);
    MPFR_ASSERTN (mpfr_cmp_str (z, "-2.35619449019234492884698253745962716314787704953132936573120844423086230471465674897102611900658780098661106488496172998532038345716293667379401955609636083808771307702645389082916973346721171619778647332160823174945008459635673617534008737395340143185923642519259526145784", 10, MPFR_RNDN) == 0);

    mpfr_clears (x, y, z, (mpfr_ptr) 0);
}
Beispiel #12
0
static void
check_regression (void)
{
  mpfr_t x, y, z;
  int i;
  FILE *fp;
  char s[BUFSIZE];

  mpfr_inits2 (6177, x, y, z, (mpfr_ptr) 0);
  /* we read long strings from a file since ISO C90 does not support strings of
     length > 509 */
  fp = src_fopen ("tmul.dat", "r");
  if (fp == NULL)
    {
      fprintf (stderr, "Error, cannot open tmul.dat in srcdir\n");
      exit (1);
    }
  get_string (s, fp);
  mpfr_set_str (y, s, 16, MPFR_RNDN);
  get_string (s, fp);
  mpfr_set_str (z, s, 16, MPFR_RNDN);
  i = mpfr_mul (x, y, z, MPFR_RNDN);
  get_string (s, fp);
  if (mpfr_cmp_str (x, s, 16, MPFR_RNDN) != 0 || i != -1)
    {
      printf ("Regression test 1 failed (i=%d, expected -1)\nx=", i);
      mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
      exit (1);
    }
  fclose (fp);

  mpfr_set_prec (x, 606);
  mpfr_set_prec (y, 606);
  mpfr_set_prec (z, 606);

  mpfr_set_str (y, "-f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92daefc3f8052ca9f58736564d9e93e62d324@-1", 16, MPFR_RNDN);
  mpfr_set_str (z, "-f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92daefc3f8052ca9f58736564d9e93e62d324@-1", 16, MPFR_RNDN);
  i = mpfr_mul (x, y, z, MPFR_RNDU);
  mpfr_set_str (y, "f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff25b5df87f00a5953eb0e6cac9b3d27cc5a64c@-1", 16, MPFR_RNDN);
  if (mpfr_cmp (x, y) || i <= 0)
    {
      printf ("Regression test (2) failed! (i=%d - Expected 1)\n", i);
      mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
      exit (1);
    }

  mpfr_set_prec (x, 184);
  mpfr_set_prec (y, 92);
  mpfr_set_prec (z, 1023);

  mpfr_set_str (y, "6.9b8c8498882770d8038c3b0@-1", 16, MPFR_RNDN);
  mpfr_set_str (z, "7.44e24b986e7fb296f1e936ce749fec3504cbf0d5ba769466b1c9f1578115efd5d29b4c79271191a920a99280c714d3a657ad6e3afbab77ffce9d697e9bb9110e26d676069afcea8b69f1d1541f2365042d80a97c21dcccd8ace4f1bb58b49922003e738e6f37bb82ef653cb2e87f763974e6ae50ae54e7724c38b80653e3289@255", 16, MPFR_RNDN);
  i = mpfr_mul (x, y, z, MPFR_RNDU);
  mpfr_set_prec (y, 184);
  mpfr_set_str (y, "3.0080038f2ac5054e3e71ccbb95f76aaab2221715025a28@255",
                16, MPFR_RNDN);
  if (mpfr_cmp (x, y) || i <= 0)
    {
      printf ("Regression test (4) failed! (i=%d - expected 1)\n", i);
      printf ("Ref: 3.0080038f2ac5054e3e71ccbb95f76aaab2221715025a28@255\n"
              "Got: ");
      mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_set_prec (x, 908);
  mpfr_set_prec (y, 908);
  mpfr_set_prec (z, 908);
  mpfr_set_str (y, "-f.fffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"ffffffffffffffffffffffffffffffffffffffffffffffffffffff99be91f83ec6f0ed28a3d42"
"e6e9a327230345ea6@-1", 16, MPFR_RNDN);
  mpfr_set_str (z, "-f.fffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"ffffffffffffffffffffffffffffffffffffffffffffffffffffff99be91f83ec6f0ed28a3d42"
                "e6e9a327230345ea6@-1", 16, MPFR_RNDN);
  i = mpfr_mul (x, y, z, MPFR_RNDU);
  mpfr_set_str (y, "f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
"fffffffffffffffffffffffffffffffffffffffffffffffffffff337d23f07d8de1da5147a85c"
"dd3464e46068bd4d@-1", 16, MPFR_RNDN);
  if (mpfr_cmp (x, y) || i <= 0)
    {
      printf ("Regression test (5) failed! (i=%d - expected 1)\n", i);
      mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }


  mpfr_set_prec (x, 50);
  mpfr_set_prec (y, 40);
  mpfr_set_prec (z, 53);
  mpfr_set_str (y, "4.1ffffffff8", 16, MPFR_RNDN);
  mpfr_set_str (z, "4.2000000ffe0000@-4", 16, MPFR_RNDN);
  i = mpfr_mul (x, y, z, MPFR_RNDN);
  if (mpfr_cmp_str (x, "1.104000041d6c0@-3", 16, MPFR_RNDN) != 0
      || i <= 0)
    {
      printf ("Regression test (6) failed! (i=%d - expected 1)\nx=", i);
      mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
      printf ("\nMore prec=");
      mpfr_set_prec (x, 93);
      mpfr_mul (x, y, z, MPFR_RNDN);
      mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_set_prec (x, 439);
  mpfr_set_prec (y, 393);
  mpfr_set_str (y, "-1.921fb54442d18469898cc51701b839a252049c1114cf98e804177d"
                "4c76273644a29410f31c6809bbdf2a33679a748636600",
                16, MPFR_RNDN);
  i = mpfr_mul (x, y, y, MPFR_RNDU);
  if (mpfr_cmp_str (x, "2.77a79937c8bbcb495b89b36602306b1c2159a8ff834288a19a08"
    "84094f1cda3dc426da61174c4544a173de83c2500f8bfea2e0569e3698",
                    16, MPFR_RNDN) != 0
      || i <= 0)
    {
      printf ("Regression test (7) failed! (i=%d - expected 1)\nx=", i);
      mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_set_prec (x, 1023);
  mpfr_set_prec (y, 1023);
  mpfr_set_prec (z, 511);
  mpfr_set_ui (x, 17, MPFR_RNDN);
  mpfr_set_ui (y, 42, MPFR_RNDN);
  i = mpfr_mul (z, x, y, MPFR_RNDN);
  if (mpfr_cmp_ui (z, 17*42) != 0 || i != 0)
    {
      printf ("Regression test (8) failed! (i=%d - expected 0)\nz=", i);
      mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }

  mpfr_clears (x, y, z, (mpfr_ptr) 0);
}
Beispiel #13
0
Datei: texp.c Projekt: jozip/xcl
static void
underflow_up (int extended_emin)
{
    mpfr_t minpos, x, y, t, t2;
    int precx, precy;
    int inex;
    int rnd;
    int e3;
    int i, j;

    mpfr_init2 (minpos, 2);
    mpfr_set_ui (minpos, 0, MPFR_RNDN);
    mpfr_nextabove (minpos);

    /* Let's test values near the underflow boundary.
     *
     * Minimum representable positive number: minpos = 2^(emin - 1).
     * Let's choose an MPFR number x = log(minpos) + eps, with |eps| small
     * (note: eps cannot be 0, and cannot be a rational number either).
     * Then exp(x) = minpos * exp(eps) ~= minpos * (1 + eps + eps^2).
     * We will compute y = rnd(exp(x)) in some rounding mode, precision p.
     *   1. If eps > 0, then in any rounding mode:
     *        rnd(exp(x)) >= minpos and no underflow.
     *      So, let's take x1 = rndu(log(minpos)) in some precision.
     *   2. If eps < 0, then exp(x) < minpos and the result will be either 0
     *      or minpos. An underflow always occurs in MPFR_RNDZ and MPFR_RNDD,
     *      but not necessarily in MPFR_RNDN and MPFR_RNDU (this is underflow
     *      after rounding in an unbounded exponent range). If -a < eps < -b,
     *        minpos * (1 - a) < exp(x) < minpos * (1 - b + b^2).
     *      - If eps > -2^(-p), no underflow in MPFR_RNDU.
     *      - If eps > -2^(-p-1), no underflow in MPFR_RNDN.
     *      - If eps < - (2^(-p-1) + 2^(-2p-1)), underflow in MPFR_RNDN.
     *      - If eps < - (2^(-p) + 2^(-2p+1)), underflow in MPFR_RNDU.
     *      - In MPFR_RNDN, result is minpos iff exp(eps) > 1/2, i.e.
     *        - log(2) < eps < ...
     *
     * Moreover, since precy < MPFR_EXP_THRESHOLD (to avoid tests that take
     * too much time), mpfr_exp() always selects mpfr_exp_2(); so, we need
     * to test mpfr_exp_3() too. This will be done via the e3 variable:
     *   e3 = 0: mpfr_exp(), thus mpfr_exp_2().
     *   e3 = 1: mpfr_exp_3(), via the exp_3() wrapper.
     * i.e.: inex = e3 ? exp_3 (y, x, rnd) : mpfr_exp (y, x, rnd);
     */

    /* Case eps > 0. In revision 5461 (trunk) on a 64-bit Linux machine:
     *   Incorrect flags in underflow_up, eps > 0, MPFR_RNDN and extended emin
     *   for precx = 96, precy = 16, mpfr_exp_3
     *   Got 9 instead of 8.
     * Note: testing this case in several precisions for x and y introduces
     * some useful random. Indeed, the bug is not always triggered.
     * Fixed in r5469.
     */
    for (precx = 16; precx <= 128; precx += 16)
    {
        mpfr_init2 (x, precx);
        mpfr_log (x, minpos, MPFR_RNDU);
        for (precy = 16; precy <= 128; precy += 16)
        {
            mpfr_init2 (y, precy);

            for (e3 = 0; e3 <= 1; e3++)
            {
                RND_LOOP (rnd)
                {
                    int err = 0;

                    mpfr_clear_flags ();
                    inex = e3 ? exp_3 (y, x, (mpfr_rnd_t) rnd)
                           : mpfr_exp (y, x, (mpfr_rnd_t) rnd);
                    if (__gmpfr_flags != MPFR_FLAGS_INEXACT)
                    {
                        printf ("Incorrect flags in underflow_up, eps > 0, %s",
                                mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                        if (extended_emin)
                            printf (" and extended emin");
                        printf ("\nfor precx = %d, precy = %d, %s\n",
                                precx, precy, e3 ? "mpfr_exp_3" : "mpfr_exp");
                        printf ("Got %u instead of %u.\n", __gmpfr_flags,
                                (unsigned int) MPFR_FLAGS_INEXACT);
                        err = 1;
                    }
                    if (mpfr_cmp0 (y, minpos) < 0)
                    {
                        printf ("Incorrect result in underflow_up, eps > 0, %s",
                                mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                        if (extended_emin)
                            printf (" and extended emin");
                        printf ("\nfor precx = %d, precy = %d, %s\n",
                                precx, precy, e3 ? "mpfr_exp_3" : "mpfr_exp");
                        mpfr_dump (y);
                        err = 1;
                    }
                    MPFR_ASSERTN (inex != 0);
                    if (rnd == MPFR_RNDD || rnd == MPFR_RNDZ)
                        MPFR_ASSERTN (inex < 0);
                    if (rnd == MPFR_RNDU)
                        MPFR_ASSERTN (inex > 0);
                    if (err)
                        exit (1);
                }
            }

            mpfr_clear (y);
        }
        mpfr_clear (x);
    }

    /* Case - log(2) < eps < 0 in MPFR_RNDN, starting with small-precision x;
     * only check the result and the ternary value.
     * Previous to r5453 (trunk), on 32-bit and 64-bit machines, this fails
     * for precx = 65 and precy = 16, e.g.:
     *   exp_2.c:264:  assertion failed: ...
     * because mpfr_sub (r, x, r, MPFR_RNDU); yields a null value. This is
     * fixed in r5453 by going to next Ziv's iteration.
     */
    for (precx = sizeof(mpfr_exp_t) * CHAR_BIT + 1; precx <= 81; precx += 8)
    {
        mpfr_init2 (x, precx);
        mpfr_log (x, minpos, MPFR_RNDD);  /* |ulp| <= 1/2 */
        for (precy = 16; precy <= 128; precy += 16)
        {
            mpfr_init2 (y, precy);
            inex = mpfr_exp (y, x, MPFR_RNDN);
            if (inex <= 0 || mpfr_cmp0 (y, minpos) != 0)
            {
                printf ("Error in underflow_up, - log(2) < eps < 0");
                if (extended_emin)
                    printf (" and extended emin");
                printf (" for prec = %d\nExpected ", precy);
                mpfr_out_str (stdout, 16, 0, minpos, MPFR_RNDN);
                printf (" (minimum positive MPFR number) and inex > 0\nGot ");
                mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
                printf ("\nwith inex = %d\n", inex);
                exit (1);
            }
            mpfr_clear (y);
        }
        mpfr_clear (x);
    }

    /* Cases eps ~ -2^(-p) and eps ~ -2^(-p-1). More precisely,
     *   _ for j = 0, eps > -2^(-(p+i)),
     *   _ for j = 1, eps < - (2^(-(p+i)) + 2^(1-2(p+i))),
     * where i = 0 or 1.
     */
    mpfr_inits2 (2, t, t2, (mpfr_ptr) 0);
    for (precy = 16; precy <= 128; precy += 16)
    {
        mpfr_set_ui_2exp (t, 1, - precy, MPFR_RNDN);         /* 2^(-p) */
        mpfr_set_ui_2exp (t2, 1, 1 - 2 * precy, MPFR_RNDN);  /* 2^(-2p+1) */
        precx = sizeof(mpfr_exp_t) * CHAR_BIT + 2 * precy + 8;
        mpfr_init2 (x, precx);
        mpfr_init2 (y, precy);
        for (i = 0; i <= 1; i++)
        {
            for (j = 0; j <= 1; j++)
            {
                if (j == 0)
                {
                    /* Case eps > -2^(-(p+i)). */
                    mpfr_log (x, minpos, MPFR_RNDU);
                }
                else  /* j == 1 */
                {
                    /* Case eps < - (2^(-(p+i)) + 2^(1-2(p+i))). */
                    mpfr_log (x, minpos, MPFR_RNDD);
                    inex = mpfr_sub (x, x, t2, MPFR_RNDN);
                    MPFR_ASSERTN (inex == 0);
                }
                inex = mpfr_sub (x, x, t, MPFR_RNDN);
                MPFR_ASSERTN (inex == 0);

                RND_LOOP (rnd)
                for (e3 = 0; e3 <= 1; e3++)
                {
                    int err = 0;
                    unsigned int flags;

                    flags = MPFR_FLAGS_INEXACT |
                            (((rnd == MPFR_RNDU || rnd == MPFR_RNDA)
                              && (i == 1 || j == 0)) ||
                             (rnd == MPFR_RNDN && (i == 1 && j == 0)) ?
                             0 : MPFR_FLAGS_UNDERFLOW);
                    mpfr_clear_flags ();
                    inex = e3 ? exp_3 (y, x, (mpfr_rnd_t) rnd)
                           : mpfr_exp (y, x, (mpfr_rnd_t) rnd);
                    if (__gmpfr_flags != flags)
                    {
                        printf ("Incorrect flags in underflow_up, %s",
                                mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                        if (extended_emin)
                            printf (" and extended emin");
                        printf ("\nfor precx = %d, precy = %d, ",
                                precx, precy);
                        if (j == 0)
                            printf ("eps >~ -2^(-%d)", precy + i);
                        else
                            printf ("eps <~ - (2^(-%d) + 2^(%d))",
                                    precy + i, 1 - 2 * (precy + i));
                        printf (", %s\n", e3 ? "mpfr_exp_3" : "mpfr_exp");
                        printf ("Got %u instead of %u.\n",
                                __gmpfr_flags, flags);
                        err = 1;
                    }
                    if (rnd == MPFR_RNDU || rnd == MPFR_RNDA || rnd == MPFR_RNDN ?
                            mpfr_cmp0 (y, minpos) != 0 : MPFR_NOTZERO (y))
                    {
                        printf ("Incorrect result in underflow_up, %s",
                                mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                        if (extended_emin)
                            printf (" and extended emin");
                        printf ("\nfor precx = %d, precy = %d, ",
                                precx, precy);
                        if (j == 0)
                            printf ("eps >~ -2^(-%d)", precy + i);
                        else
                            printf ("eps <~ - (2^(-%d) + 2^(%d))",
                                    precy + i, 1 - 2 * (precy + i));
                        printf (", %s\n", e3 ? "mpfr_exp_3" : "mpfr_exp");
                        mpfr_dump (y);
                        err = 1;
                    }
                    if (err)
                        exit (1);
                }  /* for (e3 ...) */
            }  /* for (j ...) */
            mpfr_div_2si (t, t, 1, MPFR_RNDN);
            mpfr_div_2si (t2, t2, 2, MPFR_RNDN);
        }  /* for (i ...) */
        mpfr_clears (x, y, (mpfr_ptr) 0);
    }  /* for (precy ...) */
    mpfr_clears (t, t2, (mpfr_ptr) 0);

    /* Case exp(eps) ~= 1/2, i.e. eps ~= - log(2).
     * We choose x0 and x1 with high enough precision such that:
     *   x0 = rndd(rndd(log(minpos)) - rndu(log(2)))
     *   x1 = rndu(rndu(log(minpos)) - rndd(log(2)))
     * In revision 5507 (trunk) on a 64-bit Linux machine, this fails:
     *   Error in underflow_up, eps >~ - log(2) and extended emin
     *   for precy = 16, mpfr_exp
     *   Expected 1.0@-1152921504606846976 (minimum positive MPFR number),
     *   inex > 0 and flags = 9
     *   Got 0
     *   with inex = -1 and flags = 9
     * due to a double-rounding problem in mpfr_mul_2si when rescaling
     * the result.
     */
    mpfr_inits2 (sizeof(mpfr_exp_t) * CHAR_BIT + 64, x, t, (mpfr_ptr) 0);
    for (i = 0; i <= 1; i++)
    {
        mpfr_log (x, minpos, i ? MPFR_RNDU : MPFR_RNDD);
        mpfr_const_log2 (t, i ? MPFR_RNDD : MPFR_RNDU);
        mpfr_sub (x, x, t, i ? MPFR_RNDU : MPFR_RNDD);
        for (precy = 16; precy <= 128; precy += 16)
        {
            mpfr_init2 (y, precy);
            for (e3 = 0; e3 <= 1; e3++)
            {
                unsigned int flags, uflags =
                    MPFR_FLAGS_INEXACT | MPFR_FLAGS_UNDERFLOW;

                mpfr_clear_flags ();
                inex = e3 ? exp_3 (y, x, MPFR_RNDN) : mpfr_exp (y, x, MPFR_RNDN);
                flags = __gmpfr_flags;
                if (flags != uflags ||
                        (i ? (inex <= 0 || mpfr_cmp0 (y, minpos) != 0)
                         : (inex >= 0 || MPFR_NOTZERO (y))))
                {
                    printf ("Error in underflow_up, eps %c~ - log(2)",
                            i ? '>' : '<');
                    if (extended_emin)
                        printf (" and extended emin");
                    printf ("\nfor precy = %d, %s\nExpected ", precy,
                            e3 ? "mpfr_exp_3" : "mpfr_exp");
                    if (i)
                    {
                        mpfr_out_str (stdout, 16, 0, minpos, MPFR_RNDN);
                        printf (" (minimum positive MPFR number),\ninex >");
                    }
                    else
                    {
                        printf ("+0, inex <");
                    }
                    printf (" 0 and flags = %u\nGot ", uflags);
                    mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
                    printf ("\nwith inex = %d and flags = %u\n", inex, flags);
                    exit (1);
                }
            }
            mpfr_clear (y);
        }
    }
    mpfr_clears (x, t, (mpfr_ptr) 0);

    mpfr_clear (minpos);
}
Beispiel #14
0
static void
test_underflow1 (void)
{
  mpfr_t x, y, z, r;
  int inex, signy, signz, rnd, err = 0;

  mpfr_inits2 (8, x, y, z, r, (void *) 0);

  MPFR_SET_POS (x);
  mpfr_setmin (x, mpfr_get_emin ());  /* x = 0.1@emin */

  for (signy = -1; signy <= 1; signy += 2)
    {
      mpfr_set_si_2exp (y, signy, -1, GMP_RNDN);  /* |y| = 1/2 */
      for (signz = -3; signz <= 3; signz += 2)
        {
          RND_LOOP (rnd)
            {
              mpfr_set_si (z, signz, GMP_RNDN);
              if (ABS (signz) != 1)
                mpfr_setmax (z, mpfr_get_emax ());
              /* |z| = 1 or 2^emax - ulp */
              mpfr_clear_flags ();
              inex = mpfr_fma (r, x, y, z, rnd);
#define ERRTU1 "Error in test_underflow1 (signy = %d, signz = %d, %s)\n  "
              if (mpfr_nanflag_p ())
                {
                  printf (ERRTU1 "NaN flag is set\n", signy, signz,
                          mpfr_print_rnd_mode (rnd));
                  err = 1;
                }
              if (signy < 0 && (rnd == GMP_RNDD ||
                                (rnd == GMP_RNDZ && signz > 0)))
                mpfr_nextbelow (z);
              if (signy > 0 && (rnd == GMP_RNDU ||
                                (rnd == GMP_RNDZ && signz < 0)))
                mpfr_nextabove (z);
              if ((mpfr_overflow_p () != 0) ^ (mpfr_inf_p (z) != 0))
                {
                  printf (ERRTU1 "wrong overflow flag\n", signy, signz,
                          mpfr_print_rnd_mode (rnd));
                  err = 1;
                }
              if (mpfr_underflow_p ())
                {
                  printf (ERRTU1 "underflow flag is set\n", signy, signz,
                          mpfr_print_rnd_mode (rnd));
                  err = 1;
                }
              if (! mpfr_equal_p (r, z))
                {
                  printf (ERRTU1 "got ", signy, signz,
                          mpfr_print_rnd_mode (rnd));
                  mpfr_print_binary (r);
                  printf (" instead of ");
                  mpfr_print_binary (z);
                  printf ("\n");
                  err = 1;
                }
              if (inex >= 0 && (rnd == GMP_RNDD ||
                                (rnd == GMP_RNDZ && signz > 0) ||
                                (rnd == GMP_RNDN && signy > 0)))
                {
                  printf (ERRTU1 "ternary value = %d instead of < 0\n",
                          signy, signz, mpfr_print_rnd_mode (rnd), inex);
                  err = 1;
                }
              if (inex <= 0 && (rnd == GMP_RNDU ||
                                (rnd == GMP_RNDZ && signz < 0) ||
                                (rnd == GMP_RNDN && signy < 0)))
                {
                  printf (ERRTU1 "ternary value = %d instead of > 0\n",
                          signy, signz, mpfr_print_rnd_mode (rnd), inex);
                  err = 1;
                }
            }
        }
    }

  if (err)
    exit (1);
  mpfr_clears (x, y, z, r, (void *) 0);
}
Beispiel #15
0
static void
check_cmp (int argc, char *argv[])
{
  mpfr_t x, y;
  int n, k;

  mpfr_inits2 (53, x, y, (mpfr_ptr) 0);

  mpfr_set_ui(x, 1, MPFR_RNDN);
  (mpfr_abs) (x, x, MPFR_RNDN);
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("Error in mpfr_abs(1.0)\n");
      exit (1);
    }

  mpfr_set_si(x, -1, MPFR_RNDN);
  mpfr_abs(x, x, MPFR_RNDN);
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("Error in mpfr_abs(1.0)\n");
      exit (1);
    }

  mpfr_set_si(x, -1, MPFR_RNDN);
  mpfr_abs(x, x, MPFR_RNDN);
  if (mpfr_cmp_ui (x, 1))
    {
      printf ("Error in mpfr_abs(-1.0)\n");
      exit (1);
    }

  mpfr_set_inf (x, 1);
  mpfr_abs (x, x, MPFR_RNDN);
  if (!mpfr_inf_p(x) || (mpfr_sgn(x) <= 0))
    {
      printf ("Error in mpfr_abs(Inf).\n");
      exit (1);
    }
  mpfr_set_inf (x, -1);
  mpfr_abs (x, x, MPFR_RNDN);
  if (!mpfr_inf_p(x) || (mpfr_sgn(x) <= 0))
    {
      printf ("Error in mpfr_abs(-Inf).\n");
      exit (1);
    }

  MPFR_SET_NAN(x);
  mpfr_abs (x, x, MPFR_RNDN);
  if (!MPFR_IS_NAN(x))
    {
      printf ("Error in mpfr_abs(NAN).\n");
      exit (1);
    }

  n = (argc==1) ? 25000 : atoi(argv[1]);
  for (k = 1; k <= n; k++)
    {
      mpfr_rnd_t rnd;
      int sign = SIGN_RAND ();

      mpfr_urandomb (x, RANDS);
      MPFR_SET_SIGN (x, sign);
      rnd = RND_RAND ();
      mpfr_abs (y, x, rnd);
      MPFR_SET_POS (x);
      if (mpfr_cmp (x, y))
        {
          printf ("Mismatch for sign=%d and x=", sign);
          mpfr_print_binary (x);
          printf ("\nResults=");
          mpfr_print_binary (y);
          putchar ('\n');
          exit (1);
        }
    }

  mpfr_clears (x, y, (mpfr_ptr) 0);
}
Beispiel #16
0
Datei: tagm.c Projekt: Canar/mpfr
static void
check4 (const char *as, const char *bs, mpfr_rnd_t rnd_mode,
        const char *res, int inex)
{
  mpfr_t ta, tb, tc, tres;
  mpfr_exp_t emin, emax;
  int i;

  emin = mpfr_get_emin ();
  emax = mpfr_get_emax ();

  mpfr_inits2 (53, ta, tb, tc, tres, (mpfr_ptr) 0);

  for (i = 0; i <= 2; i++)
    {
      unsigned int expflags, newflags;
      int inex2;

      mpfr_set_str1 (ta, as);
      mpfr_set_str1 (tb, bs);
      mpfr_set_str1 (tc, res);

      if (i > 0)
        {
          mpfr_exp_t ea, eb, ec, e0;

          set_emin (MPFR_EMIN_MIN);
          set_emax (MPFR_EMAX_MAX);

          ea = mpfr_get_exp (ta);
          eb = mpfr_get_exp (tb);
          ec = mpfr_get_exp (tc);

          e0 = i == 1 ? __gmpfr_emin : __gmpfr_emax;
          if ((i == 1 && ea < eb) || (i == 2 && ea > eb))
            {
              mpfr_set_exp (ta, e0);
              mpfr_set_exp (tb, e0 + (eb - ea));
              mpfr_set_exp (tc, e0 + (ec - ea));
            }
          else
            {
              mpfr_set_exp (ta, e0 + (ea - eb));
              mpfr_set_exp (tb, e0);
              mpfr_set_exp (tc, e0 + (ec - eb));
            }
        }

      __gmpfr_flags = expflags =
        (randlimb () & 1) ? MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE : 0;
      inex2 = mpfr_agm (tres, ta, tb, rnd_mode);
      newflags = __gmpfr_flags;
      expflags |= MPFR_FLAGS_INEXACT;

      if (SIGN (inex2) != inex || newflags != expflags ||
          ! mpfr_equal_p (tres, tc))
        {
          printf ("mpfr_agm failed in rnd_mode=%s for\n",
                  mpfr_print_rnd_mode (rnd_mode));
          printf ("  a = ");
          mpfr_out_str (stdout, 10, 0, ta, MPFR_RNDN);
          printf ("\n");
          printf ("  b = ");
          mpfr_out_str (stdout, 10, 0, tb, MPFR_RNDN);
          printf ("\n");
          printf ("expected inex = %d, flags = %u,\n"
                  "         ", inex, expflags);
          mpfr_dump (tc);
          printf ("got      inex = %d, flags = %u,\n"
                  "         ", inex2, newflags);
          mpfr_dump (tres);
          exit (1);
        }

      set_emin (emin);
      set_emax (emax);
    }

  mpfr_clears (ta, tb, tc, tres, (mpfr_ptr) 0);
}
int
main (int argc, char *argv[])
{
  mpfr_t w,z;
  unsigned long k;
  int i;

  tests_start_mpfr ();

  mpfr_inits2 (53, w, z, (mpfr_ptr) 0);

  for (i = 0; i < 3; i++)
    {
      mpfr_set_inf (w, 1);
      test_mul (i, 0, w, w, 10, MPFR_RNDZ);
      if (!MPFR_IS_INF(w))
        {
          printf ("Result is not Inf (i = %d)\n", i);
          exit (1);
        }

      mpfr_set_nan (w);
      test_mul (i, 0, w, w, 10, MPFR_RNDZ);
      if (!MPFR_IS_NAN(w))
        {
          printf ("Result is not NaN (i = %d)\n", i);
          exit (1);
        }

      for (k = 0 ; k < numberof(val) ; k+=3)
        {
          mpfr_set_str (w, val[k], 16, MPFR_RNDN);
          test_mul (i, 0, z, w, 10, MPFR_RNDZ);
          if (mpfr_cmp_str (z, val[k+1], 16, MPFR_RNDN))
            {
              printf ("ERROR for x * 2^n (i = %d) for %s\n", i, val[k]);
              printf ("Expected: %s\n"
                      "Got     : ", val[k+1]);
              mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
              putchar ('\n');
              exit (1);
            }
          test_mul (i, 1, z, w, 10, MPFR_RNDZ);
          if (mpfr_cmp_str (z, val[k+2], 16, MPFR_RNDN))
            {
              printf ("ERROR for x / 2^n (i = %d) for %s\n", i, val[k]);
              printf ("Expected: %s\n"
                      "Got     : ", val[k+2]);
              mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
              putchar ('\n');
              exit (1);
            }
        }

      mpfr_set_inf (w, 1);
      mpfr_nextbelow (w);
      test_mul (i, 0, w, w, 1, MPFR_RNDN);
      if (!mpfr_inf_p (w))
        {
          printf ("Overflow error (i = %d)!\n", i);
          exit (1);
        }
      mpfr_set_ui (w, 0, MPFR_RNDN);
      mpfr_nextabove (w);
      test_mul (i, 1, w, w, 1, MPFR_RNDN);
      if (mpfr_cmp_ui (w, 0))
        {
          printf ("Underflow error (i = %d)!\n", i);
          exit (1);
        }
    }

  if (MPFR_EXP_MAX >= LONG_MAX/2 && MPFR_EXP_MIN <= LONG_MAX/2-LONG_MAX-1)
    {
      unsigned long lmp1 = (unsigned long) LONG_MAX + 1;

      mpfr_set_ui (w, 1, MPFR_RNDN);
      mpfr_mul_2ui (w, w, LONG_MAX/2, MPFR_RNDZ);
      mpfr_div_2ui (w, w, lmp1, MPFR_RNDZ);
      mpfr_mul_2ui (w, w, lmp1 - LONG_MAX/2, MPFR_RNDZ);
      if (!mpfr_cmp_ui (w, 1))
        {
          printf ("Underflow LONG_MAX error!\n");
          exit (1);
        }
    }

  mpfr_clears (w, z, (mpfr_ptr) 0);

  underflow0 ();
  large0 ();

  tests_end_mpfr ();
  return 0;
}
Beispiel #18
0
static void
bug_mul_div_q_20100818 (void)
{
  mpq_t qa, qb;
  mpfr_t x1, x2, y1, y2, y3;
  mpfr_exp_t emin, emax, e;
  int inex;
  int rnd;

  emin = mpfr_get_emin ();
  emax = mpfr_get_emax ();
  set_emin (MPFR_EMIN_MIN);
  set_emax (MPFR_EMAX_MAX);

  mpq_init (qa);
  mpq_init (qb);
  mpfr_inits2 (32, x1, x2, y1, y2, y3, (mpfr_ptr) 0);

  mpq_set_ui (qa, 3, 17);
  mpq_set_ui (qb, 17, 3);
  inex = mpfr_set_ui (x1, 7, MPFR_RNDN);
  MPFR_ASSERTN (inex == 0);

  e = MPFR_EMAX_MAX - 3;
  inex = mpfr_set_ui_2exp (x2, 7, e, MPFR_RNDN);  /* x2 = x1 * 2^e */
  MPFR_ASSERTN (inex == 0);

  RND_LOOP(rnd)
    {
      mpfr_mul_q (y1, x1, qa, (mpfr_rnd_t) rnd);
      mpfr_div_q (y3, x1, qb, (mpfr_rnd_t) rnd);
      MPFR_ASSERTN (mpfr_equal_p (y1, y3));
      inex = mpfr_set_ui_2exp (y3, 1, e, MPFR_RNDN);
      MPFR_ASSERTN (inex == 0);
      inex = mpfr_mul (y3, y3, y1, MPFR_RNDN);  /* y3 = y1 * 2^e */
      MPFR_ASSERTN (inex == 0);
      mpfr_mul_q (y2, x2, qa, (mpfr_rnd_t) rnd);
      if (! mpfr_equal_p (y2, y3))
        {
          printf ("Error 1 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
          printf ("Expected "); mpfr_dump (y3);
          printf ("Got      "); mpfr_dump (y2);
          exit (1);
        }
      mpfr_div_q (y2, x2, qb, (mpfr_rnd_t) rnd);
      if (! mpfr_equal_p (y2, y3))
        {
          printf ("Error 2 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
          printf ("Expected "); mpfr_dump (y3);
          printf ("Got      "); mpfr_dump (y2);
          exit (1);
        }
    }

  e = MPFR_EMIN_MIN;
  inex = mpfr_set_ui_2exp (x2, 7, e, MPFR_RNDN);  /* x2 = x1 * 2^e */
  MPFR_ASSERTN (inex == 0);

  RND_LOOP(rnd)
    {
      mpfr_div_q (y1, x1, qa, (mpfr_rnd_t) rnd);
      mpfr_mul_q (y3, x1, qb, (mpfr_rnd_t) rnd);
      MPFR_ASSERTN (mpfr_equal_p (y1, y3));
      inex = mpfr_set_ui_2exp (y3, 1, e, MPFR_RNDN);
      MPFR_ASSERTN (inex == 0);
      inex = mpfr_mul (y3, y3, y1, MPFR_RNDN);  /* y3 = y1 * 2^e */
      MPFR_ASSERTN (inex == 0);
      mpfr_div_q (y2, x2, qa, (mpfr_rnd_t) rnd);
      if (! mpfr_equal_p (y2, y3))
        {
          printf ("Error 3 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
          printf ("Expected "); mpfr_dump (y3);
          printf ("Got      "); mpfr_dump (y2);
          exit (1);
        }
      mpfr_mul_q (y2, x2, qb, (mpfr_rnd_t) rnd);
      if (! mpfr_equal_p (y2, y3))
        {
          printf ("Error 4 in bug_mul_div_q_20100818 (rnd = %d)\n", rnd);
          printf ("Expected "); mpfr_dump (y3);
          printf ("Got      "); mpfr_dump (y2);
          exit (1);
        }
    }

  mpq_clear (qa);
  mpq_clear (qb);
  mpfr_clears (x1, x2, y1, y2, y3, (mpfr_ptr) 0);

  set_emin (emin);
  set_emax (emax);
}
Beispiel #19
0
static void
test_special2z (int (*mpfr_func)(mpfr_ptr, mpz_srcptr, mpfr_srcptr, mpfr_rnd_t),
               void (*mpz_func)(mpz_ptr, mpz_srcptr, mpz_srcptr),
               const char *op)
{
  mpfr_t x1, x2;
  mpz_t  z1, z2;
  int res;

  mpfr_inits2 (128, x1, x2, (mpfr_ptr) 0);
  mpz_init (z1); mpz_init(z2);
  mpz_fac_ui (z1, 19); /* 19!+1 fits perfectly in a 128 bits mantissa */
  mpz_add_ui (z1, z1, 1);
  mpz_fac_ui (z2, 20); /* 20!+1 fits perfectly in a 128 bits mantissa */
  mpz_add_ui (z2, z2, 1);

  res = mpfr_set_z(x1, z1, MPFR_RNDN);
  if (res)
    {
      printf("Special2z %s: set_z1 error\n", op);
      exit(1);
    }
  mpfr_set_z (x2, z2, MPFR_RNDN);
  if (res)
    {
      printf("Special2z %s: set_z2 error\n", op);
      exit(1);
    }

  /* (19!+1) * (20!+1) fits in a 128 bits number */
  res = mpfr_func(x1, z1, x2, MPFR_RNDN);
  if (res)
    {
      printf("Special2z %s: wrong inexact flag.\n", op);
      exit(1);
    }
  mpz_func(z1, z1, z2);
  res = mpfr_set_z (x2, z1, MPFR_RNDN);
  if (res)
    {
      printf("Special2z %s: set_z2 error\n", op);
      exit(1);
    }
  if (mpfr_cmp(x1, x2))
    {
      printf("Special2z %s: results differ.\nx1=", op);
      mpfr_print_binary(x1);
      printf("\nx2=");
      mpfr_print_binary(x2);
      printf ("\nZ2=");
      mpz_out_str (stdout, 2, z1);
      putchar('\n');
      exit(1);
    }

  mpz_set_ui (z1, 0);
  mpz_set_ui (z2, 1);
  mpfr_set_ui (x2, 1, MPFR_RNDN);
  res = mpfr_func(x1, z1, x2, MPFR_RNDN);
  mpz_func (z1, z1, z2);
  mpfr_set_z (x2, z1, MPFR_RNDN);
  if (mpfr_cmp(x1, x2))
    {
      printf("Special2z %s: results differ(2).\nx1=", op);
      mpfr_print_binary(x1);
      printf("\nx2=");
      mpfr_print_binary(x2);
      putchar('\n');
      exit(1);
    }

  mpz_clear (z1); mpz_clear(z2);
  mpfr_clears (x1, x2, (mpfr_ptr) 0);
}
Beispiel #20
0
static void
addsubq_overflow_aux (mpfr_exp_t e)
{
  mpfr_t x, y;
  mpq_t q;
  mpfr_exp_t emax;
  int inex;
  int rnd;
  int sign, sub;

  MPFR_ASSERTN (e <= LONG_MAX);
  emax = mpfr_get_emax ();
  set_emax (e);
  mpfr_inits2 (16, x, y, (mpfr_ptr) 0);
  mpq_init (q);

  mpfr_set_inf (x, 1);
  mpfr_nextbelow (x);
  mpq_set_ui (q, 1, 1);

  for (sign = 0; sign <= 1; sign++)
    {
      for (sub = 0; sub <= 1; sub++)
        {
          RND_LOOP(rnd)
            {
              unsigned int flags, ex_flags;
              int inf;

              inf = rnd == MPFR_RNDA ||
                    rnd == (sign ? MPFR_RNDD : MPFR_RNDU);
              ex_flags = MPFR_FLAGS_INEXACT | (inf ? MPFR_FLAGS_OVERFLOW : 0);
              mpfr_clear_flags ();
              inex = sub ?
                mpfr_sub_q (y, x, q, (mpfr_rnd_t) rnd) :
                mpfr_add_q (y, x, q, (mpfr_rnd_t) rnd);
              flags = __gmpfr_flags;
              if (inex == 0 || flags != ex_flags ||
                  (inf ? ! mpfr_inf_p (y) : ! mpfr_equal_p (x, y)))
                {
                  printf ("Error in addsubq_overflow_aux(%ld),"
                          " sign = %d, %s\n", (long) e, sign,
                          mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                  printf ("Got inex = %d, y = ", inex);
                  mpfr_dump (y);
                  printf ("Expected flags:");
                  flags_out (ex_flags);
                  printf ("Got flags:     ");
                  flags_out (flags);
                  exit (1);
                }
            }
          mpq_neg (q, q);
        }
      mpfr_neg (x, x, MPFR_RNDN);
      mpq_neg (q, q);
    }

  mpq_clear (q);
  mpfr_clears (x, y, (mpfr_ptr) 0);
  set_emax (emax);
}
Beispiel #21
0
static void
consistency (void)
{
  mpfr_t x, s1, s2, c1, c2;
  mpfr_exp_t emin, emax;
  mpfr_rnd_t rnd;
  unsigned int flags_sin, flags_cos, flags, flags_before, flags_ref;
  int inex_sin, is, inex_cos, ic, inex, inex_ref;
  int i;

  emin = mpfr_get_emin ();
  emax = mpfr_get_emax ();

  for (i = 0; i <= 10000; i++)
    {
      mpfr_init2 (x, MPFR_PREC_MIN + (randlimb () % 8));
      mpfr_inits2 (MPFR_PREC_MIN + (randlimb () % 8), s1, s2, c1, c2,
                   (mpfr_ptr) 0);
      if (i < 8 * MPFR_RND_MAX)
        {
          int j = i / MPFR_RND_MAX;
          if (j & 1)
            mpfr_set_emin (MPFR_EMIN_MIN);
          mpfr_set_si (x, (j & 2) ? 1 : -1, MPFR_RNDN);
          mpfr_set_exp (x, mpfr_get_emin ());
          rnd = (mpfr_rnd_t) (i % MPFR_RND_MAX);
          flags_before = 0;
          if (j & 4)
            mpfr_set_emax (-17);
        }
      else
        {
          tests_default_random (x, 256, -5, 50, 0);
          rnd = RND_RAND ();
          flags_before = (randlimb () & 1) ?
            (unsigned int) (MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE) :
            (unsigned int) 0;
        }
      __gmpfr_flags = flags_before;
      inex_sin = mpfr_sin (s1, x, rnd);
      is = inex_sin < 0 ? 2 : inex_sin > 0 ? 1 : 0;
      flags_sin = __gmpfr_flags;
      __gmpfr_flags = flags_before;
      inex_cos = mpfr_cos (c1, x, rnd);
      ic = inex_cos < 0 ? 2 : inex_cos > 0 ? 1 : 0;
      flags_cos = __gmpfr_flags;
      __gmpfr_flags = flags_before;
      inex = mpfr_sin_cos (s2, c2, x, rnd);
      flags = __gmpfr_flags;
      inex_ref = is + 4 * ic;
      flags_ref = flags_sin | flags_cos;
      if (!(mpfr_equal_p (s1, s2) && mpfr_equal_p (c1, c2)) ||
          inex != inex_ref || flags != flags_ref)
        {
          printf ("mpfr_sin_cos and mpfr_sin/mpfr_cos disagree on %s,"
                  " i = %d\nx = ", mpfr_print_rnd_mode (rnd), i);
          mpfr_dump (x);
          printf ("s1 = ");
          mpfr_dump (s1);
          printf ("s2 = ");
          mpfr_dump (s2);
          printf ("c1 = ");
          mpfr_dump (c1);
          printf ("c2 = ");
          mpfr_dump (c2);
          printf ("inex_sin = %d (s = %d), inex_cos = %d (c = %d), "
                  "inex = %d (expected %d)\n",
                  inex_sin, is, inex_cos, ic, inex, inex_ref);
          printf ("flags_sin = 0x%x, flags_cos = 0x%x, "
                  "flags = 0x%x (expected 0x%x)\n",
                  flags_sin, flags_cos, flags, flags_ref);
          exit (1);
        }
      mpfr_clears (x, s1, s2, c1, c2, (mpfr_ptr) 0);
      mpfr_set_emin (emin);
      mpfr_set_emax (emax);
    }
}
Beispiel #22
0
static int
binary (void)
{
    mpfr_t x;
    mpfr_t z;
    mpfr_inits2 (64, x, z, (mpfr_ptr) 0);

    /* special */
    mpfr_set_inf (x, 1);
    check_sprintf (pinf_str, "%Rb", x);

    mpfr_set_inf (x, -1);
    check_sprintf (minf_str, "%Rb", x);

    mpfr_set_nan (x);
    check_sprintf (nan_str, "%Rb", x);

    /* regular numbers */
    mpfr_set_str (x, "1110010101.1001101", 2, MPFR_RNDN);
    mpfr_set_ui (z, 0, MPFR_RNDN);

    /* simplest case: right justified */
    check_sprintf ("    1.1100101011001101p+9", "%25Rb", x);
    check_sprintf ("                     0p+0", "%25Rb", z);
    /* sign or space, pad with leading zeros */
    check_sprintf (" 0001.1100101011001101p+9", "% 025Rb", x);
    check_sprintf (" 000000000000000000000p+0", "% 025Rb", z);
    /* sign + or -, left justified */
    check_sprintf ("+1.1100101011001101p+9   ", "%+-25Rb", x);
    check_sprintf ("+0p+0                    ", "%+-25Rb", z);
    /* sign or space */
    check_sprintf (" 1.110p+9",  "% .3RNb", x);
    check_sprintf (" 1.1101p+9", "% .4RNb", x);
    check_sprintf (" 0.0000p+0", "% .4RNb", z);
    /* sign + or -, decimal point, pad with leading zeros */
    check_sprintf ("+00001.1p+9", "%0+#11.1RZb", x);
    check_sprintf ("+0001.0p+10", "%0+#11.1RNb", x);
    check_sprintf ("+000000.p+0", "%0+#11.0RNb", z);
    /* pad with leading zero */
    check_sprintf ("00001.1100101011001101p+9", "%025RDb", x);
    /* sign or space, decimal point (unused), left justified */
    check_sprintf (" 1.1p+9    ", "%- #11.1RDb", x);
    check_sprintf (" 1.p+9     ", "%- #11.0RDb", x);
    check_sprintf (" 1.p+10    ", "%- #11.0RUb", x);
    check_sprintf (" 1.p+9     ", "%- #11.0RZb", x);
    check_sprintf (" 1.p+10    ", "%- #11.0RYb", x);
    check_sprintf (" 1.p+10    ", "%- #11.0RNb", x);

    mpfr_mul_si (x, x, -1, MPFR_RNDD);
    mpfr_mul_si (z, z, -1, MPFR_RNDD);

    /* sign + or - */
    check_sprintf ("   -1.1p+9", "%+10.1RUb", x);
    check_sprintf ("   -0.0p+0", "%+10.1RUb", z);

    /* precision 0 */
    check_sprintf ("-1p+10", "%.0RNb", x);
    check_sprintf ("-1p+10", "%.0RDb", x);
    check_sprintf ("-1p+9",  "%.0RUb", x);
    check_sprintf ("-1p+9",  "%.0RZb", x);
    check_sprintf ("-1p+10", "%.0RYb", x);
    /* round to next base power */
    check_sprintf ("-1.0p+10", "%.1RNb", x);
    check_sprintf ("-1.0p+10", "%.1RDb", x);
    check_sprintf ("-1.0p+10", "%.1RYb", x);
    /* do not round to next base power */
    check_sprintf ("-1.1p+9", "%.1RUb", x);
    check_sprintf ("-1.1p+9", "%.1RZb", x);
    /* rounding bit is zero */
    check_sprintf ("-1.11p+9", "%.2RNb", x);
    /* tie case in round to nearest mode */
    check_sprintf ("-1.1100101011001101p+9", "%.16RNb", x);
    /* trailing zeros in fractional part */
    check_sprintf ("-1.110010101100110100000000000000p+9", "%.30RNb", x);

    mpfr_clears (x, z, (mpfr_ptr) 0);
    return 0;
}
Beispiel #23
0
	void FixComplexKCM::init()
	{
		if(lsb_in>msb_in) 
		{
			throw string("FixComplexKCM: Error, lsbIn>msbIn");
		}

		// definition of the source file name, used for info and error reporting
		// using REPORT 
		srcFileName="FixComplexKCM";

		// definition of the name of the operator
		ostringstream name;
		name << "FixComplexKCM_" << vhdlize(msb_in) <<"_" << vhdlize(lsb_in) 
			<< "_" << vhdlize(lsb_out) << "_" << vhdlize(constant_re) << "_" <<
			vhdlize(constant_im) << "_" << ((signedInput) ? "" : "un") <<
			"signed" ;

		setName(name.str());
		
		// Copyright 
		setCopyrightString("3IF 2015 dev team (2015)");

		input_width = 1 + msb_in - lsb_in;
		
		// declaring inputs
		addInput ("ReIN" , input_width);
		addInput ("ImIN" , input_width);

		//Computing constants for testBench and in order to know constant width
		sollya_obj_t nodeIm, nodeRe;	
		nodeRe = sollya_lib_parse_string(constant_re.c_str());
		
		if(sollya_lib_obj_is_error(nodeRe))
		{
			ostringstream error;
			error << srcFileName <<" : Unable to parse string \""  <<
				constant_re << "\" as a numeric constant" << endl;
			throw error.str();
		}
		
		nodeIm = sollya_lib_parse_string(constant_im.c_str());
		if(sollya_lib_obj_is_error(nodeIm))
		{
			ostringstream error;
			error << srcFileName <<" : Unable to parse string \""  <<
				constant_im << "\" as a numeric constant" << endl;
			throw error.str();
		}

		mpfr_inits2(10000, mpfr_constant_re, mpfr_constant_im, NULL);

		sollya_lib_get_constant(mpfr_constant_re, nodeRe);
		sollya_lib_get_constant(mpfr_constant_im, nodeIm);

		constantReNeg = (mpfr_sgn(mpfr_constant_re) < 0);
		constantImNeg = (mpfr_sgn(mpfr_constant_im) < 0);

		mpfr_t log2C;
		mpfr_init2(log2C, 100); 
		
		//Constant real part width
		mpfr_log2(log2C, mpfr_constant_re, GMP_RNDN);
		constantReMsb = mpfr_get_si(log2C, GMP_RNDU);

		//Constant imaginary part width
		mpfr_log2(log2C, mpfr_constant_im, GMP_RNDN);
		constantImMsb = mpfr_get_si(log2C, GMP_RNDU);

		//Free
		mpfr_clear(log2C);

		int constantMaxMSB = max(constantReMsb, constantImMsb);	

		//Do we need an extra sign bit ?
		bool extraSignBitRe = !signedInput && (constantReNeg || !constantImNeg);
		bool extraSignBitIm = !signedInput && (constantReNeg || constantImNeg);

		int msbout_re, msbout_im; 
		msbout_re = msbout_im = msb_in + constantMaxMSB +1;
		if(extraSignBitRe)
		{
			msbout_re++;
		}
		if(extraSignBitIm)
		{
			msbout_im++;
		}
		
		outputre_width = msbout_re - lsb_out + 1;
		outputim_width = msbout_im - lsb_out + 1;

		if(outputre_width < 0 || outputim_width < 0)
		{
			THROWERROR("Computed msb will be lower than asked lsb."
					" Result would always be zero ");
		}

	}
static void
exprange (void)
{
  mpfr_exp_t emin, emax;
  mpfr_t x, y, z;
  int inex1, inex2;
  unsigned int flags1, flags2;

  emin = mpfr_get_emin ();
  emax = mpfr_get_emax ();

  mpfr_init2 (x, 16);
  mpfr_inits2 (8, y, z, (mpfr_ptr) 0);

  mpfr_set_ui_2exp (x, 5, -1, MPFR_RNDN);
  mpfr_clear_flags ();
  inex1 = mpfr_gamma (y, x, MPFR_RNDN);
  flags1 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emin (0);
  mpfr_clear_flags ();
  inex2 = mpfr_gamma (z, x, MPFR_RNDN);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emin (emin);
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test1)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }

  mpfr_set_ui_2exp (x, 32769, -60, MPFR_RNDN);
  mpfr_clear_flags ();
  inex1 = mpfr_gamma (y, x, MPFR_RNDD);
  flags1 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (45);
  mpfr_clear_flags ();
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (emax);
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test2)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }

  mpfr_set_emax (44);
  mpfr_clear_flags ();
  inex1 = mpfr_check_range (y, inex1, MPFR_RNDD);
  flags1 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_clear_flags ();
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (emax);
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test3)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }

  mpfr_set_ui_2exp (x, 1, -60, MPFR_RNDN);
  mpfr_clear_flags ();
  inex1 = mpfr_gamma (y, x, MPFR_RNDD);
  flags1 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (60);
  mpfr_clear_flags ();
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  mpfr_set_emax (emax);
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test4)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }

  MPFR_ASSERTN (MPFR_EMIN_MIN == - MPFR_EMAX_MAX);
  mpfr_set_emin (MPFR_EMIN_MIN);
  mpfr_set_emax (MPFR_EMAX_MAX);
  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_nextabove (x);  /* x = 2^(emin - 1) */
  mpfr_set_inf (y, 1);
  inex1 = 1;
  flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
  mpfr_clear_flags ();
  /* MPFR_RNDU: overflow, infinity since 1/x = 2^(emax + 1) */
  inex2 = mpfr_gamma (z, x, MPFR_RNDU);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test5)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_clear_flags ();
  /* MPFR_RNDN: overflow, infinity since 1/x = 2^(emax + 1) */
  inex2 = mpfr_gamma (z, x, MPFR_RNDN);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test6)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_nextbelow (y);
  inex1 = -1;
  mpfr_clear_flags ();
  /* MPFR_RNDD: overflow, maxnum since 1/x = 2^(emax + 1) */
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test7)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_mul_2ui (x, x, 1, MPFR_RNDN);  /* x = 2^emin */
  mpfr_set_inf (y, 1);
  inex1 = 1;
  flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
  mpfr_clear_flags ();
  /* MPFR_RNDU: overflow, infinity since 1/x = 2^emax */
  inex2 = mpfr_gamma (z, x, MPFR_RNDU);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test8)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_clear_flags ();
  /* MPFR_RNDN: overflow, infinity since 1/x = 2^emax */
  inex2 = mpfr_gamma (z, x, MPFR_RNDN);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test9)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_nextbelow (y);
  inex1 = -1;
  flags1 = MPFR_FLAGS_INEXACT;
  mpfr_clear_flags ();
  /* MPFR_RNDD: no overflow, maxnum since 1/x = 2^emax and euler > 0 */
  inex2 = mpfr_gamma (z, x, MPFR_RNDD);
  flags2 = __gmpfr_flags;
  MPFR_ASSERTN (mpfr_inexflag_p ());
  if (inex1 != inex2 || flags1 != flags2 || ! mpfr_equal_p (y, z))
    {
      printf ("Error in exprange (test10)\n");
      printf ("x = ");
      mpfr_dump (x);
      printf ("Expected inex1 = %d, flags1 = %u, ", SIGN (inex1), flags1);
      mpfr_dump (y);
      printf ("Got      inex2 = %d, flags2 = %u, ", SIGN (inex2), flags2);
      mpfr_dump (z);
      exit (1);
    }
  mpfr_set_emin (emin);
  mpfr_set_emax (emax);

  mpfr_clears (x, y, z, (mpfr_ptr) 0);
}
Beispiel #25
0
int
main (void)
{
  int j, k;
  mpfr_t x, y, z, t, y2, z2, t2;

  tests_start_mpfr ();

  mpfr_inits2 (SIZEX, x, y, z, t, y2, z2, t2, (mpfr_ptr) 0);

  mpfr_set_str1 (x, "0.5");
  mpfr_ceil(y, x);
  if (mpfr_cmp_ui (y, 1))
    {
      printf ("Error in mpfr_ceil for x=0.5: expected 1.0, got ");
      mpfr_print_binary(y);
      putchar('\n');
      exit (1);
    }

  mpfr_set_ui (x, 0, MPFR_RNDN);
  mpfr_ceil(y, x);
  if (mpfr_cmp_ui(y,0))
    {
      printf ("Error in mpfr_ceil for x=0.0: expected 0.0, got ");
      mpfr_print_binary(y);
      putchar('\n');
      exit (1);
    }

  mpfr_set_ui (x, 1, MPFR_RNDN);
  mpfr_ceil(y, x);
  if (mpfr_cmp_ui(y,1))
    {
      printf ("Error in mpfr_ceil for x=1.0: expected 1.0, got ");
      mpfr_print_binary(y);
      putchar('\n');
      exit (1);
    }

  for (j=0;j<1000;j++)
    {
      mpfr_urandomb (x, RANDS);
      MPFR_EXP (x) = 2;

      for (k = 2; k <= SIZEX; k++)
        {
          mpfr_set_prec(y, k);
          mpfr_set_prec(y2, k);
          mpfr_set_prec(z, k);
          mpfr_set_prec(z2, k);
          mpfr_set_prec(t, k);
          mpfr_set_prec(t2, k);

          mpfr_floor(y, x);
          mpfr_set(y2, x, MPFR_RNDD);

          mpfr_trunc(z, x);
          mpfr_set(z2, x, MPFR_RNDZ);

          mpfr_ceil(t, x);
          mpfr_set(t2, x, MPFR_RNDU);

          if (!mpfr_eq(y, y2, k))
            {
              printf("Error in floor, x = "); mpfr_print_binary(x);
              printf("\n");
              printf("floor(x) = "); mpfr_print_binary(y);
              printf("\n");
              printf("round(x, RNDD) = "); mpfr_print_binary(y2);
              printf("\n");
              exit(1);
            }

          if (!mpfr_eq(z, z2, k))
            {
              printf("Error in trunc, x = "); mpfr_print_binary(x);
              printf("\n");
              printf("trunc(x) = "); mpfr_print_binary(z);
              printf("\n");
              printf("round(x, RNDZ) = "); mpfr_print_binary(z2);
              printf("\n");
              exit(1);
            }

          if (!mpfr_eq(y, y2, k))
            {
              printf("Error in ceil, x = "); mpfr_print_binary(x);
              printf("\n");
              printf("ceil(x) = "); mpfr_print_binary(t);
              printf("\n");
              printf("round(x, RNDU) = "); mpfr_print_binary(t2);
              printf("\n");
              exit(1);
            }
          MPFR_EXP(x)++;
        }
    }

  mpfr_clears (x, y, z, t, y2, z2, t2, (mpfr_ptr) 0);

  tests_end_mpfr ();
  return 0;
}
static int
tiny_aux (int stop, mpfr_exp_t e)
{
  mpfr_t x, y, z;
  int r, s, spm, inex, err = 0;
  int expected_dir[2][5] = { { 1, -1, 1, -1, 1 }, { 1, 1, 1, -1, -1 } };
  mpfr_exp_t saved_emax;

  saved_emax = mpfr_get_emax ();

  mpfr_init2 (x, 32);
  mpfr_inits2 (8, y, z, (mpfr_ptr) 0);

  mpfr_set_ui_2exp (x, 1, e, MPFR_RNDN);
  spm = 1;
  for (s = 0; s < 2; s++)
    {
      RND_LOOP(r)
        {
          mpfr_rnd_t rr = (mpfr_rnd_t) r;
          mpfr_exp_t exponent, emax;

          /* Exponent of the rounded value in unbounded exponent range. */
          exponent = expected_dir[s][r] < 0 && s == 0 ? - e : 1 - e;

          for (emax = exponent - 1; emax <= exponent; emax++)
            {
              unsigned int flags, expected_flags = MPFR_FLAGS_INEXACT;
              int overflow, expected_inex = expected_dir[s][r];

              if (emax > MPFR_EMAX_MAX)
                break;
              mpfr_set_emax (emax);

              mpfr_clear_flags ();
              inex = mpfr_gamma (y, x, rr);
              flags = __gmpfr_flags;
              mpfr_clear_flags ();
              mpfr_set_si_2exp (z, spm, - e, MPFR_RNDU);
              overflow = mpfr_overflow_p ();
              /* z is 1/x - euler rounded toward +inf */

              if (overflow && rr == MPFR_RNDN && s == 1)
                expected_inex = -1;

              if (expected_inex < 0)
                mpfr_nextbelow (z); /* 1/x - euler rounded toward -inf */

              if (exponent > emax)
                expected_flags |= MPFR_FLAGS_OVERFLOW;

              if (!(mpfr_equal_p (y, z) && flags == expected_flags
                    && SAME_SIGN (inex, expected_inex)))
                {
                  printf ("Error in tiny for s = %d, r = %s, emax = %"
                          MPFR_EXP_FSPEC "d%s\n  on ",
                          s, mpfr_print_rnd_mode (rr), emax,
                          exponent > emax ? " (overflow)" : "");
                  mpfr_dump (x);
                  printf ("  expected inex = %2d, ", expected_inex);
                  mpfr_dump (z);
                  printf ("  got      inex = %2d, ", SIGN (inex));
                  mpfr_dump (y);
                  printf ("  expected flags = %u, got %u\n",
                          expected_flags, flags);
                  if (stop)
                    exit (1);
                  err = 1;
                }
            }
        }
      mpfr_neg (x, x, MPFR_RNDN);
      spm = - spm;
    }

  mpfr_clears (x, y, z, (mpfr_ptr) 0);
  mpfr_set_emax (saved_emax);
  return err;
}
Beispiel #27
0
static void
test_overflow2 (void)
{
  mpfr_t x, y, z, r;
  int i, inex, rnd, err = 0;

  mpfr_inits2 (8, x, y, z, r, (void *) 0);

  MPFR_SET_POS (x);
  mpfr_setmin (x, mpfr_get_emax ());  /* x = 0.1@emax */
  mpfr_set_si (y, -2, GMP_RNDN);      /* y = -2 */
  /* The intermediate multiplication x * y will overflow. */

  for (i = -9; i <= 9; i++)
    RND_LOOP (rnd)
      {
        int inf, overflow;

        inf = rnd == GMP_RNDN || rnd == GMP_RNDD;
        overflow = inf || i <= 0;

        inex = mpfr_set_si_2exp (z, i, mpfr_get_emin (), GMP_RNDN);
        MPFR_ASSERTN (inex == 0);

        mpfr_clear_flags ();
        /* One has: x * y = -1@emax exactly (but not representable). */
        inex = mpfr_fma (r, x, y, z, rnd);
        if (overflow ^ (mpfr_overflow_p () != 0))
          {
            printf ("Error in test_overflow2 (i = %d, %s): wrong overflow"
                    " flag (should be %d)\n", i, mpfr_print_rnd_mode (rnd),
                    overflow);
            err = 1;
          }
        if (mpfr_nanflag_p ())
          {
            printf ("Error in test_overflow2 (i = %d, %s): NaN flag should"
                    " not be set\n", i, mpfr_print_rnd_mode (rnd));
            err = 1;
          }
        if (mpfr_nan_p (r))
          {
            printf ("Error in test_overflow2 (i = %d, %s): got NaN\n",
                    i, mpfr_print_rnd_mode (rnd));
            err = 1;
          }
        else if (MPFR_SIGN (r) >= 0)
          {
            printf ("Error in test_overflow2 (i = %d, %s): wrong sign "
                    "(+ instead of -)\n", i, mpfr_print_rnd_mode (rnd));
            err = 1;
          }
        else if (inf && ! mpfr_inf_p (r))
          {
            printf ("Error in test_overflow2 (i = %d, %s): expected -Inf,"
                    " got\n", i, mpfr_print_rnd_mode (rnd));
            mpfr_dump (r);
            err = 1;
          }
        else if (!inf && (mpfr_inf_p (r) ||
                          (mpfr_nextbelow (r), ! mpfr_inf_p (r))))
          {
            printf ("Error in test_overflow2 (i = %d, %s): expected -MAX,"
                    " got\n", i, mpfr_print_rnd_mode (rnd));
            mpfr_dump (r);
            err = 1;
          }
        if (inf ? inex >= 0 : inex <= 0)
          {
            printf ("Error in test_overflow2 (i = %d, %s): wrong inexact"
                    " flag (got %d)\n", i, mpfr_print_rnd_mode (rnd), inex);
            err = 1;
          }

      }

  if (err)
    exit (1);
  mpfr_clears (x, y, z, r, (void *) 0);
}
Beispiel #28
0
static void
test_generic (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int nmax)
{
  mpfr_prec_t prec, xprec, yprec;
  mpfr_t x, y, z, t, w;
#if defined(TWO_ARGS_ALL)
  mpfr_t u;
#endif
#if defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
  double d;
#endif
#if defined(ULONG_ARG1) || defined(ULONG_ARG2)
  unsigned long i;
#endif
  mpfr_rnd_t rnd;
  int inexact, compare, compare2;
  unsigned int n;
  unsigned long ctrt = 0, ctrn = 0;
  int test_of = 1, test_uf = 1;
  mpfr_exp_t old_emin, old_emax;

  old_emin = mpfr_get_emin ();
  old_emax = mpfr_get_emax ();

  mpfr_inits2 (MPFR_PREC_MIN, x, y, z, t, w, (mpfr_ptr) 0);
#if defined(TWO_ARGS_ALL)
  mpfr_init2 (u, MPFR_PREC_MIN);
#endif

  /* generic test */
  for (prec = p0; prec <= p1; prec++)
    {
      mpfr_set_prec (z, prec);
      mpfr_set_prec (t, prec);
      yprec = prec + 10;
      mpfr_set_prec (y, yprec);
      mpfr_set_prec (w, yprec);

      /* Note: in precision p1, we test 4 special cases. */
      for (n = 0; n < (prec == p1 ? nmax + 4 : nmax); n++)
        {
          int infinite_input = 0;
          unsigned int flags;
          mpfr_exp_t oemin, oemax;

          xprec = prec;
          if (randlimb () & 1)
            {
              xprec *= (double) randlimb () / MP_LIMB_T_MAX;
              if (xprec < MPFR_PREC_MIN)
                xprec = MPFR_PREC_MIN;
            }
          mpfr_set_prec (x, xprec);
#if defined(TWO_ARGS)
          mpfr_set_prec (u, xprec);
#elif defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
          mpfr_set_prec (u, IEEE_DBL_MANT_DIG);
#elif defined(ULONG_ARG1) || defined(ULONG_ARG2)
          mpfr_set_prec (u, sizeof (unsigned long) * CHAR_BIT);
#endif

          if (n > 3 || prec < p1)
            {
#if defined(RAND_FUNCTION)
              RAND_FUNCTION (x);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
              RAND_FUNCTION (u);
#endif
#else  /* ! defined(RAND_FUNCTION) */
              tests_default_random (x, TEST_RANDOM_POS,
                                    TEST_RANDOM_EMIN, TEST_RANDOM_EMAX,
                                    TEST_RANDOM_ALWAYS_SCALE);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
              tests_default_random (u, TEST_RANDOM_POS2,
                                    TEST_RANDOM_EMIN, TEST_RANDOM_EMAX,
                                    TEST_RANDOM_ALWAYS_SCALE);
#endif
#endif  /* ! defined(RAND_FUNCTION) */
            }
          else
            {
              /* Special cases tested in precision p1 if n <= 3. They are
                 useful really in the extended exponent range. */
#if (defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)) && defined(MPFR_ERRDIVZERO)
              goto next_n;
#endif
              set_emin (MPFR_EMIN_MIN);
              set_emax (MPFR_EMAX_MAX);
              if (n <= 1)
                {
                  mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
                  mpfr_set_exp (x, mpfr_get_emin ());
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
                  mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
                  mpfr_set_exp (u, mpfr_get_emin ());
#endif
                }
              else  /* 2 <= n <= 3 */
                {
                  if (getenv ("MPFR_CHECK_MAX") == NULL)
                    goto next_n;
                  mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
                  mpfr_setmax (x, REDUCE_EMAX);
#if defined(TWO_ARGS) || defined(DOUBLE_ARG1) || defined(DOUBLE_ARG2)
                  mpfr_set_si (u, randlimb () % 2 == 0 ? 1 : -1, MPFR_RNDN);
                  mpfr_setmax (u, mpfr_get_emax ());
#endif
                }
            }

#if defined(ULONG_ARG1) || defined(ULONG_ARG2)
          i = randlimb ();
          inexact = mpfr_set_ui (u, i, MPFR_RNDN);
          MPFR_ASSERTN (inexact == 0);
#endif

          /* Exponent range for the test. */
          oemin = mpfr_get_emin ();
          oemax = mpfr_get_emax ();

          rnd = RND_RAND ();
          mpfr_clear_flags ();
#ifdef DEBUG_TGENERIC
          TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (y));
#endif
#if defined(TWO_ARGS)
          compare = TEST_FUNCTION (y, x, u, rnd);
#elif defined(DOUBLE_ARG1)
          d = mpfr_get_d (u, rnd);
          compare = TEST_FUNCTION (y, d, x, rnd);
          /* d can be infinite due to overflow in mpfr_get_d */
          infinite_input |= DOUBLE_ISINF (d);
#elif defined(DOUBLE_ARG2)
          d = mpfr_get_d (u, rnd);
          compare = TEST_FUNCTION (y, x, d, rnd);
          /* d can be infinite due to overflow in mpfr_get_d */
          infinite_input |= DOUBLE_ISINF (d);
#elif defined(ULONG_ARG1)
          compare = TEST_FUNCTION (y, i, x, rnd);
#elif defined(ULONG_ARG2)
          compare = TEST_FUNCTION (y, x, i, rnd);
#else
          compare = TEST_FUNCTION (y, x, rnd);
#endif
          flags = __gmpfr_flags;
          if (mpfr_get_emin () != oemin ||
              mpfr_get_emax () != oemax)
            {
              printf ("tgeneric: the exponent range has been modified"
                      " by the tested function!\n");
              exit (1);
            }
          TGENERIC_CHECK ("bad inexact flag",
                          (compare != 0) ^ (mpfr_inexflag_p () == 0));
          ctrt++;

          /* Tests in a reduced exponent range. */
          {
            unsigned int oldflags = flags;
            mpfr_exp_t e, emin, emax;

            /* Determine the smallest exponent range containing the
               exponents of the mpfr_t inputs (x, and u if TWO_ARGS)
               and output (y). */
            emin = MPFR_EMAX_MAX;
            emax = MPFR_EMIN_MIN;
            if (MPFR_IS_PURE_FP (x))
              {
                e = MPFR_GET_EXP (x);
                if (e < emin)
                  emin = e;
                if (e > emax)
                  emax = e;
              }
#if defined(TWO_ARGS)
            if (MPFR_IS_PURE_FP (u))
              {
                e = MPFR_GET_EXP (u);
                if (e < emin)
                  emin = e;
                if (e > emax)
                  emax = e;
              }
#endif
            if (MPFR_IS_PURE_FP (y))
              {
                e = MPFR_GET_EXP (y);
                if (test_of && e - 1 >= emax)
                  {
                    unsigned int ex_flags;

                    mpfr_set_emax (e - 1);
                    mpfr_clear_flags ();
#if defined(TWO_ARGS)
                    inexact = TEST_FUNCTION (w, x, u, rnd);
#elif defined(DOUBLE_ARG1)
                    inexact = TEST_FUNCTION (w, d, x, rnd);
#elif defined(DOUBLE_ARG2)
                    inexact = TEST_FUNCTION (w, x, d, rnd);
#elif defined(ULONG_ARG1)
                    inexact = TEST_FUNCTION (w, i, x, rnd);
#elif defined(ULONG_ARG2)
                    inexact = TEST_FUNCTION (w, x, i, rnd);
#else
                    inexact = TEST_FUNCTION (w, x, rnd);
#endif
                    flags = __gmpfr_flags;
                    mpfr_set_emax (oemax);
                    ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT;
                    if (flags != ex_flags)
                      {
                        printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
                                ", reduced exponent range [%"
                                MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC
                                "d] (overflow test) on:\n",
                                (mpfr_eexp_t) oemin, (mpfr_eexp_t) e - 1);
                        printf ("x = ");
                        mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                        printf ("u = ");
                        mpfr_dump (u);
#endif
                        printf ("yprec = %u, rnd_mode = %s\n",
                                (unsigned int) yprec,
                                mpfr_print_rnd_mode (rnd));
                        printf ("Expected flags =");
                        flags_out (ex_flags);
                        printf ("     got flags =");
                        flags_out (flags);
                        printf ("inex = %d, w = ", inexact);
                        mpfr_dump (w);
                        exit (1);
                      }
                    test_of = 0;  /* Overflow is tested only once. */
                  }
                if (test_uf && e + 1 <= emin)
                  {
                    unsigned int ex_flags;

                    mpfr_set_emin (e + 1);
                    mpfr_clear_flags ();
#if defined(TWO_ARGS)
                    inexact = TEST_FUNCTION (w, x, u, rnd);
#elif defined(DOUBLE_ARG1)
                    inexact = TEST_FUNCTION (w, d, x, rnd);
#elif defined(DOUBLE_ARG2)
                    inexact = TEST_FUNCTION (w, x, d, rnd);
#elif defined(ULONG_ARG1)
                    inexact = TEST_FUNCTION (w, i, x, rnd);
#elif defined(ULONG_ARG2)
                    inexact = TEST_FUNCTION (w, x, i, rnd);
#else
                    inexact = TEST_FUNCTION (w, x, rnd);
#endif
                    flags = __gmpfr_flags;
                    mpfr_set_emin (oemin);
                    ex_flags = MPFR_FLAGS_UNDERFLOW | MPFR_FLAGS_INEXACT;
                    if (flags != ex_flags)
                      {
                        printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
                                ", reduced exponent range [%"
                                MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC
                                "d] (underflow test) on:\n",
                                (mpfr_eexp_t) e + 1, (mpfr_eexp_t) oemax);
                        printf ("x = ");
                        mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                        printf ("u = ");
                        mpfr_dump (u);
#endif
                        printf ("yprec = %u, rnd_mode = %s\n",
                                (unsigned int) yprec,
                                mpfr_print_rnd_mode (rnd));
                        printf ("Expected flags =");
                        flags_out (ex_flags);
                        printf ("     got flags =");
                        flags_out (flags);
                        printf ("inex = %d, w = ", inexact);
                        mpfr_dump (w);
                        exit (1);
                      }
                    test_uf = 0;  /* Underflow is tested only once. */
                  }
                if (e < emin)
                  emin = e;
                if (e > emax)
                  emax = e;
              }
            if (emin > emax)
              emin = emax;  /* case where all values are singular */
            /* Consistency test in a reduced exponent range. Doing it
               for the first 10 samples and for prec == p1 (which has
               some special cases) should be sufficient. */
            if (ctrt <= 10 || prec == p1)
              {
                mpfr_set_emin (emin);
                mpfr_set_emax (emax);
#ifdef DEBUG_TGENERIC
                /* Useful information in case of assertion failure. */
                printf ("tgeneric: reduced exponent range [%"
                        MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d]\n",
                        (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
#endif
                mpfr_clear_flags ();
#if defined(TWO_ARGS)
                inexact = TEST_FUNCTION (w, x, u, rnd);
#elif defined(DOUBLE_ARG1)
                inexact = TEST_FUNCTION (w, d, x, rnd);
#elif defined(DOUBLE_ARG2)
                inexact = TEST_FUNCTION (w, x, d, rnd);
#elif defined(ULONG_ARG1)
                inexact = TEST_FUNCTION (w, i, x, rnd);
#elif defined(ULONG_ARG2)
                inexact = TEST_FUNCTION (w, x, i, rnd);
#else
                inexact = TEST_FUNCTION (w, x, rnd);
#endif
                flags = __gmpfr_flags;
                mpfr_set_emin (oemin);
                mpfr_set_emax (oemax);
                if (! (SAME_VAL (w, y) &&
                       SAME_SIGN (inexact, compare) &&
                       flags == oldflags))
                  {
                    printf ("tgeneric: error for " MAKE_STR(TEST_FUNCTION)
                            ", reduced exponent range [%"
                            MPFR_EXP_FSPEC "d,%" MPFR_EXP_FSPEC "d] on:\n",
                            (mpfr_eexp_t) emin, (mpfr_eexp_t) emax);
                    printf ("x = ");
                    mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                    printf ("u = ");
                    mpfr_dump (u);
#endif
                    printf ("yprec = %u, rnd_mode = %s\n",
                            (unsigned int) yprec, mpfr_print_rnd_mode (rnd));
                    printf ("Expected:\n  y = ");
                    mpfr_dump (y);
                    printf ("  inex = %d, flags =", compare);
                    flags_out (oldflags);
                    printf ("Got:\n  w = ");
                    mpfr_dump (w);
                    printf ("  inex = %d, flags =", inexact);
                    flags_out (flags);
                    exit (1);
                  }
              }
            __gmpfr_flags = oldflags;  /* restore the flags */
          }

          if (MPFR_IS_SINGULAR (y))
            {
              if (MPFR_IS_NAN (y) || mpfr_nanflag_p ())
                TGENERIC_CHECK ("bad NaN flag",
                                MPFR_IS_NAN (y) && mpfr_nanflag_p ());
              else if (MPFR_IS_INF (y))
                {
                  TGENERIC_CHECK ("bad overflow flag",
                                  (compare != 0) ^ (mpfr_overflow_p () == 0));
                  TGENERIC_CHECK ("bad divide-by-zero flag",
                                  (compare == 0 && !infinite_input) ^
                                  (mpfr_divby0_p () == 0));
                }
              else if (MPFR_IS_ZERO (y))
                TGENERIC_CHECK ("bad underflow flag",
                                (compare != 0) ^ (mpfr_underflow_p () == 0));
            }
          else if (mpfr_divby0_p ())
            {
              TGENERIC_CHECK ("both overflow and divide-by-zero",
                              ! mpfr_overflow_p ());
              TGENERIC_CHECK ("both underflow and divide-by-zero",
                              ! mpfr_underflow_p ());
              TGENERIC_CHECK ("bad compare value (divide-by-zero)",
                              compare == 0);
            }
          else if (mpfr_overflow_p ())
            {
              TGENERIC_CHECK ("both underflow and overflow",
                              ! mpfr_underflow_p ());
              TGENERIC_CHECK ("bad compare value (overflow)", compare != 0);
              mpfr_nexttoinf (y);
              TGENERIC_CHECK ("should have been max MPFR number (overflow)",
                              MPFR_IS_INF (y));
            }
          else if (mpfr_underflow_p ())
            {
              TGENERIC_CHECK ("bad compare value (underflow)", compare != 0);
              mpfr_nexttozero (y);
              TGENERIC_CHECK ("should have been min MPFR number (underflow)",
                              MPFR_IS_ZERO (y));
            }
          else if (mpfr_can_round (y, yprec, rnd, rnd, prec))
            {
              ctrn++;
              mpfr_set (t, y, rnd);
              /* Risk of failures are known when some flags are already set
                 before the function call. Do not set the erange flag, as
                 it will remain set after the function call and no checks
                 are performed in such a case (see the mpfr_erangeflag_p
                 test below). */
              if (randlimb () & 1)
                __gmpfr_flags = MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE;
#ifdef DEBUG_TGENERIC
              TGENERIC_INFO (TEST_FUNCTION, MPFR_PREC (z));
#endif
              /* Let's increase the precision of the inputs in a random way.
                 In most cases, this doesn't make any difference, but for
                 the mpfr_fmod bug fixed in r6230, this triggers the bug. */
              mpfr_prec_round (x, mpfr_get_prec (x) + (randlimb () & 15),
                               MPFR_RNDN);
#if defined(TWO_ARGS)
              mpfr_prec_round (u, mpfr_get_prec (u) + (randlimb () & 15),
                               MPFR_RNDN);
              inexact = TEST_FUNCTION (z, x, u, rnd);
#elif defined(DOUBLE_ARG1)
              inexact = TEST_FUNCTION (z, d, x, rnd);
#elif defined(DOUBLE_ARG2)
              inexact = TEST_FUNCTION (z, x, d, rnd);
#elif defined(ULONG_ARG1)
              inexact = TEST_FUNCTION (z, i, x, rnd);
#elif defined(ULONG_ARG2)
              inexact = TEST_FUNCTION (z, x, i, rnd);
#else
              inexact = TEST_FUNCTION (z, x, rnd);
#endif
              if (mpfr_erangeflag_p ())
                goto next_n;
              if (! mpfr_equal_p (t, z))
                {
                  printf ("tgeneric: results differ for "
                          MAKE_STR(TEST_FUNCTION) " on\n  x = ");
                  mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                  printf ("  u = ");
                  mpfr_dump (u);
#endif
                  printf ("  prec = %u, rnd_mode = %s\n",
                          (unsigned int) prec, mpfr_print_rnd_mode (rnd));
                  printf ("Got      ");
                  mpfr_dump (z);
                  printf ("Expected ");
                  mpfr_dump (t);
                  printf ("Approx   ");
                  mpfr_dump (y);
                  exit (1);
                }
              compare2 = mpfr_cmp (t, y);
              /* if rounding to nearest, cannot know the sign of t - f(x)
                 because of composed rounding: y = o(f(x)) and t = o(y) */
              if (compare * compare2 >= 0)
                compare = compare + compare2;
              else
                compare = inexact; /* cannot determine sign(t-f(x)) */
              if (! SAME_SIGN (inexact, compare))
                {
                  printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
                          "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
                  printf ("x = ");
                  mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                  printf ("u = ");
                  mpfr_dump (u);
#endif
                  printf ("y = ");
                  mpfr_dump (y);
                  printf ("t = ");
                  mpfr_dump (t);
                  exit (1);
                }
            }
          else if (getenv ("MPFR_SUSPICIOUS_OVERFLOW") != NULL)
            {
              /* For developers only! */
              MPFR_ASSERTN (MPFR_IS_PURE_FP (y));
              mpfr_nexttoinf (y);
              if (MPFR_IS_INF (y) && MPFR_IS_LIKE_RNDZ (rnd, MPFR_IS_NEG (y))
                  && !mpfr_overflow_p () && TGENERIC_SO_TEST)
                {
                  printf ("Possible bug! |y| is the maximum finite number "
                          "and has been obtained when\nrounding toward zero"
                          " (%s). Thus there is a very probable overflow,\n"
                          "but the overflow flag is not set!\n",
                          mpfr_print_rnd_mode (rnd));
                  printf ("x = ");
                  mpfr_dump (x);
#if defined(TWO_ARGS_ALL)
                  printf ("u = ");
                  mpfr_dump (u);
#endif
                  exit (1);
                }
            }

        next_n:
          /* In case the exponent range has been changed by
             tests_default_random() or for special values... */
          mpfr_set_emin (old_emin);
          mpfr_set_emax (old_emax);
        }
    }

#ifndef TGENERIC_NOWARNING
  if (3 * ctrn < 2 * ctrt)
    printf ("Warning! Too few normal cases in generic tests (%lu / %lu)\n",
            ctrn, ctrt);
#endif

  mpfr_clears (x, y, z, t, w, (mpfr_ptr) 0);
#if defined(TWO_ARGS_ALL)
  mpfr_clear (u);
#endif
}
static void
underflow (mpfr_exp_t e)
{
  mpfr_t x, y, z1, z2;
  mpfr_exp_t emin;
  int i, k;
  int prec;
  int rnd;
  int div;
  int inex1, inex2;
  unsigned int flags1, flags2;

  /* Test mul_2si(x, e - k), div_2si(x, k - e) and div_2ui(x, k - e)
   * with emin = e, x = 1 + i/16, i in { -1, 0, 1 }, and k = 1 to 4,
   * by comparing the result with the one of a simple division.
   */
  emin = mpfr_get_emin ();
  set_emin (e);
  mpfr_inits2 (8, x, y, (mpfr_ptr) 0);
  for (i = 15; i <= 17; i++)
    {
      inex1 = mpfr_set_ui_2exp (x, i, -4, MPFR_RNDN);
      MPFR_ASSERTN (inex1 == 0);
      for (prec = 6; prec >= 3; prec -= 3)
        {
          mpfr_inits2 (prec, z1, z2, (mpfr_ptr) 0);
          RND_LOOP (rnd)
            for (k = 1; k <= 4; k++)
              {
                /* The following one is assumed to be correct. */
                inex1 = mpfr_mul_2si (y, x, e, MPFR_RNDN);
                MPFR_ASSERTN (inex1 == 0);
                inex1 = mpfr_set_ui (z1, 1 << k, MPFR_RNDN);
                MPFR_ASSERTN (inex1 == 0);
                mpfr_clear_flags ();
                /* Do not use mpfr_div_ui to avoid the optimization
                   by mpfr_div_2si. */
                inex1 = mpfr_div (z1, y, z1, (mpfr_rnd_t) rnd);
                flags1 = __gmpfr_flags;

              for (div = 0; div <= 2; div++)
                {
                  mpfr_clear_flags ();
                  inex2 = div == 0 ?
                    mpfr_mul_2si (z2, x, e - k, (mpfr_rnd_t) rnd) : div == 1 ?
                    mpfr_div_2si (z2, x, k - e, (mpfr_rnd_t) rnd) :
                    mpfr_div_2ui (z2, x, k - e, (mpfr_rnd_t) rnd);
                  flags2 = __gmpfr_flags;
                  if (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
                      mpfr_equal_p (z1, z2))
                    continue;
                  printf ("Error in underflow(");
                  if (e == MPFR_EMIN_MIN)
                    printf ("MPFR_EMIN_MIN");
                  else if (e == emin)
                    printf ("default emin");
                  else
                    printf ("%ld", e);
                  printf (") with mpfr_%s,\nx = %d/16, prec = %d, k = %d, "
                          "%s\n", div == 0 ? "mul_2si" : div == 1 ?
                          "div_2si" : "div_2ui", i, prec, k,
                          mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                  printf ("Expected ");
                  mpfr_out_str (stdout, 16, 0, z1, MPFR_RNDN);
                  printf (", inex = %d, flags = %u\n", SIGN (inex1), flags1);
                  printf ("Got      ");
                  mpfr_out_str (stdout, 16, 0, z2, MPFR_RNDN);
                  printf (", inex = %d, flags = %u\n", SIGN (inex2), flags2);
                  exit (1);
                }  /* div */
              }  /* k */
          mpfr_clears (z1, z2, (mpfr_ptr) 0);
        }  /* prec */
    }  /* i */
  mpfr_clears (x, y, (mpfr_ptr) 0);
  set_emin (emin);
}
Beispiel #30
0
	void FixComplexKCM::emulate(TestCase * tc) {

		/* first we are going to format the entries */
		mpz_class reIn = tc->getInputValue("ReIN");
		mpz_class imIn = tc->getInputValue("ImIN");


		/* Sign handling */
		// Msb index counting from one
		bool reInNeg = (
				signedInput &&
				(mpz_tstbit(reIn.get_mpz_t(), input_width - 1) == 1)
			);

		bool imInNeg = (
				signedInput && 
				(mpz_tstbit(imIn.get_mpz_t(), input_width - 1) == 1)
			);

		// 2's complement -> absolute value unsigned representation
		if(reInNeg)
		{
			reIn = (mpz_class(1) << input_width) - reIn;
		}

		if(imInNeg)
		{
			imIn = (mpz_class(1) << input_width) - imIn;
		}

		//Cast to mp floating point number
		mpfr_t reIn_mpfr, imIn_mpfr;
		mpfr_init2(reIn_mpfr, input_width + 1);
		mpfr_init2(imIn_mpfr, input_width + 1);

		//Exact
		mpfr_set_z(reIn_mpfr, reIn.get_mpz_t(), GMP_RNDN); 
		mpfr_set_z(imIn_mpfr, imIn.get_mpz_t(), GMP_RNDN);

		//Scaling : Exact
		mpfr_mul_2si(reIn_mpfr, reIn_mpfr, lsb_in, GMP_RNDN);
		mpfr_mul_2si(imIn_mpfr, imIn_mpfr, lsb_in, GMP_RNDN);

		mpfr_t re_prod, im_prod, crexim_prod, xrecim_prod;
		mpfr_t reOut, imOut;

		mpfr_inits2(
				2 * input_width + 1, 
				re_prod, 
				im_prod, 
				crexim_prod, 
				xrecim_prod, 
				NULL
			);

		mpfr_inits2(5 * max(outputim_width, outputre_width) + 1, reOut, imOut, NULL);

		// c_r * x_r -> re_prod
		mpfr_mul(re_prod, reIn_mpfr, mpfr_constant_re, GMP_RNDN);

		// c_i * x_i -> im_prod
		mpfr_mul(im_prod, imIn_mpfr, mpfr_constant_im, GMP_RNDN);

		// c_r * x_i -> crexim_prod
		mpfr_mul(crexim_prod, mpfr_constant_re, imIn_mpfr, GMP_RNDN);

		// x_r * c_im -> xrecim_prod
		mpfr_mul(xrecim_prod, reIn_mpfr, mpfr_constant_im, GMP_RNDN);

		/* Input sign correction */
		if(reInNeg)
		{
			//Exact
			mpfr_neg(re_prod, re_prod, GMP_RNDN);
			mpfr_neg(xrecim_prod, xrecim_prod, GMP_RNDN);
		}

		if(imInNeg)
		{
			//Exact
			mpfr_neg(im_prod, im_prod, GMP_RNDN);
			mpfr_neg(crexim_prod, crexim_prod, GMP_RNDN);
		}

		mpfr_sub(reOut, re_prod, im_prod, GMP_RNDN);
		mpfr_add(imOut, crexim_prod, xrecim_prod, GMP_RNDN);

		bool reOutNeg = (mpfr_sgn(reOut) < 0);
		bool imOutNeg = (mpfr_sgn(imOut) < 0);

		if(reOutNeg)
		{
			//Exact
			mpfr_abs(reOut, reOut, GMP_RNDN);
		}

		if(imOutNeg)
		{
			//Exact
			mpfr_abs(imOut, imOut, GMP_RNDN);
		}

		//Scale back (Exact)
		mpfr_mul_2si(reOut, reOut, -lsb_out,  GMP_RNDN);
		mpfr_mul_2si(imOut, imOut, -lsb_out, GMP_RNDN);

		//Get bits vector
		mpz_class reUp, reDown, imUp, imDown, carry;

		mpfr_get_z(reUp.get_mpz_t(), reOut, GMP_RNDU);
		mpfr_get_z(reDown.get_mpz_t(), reOut, GMP_RNDD);
		mpfr_get_z(imDown.get_mpz_t(), imOut, GMP_RNDD);
		mpfr_get_z(imUp.get_mpz_t(), imOut, GMP_RNDU);
		carry = 0;

		//If result was negative, compute 2's complement
		if(reOutNeg)
		{
			reUp = (mpz_class(1) << outputre_width) - reUp;
			reDown = (mpz_class(1) << outputre_width) - reDown;
		}

		if(imOutNeg)
		{
			imUp = (mpz_class(1) << outputim_width) - imUp;
			imDown = (mpz_class(1) << outputim_width) - imDown;
		}

		//Handle border cases
		if(imUp > (mpz_class(1) << outputim_width) - 1 )
		{
			imUp = 0;
		}

		if(reUp > (mpz_class(1) << outputre_width) - 1)
		{
			reUp = 0;
		}

		if(imDown > (mpz_class(1) << outputim_width) - 1 )
		{
			imDown = 0;
		}

		if(reDown > (mpz_class(1) << outputre_width) - 1)
		{
			reDown = 0;
		}

		//Add expected results to corresponding outputs
		tc->addExpectedOutput("ReOut", reUp);	
		tc->addExpectedOutput("ReOut", reDown);	
		tc->addExpectedOutput("ImOut", imUp);	
		tc->addExpectedOutput("ImOut", imDown);	

		mpfr_clears(
				reOut,
				imOut, 
				re_prod, 
				im_prod, 
				crexim_prod, 
				xrecim_prod, 
				reIn_mpfr, 
				imIn_mpfr,
				NULL
			);
	}