Esempio n. 1
0
void
check_one (const char *desc, mpf_ptr got, mpf_srcptr u, mpf_srcptr v)
{
  if (! refmpf_validate_division ("mpf_div", got, u, v))
    {
      mp_trace_base = -16;
      mpf_trace ("  u", u);
      mpf_trace ("  v", v);
      printf    ("  %s\n", desc);
      abort ();
    }
}
Esempio n. 2
0
void
check_print (mpf_srcptr src, mpf_srcptr got, mpf_srcptr want)
{
  mp_trace_base = 16;
  mpf_trace ("src ", src);
  mpf_trace ("got ", got);
  mpf_trace ("want", want);

  printf ("got  size=%d exp=%ld\n", SIZ(got), EXP(got));
  mpn_trace ("     limbs=", PTR(got), (mp_size_t) ABSIZ(got));

  printf ("want size=%d exp=%ld\n", SIZ(want), EXP(want));
  mpn_trace ("     limbs=", PTR(want), (mp_size_t) ABSIZ(want));
}
Esempio n. 3
0
void
check_one (const char *desc, mpf_ptr got, mpf_srcptr u, mpir_ui v)
{
  mp_size_t  usize, usign;
  mp_ptr     wp;
  mpf_t      want;

  MPF_CHECK_FORMAT (got);

  /* this code not nailified yet */
  ASSERT_ALWAYS (BITS_PER_UI <= GMP_NUMB_BITS);
  usign = SIZ (u);
  usize = ABS (usign);
  wp = refmpn_malloc_limbs (usize + 1);
  wp[usize] = mpn_mul_1 (wp, PTR(u), usize, (mp_limb_t) v);

  PTR(want) = wp;
  SIZ(want) = (usign >= 0 ? usize+1 : -(usize+1));
  EXP(want) = EXP(u) + 1;
  refmpf_normalize (want);

  if (! refmpf_validate ("mpf_mul_ui", got, want))
    {
      mp_trace_base = -16;
      printf    ("  %s\n", desc);
      mpf_trace ("  u", u);
      printf    ("  v %ld  0x%lX\n", v, v);
      abort ();
    }

  free (wp);
}
Esempio n. 4
0
void
one (mpf_srcptr f, int want)
{
  int  got;
  got = mpf_integer_p (f);
  if (got != want)
    {
      printf ("mpf_integer_p got %d want %d\n", got, want);
      mpf_trace (" f", f);
      abort ();
    }
}
Esempio n. 5
0
void
check_various (void)
{
  mpf_t  u, got, want;
  char   *s;

  mpf_init2 (u,    2*8*sizeof(long));
  mpf_init2 (got,  2*8*sizeof(long));
  mpf_init2 (want, 2*8*sizeof(long));

  s = "0 * GMP_UI_MAX";
  mpf_set_ui (u, 0L);
  mpf_mul_ui (got, u, GMP_UI_MAX);
  MPF_CHECK_FORMAT (got);
  mpf_set_ui (want, 0L);
  if (mpf_cmp (got, want) != 0)
    {
    error:
      printf ("Wrong result from %s\n", s);
      mpf_trace ("u   ", u);
      mpf_trace ("got ", got);
      mpf_trace ("want", want);
      abort ();
    }

  s = "1 * GMP_UI_MAX";
  mpf_set_ui (u, 1L);
  mpf_mul_ui (got, u, GMP_UI_MAX);
  MPF_CHECK_FORMAT (got);
  mpf_set_ui (want, GMP_UI_MAX);
  if (mpf_cmp (got, want) != 0)
    goto error;

  mpf_clear (u);
  mpf_clear (got);
  mpf_clear (want);
}
Esempio n. 6
0
void
check_one (const char *name, mpf_srcptr x, double y, int cmp)
{
  int   got;

  got = mpf_cmp_d (x, y);
  if (SGN(got) != cmp)
    {
      int i;
      printf    ("mpf_cmp_d wrong (from %s)\n", name);
      printf    ("  got  %d\n", got);
      printf    ("  want %d\n", cmp);
      mpf_trace ("  x", x);
      printf    ("  y %g\n", y);
      mp_trace_base=-16;
      mpf_trace ("  x", x);
      printf    ("  y %g\n", y);
      printf    ("  y");
      for (i = 0; i < sizeof(y); i++)
        printf (" %02X", (unsigned) ((unsigned char *) &y)[i]);
      printf ("\n");
      abort ();
    }
}
void
check_f (void)
{
  static const struct {
    const char  *fmt;
    const char  *input;
    const char  *want;
    int         ret;
    long        ftell;    /* or -1 for length of input string */

  } data[] = {

    { "%Ff",    "0",    "0", 1, -1 },
    { "%Fe",    "0",    "0", 1, -1 },
    { "%FE",    "0",    "0", 1, -1 },
    { "%Fg",    "0",    "0", 1, -1 },
    { "%FG",    "0",    "0", 1, -1 },

    { "%Ff",  "123",    "123", 1, -1 },
    { "%Ff", "+123",    "123", 1, -1 },
    { "%Ff", "-123",   "-123", 1, -1 },
    { "%Ff",  "123.",   "123", 1, -1 },
    { "%Ff", "+123.",   "123", 1, -1 },
    { "%Ff", "-123.",  "-123", 1, -1 },
    { "%Ff",  "123.0",  "123", 1, -1 },
    { "%Ff", "+123.0",  "123", 1, -1 },
    { "%Ff", "-123.0", "-123", 1, -1 },
    { "%Ff",  "0123",   "123", 1, -1 },
    { "%Ff", "-0123",  "-123", 1, -1 },

    { "%Ff",  "123.456e3",   "123456", 1, -1 },
    { "%Ff", "-123.456e3",  "-123456", 1, -1 },
    { "%Ff",  "123.456e+3",  "123456", 1, -1 },
    { "%Ff", "-123.456e+3", "-123456", 1, -1 },
    { "%Ff",  "123000e-3",      "123", 1, -1 },
    { "%Ff", "-123000e-3",     "-123", 1, -1 },
    { "%Ff",  "123000.e-3",     "123", 1, -1 },
    { "%Ff", "-123000.e-3",    "-123", 1, -1 },

    { "%Ff",  "123.456E3",   "123456", 1, -1 },
    { "%Ff", "-123.456E3",  "-123456", 1, -1 },
    { "%Ff",  "123.456E+3",  "123456", 1, -1 },
    { "%Ff", "-123.456E+3", "-123456", 1, -1 },
    { "%Ff",  "123000E-3",      "123", 1, -1 },
    { "%Ff", "-123000E-3",     "-123", 1, -1 },
    { "%Ff",  "123000.E-3",     "123", 1, -1 },
    { "%Ff", "-123000.E-3",    "-123", 1, -1 },

    { "%Ff",  ".456e3",   "456", 1, -1 },
    { "%Ff", "-.456e3",  "-456", 1, -1 },
    { "%Ff",  ".456e+3",  "456", 1, -1 },
    { "%Ff", "-.456e+3", "-456", 1, -1 },

    { "%Ff",    " 0",    "0", 1, -1 },
    { "%Ff",   "  0",    "0", 1, -1 },
    { "%Ff",  "   0",    "0", 1, -1 },
    { "%Ff",   "\t0",    "0", 1, -1 },
    { "%Ff", "\t\t0",    "0", 1, -1 },

    { "hello%Fg",      "hello0",       "0",   1, -1 },
    { "hello%Fg",      "hello 0",      "0",   1, -1 },
    { "hello%Fg",      "hello \t0",    "0",   1, -1 },
    { "hello%Fgworld", "hello 0world", "0",   1, -1 },
    { "hello%Fg",      "hello3.0",     "3.0", 1, -1 },

    { "hello%*Fg",      "hello0",        "-999", 0, -1 },
    { "hello%*Fg",      "hello 0",       "-999", 0, -1 },
    { "hello%*Fg",      "hello \t0",     "-999", 0, -1 },
    { "hello%*Fgworld", "hello 0world",  "-999", 0, -1 },
    { "hello%*Fgworld", "hello3.0world", "-999", 0, -1 },

    { "%Ff",     "",   "-999", -1, -1 },
    { "%Ff",    " ",   "-999", -1, -1 },
    { "%Ff",   "\t",   "-999", -1, -1 },
    { "%Ff",  " \t",   "-999", -1, -1 },
    { " %Ff",    "",   "-999", -1, -1 },
    { "xyz%Ff",  "",   "-999", -1, -1 },

    { "%*Ff",    "",   "-999", -1, -1 },
    { " %*Ff",   "",   "-999", -1, -1 },
    { "xyz%*Ff", "",   "-999", -1, -1 },

    { "%Ff",    "xyz", "0", 0 },

    /* various non-empty but invalid */
    { "%Ff",    "-",      "-999",  0, 1 },
    { "%Ff",    "+",      "-999",  0, 1 },
    { "xyz%Ff", "xyz-",   "-999",  0, 4 },
    { "xyz%Ff", "xyz+",   "-999",  0, 4 },
    { "%Ff",    "-.",     "-999",  0, 2 },
    { "%Ff",    "+.",     "-999",  0, 2 },
    { "%Ff",    ".e",     "-999",  0, 1 },
    { "%Ff",   "-.e",     "-999",  0, 2 },
    { "%Ff",   "+.e",     "-999",  0, 2 },
    { "%Ff",    ".E",     "-999",  0, 1 },
    { "%Ff",   "-.E",     "-999",  0, 2 },
    { "%Ff",   "+.E",     "-999",  0, 2 },
    { "%Ff",    ".e123",  "-999",  0, 1 },
    { "%Ff",   "-.e123",  "-999",  0, 2 },
    { "%Ff",   "+.e123",  "-999",  0, 2 },
    { "%Ff",    "123e",   "-999",  0, 4 },
    { "%Ff",   "-123e",   "-999",  0, 5 },
    { "%Ff",    "123e-",  "-999",  0, 5 },
    { "%Ff",   "-123e-",  "-999",  0, 6 },
    { "%Ff",    "123e+",  "-999",  0, 5 },
    { "%Ff",   "-123e+",  "-999",  0, 6 },
    { "%Ff",   "123e-Z",  "-999",  0, 5 },

    /* hex floats */
    { "%Ff", "0x123p0",       "291",  1, -1 },
    { "%Ff", "0x123P0",       "291",  1, -1 },
    { "%Ff", "0X123p0",       "291",  1, -1 },
    { "%Ff", "0X123P0",       "291",  1, -1 },
    { "%Ff", "-0x123p0",     "-291",  1, -1 },
    { "%Ff", "+0x123p0",      "291",  1, -1 },
    { "%Ff", "0x123.p0",      "291",  1, -1 },
    { "%Ff", "0x12.3p4",      "291",  1, -1 },
    { "%Ff", "-0x12.3p4",    "-291",  1, -1 },
    { "%Ff", "+0x12.3p4",     "291",  1, -1 },
    { "%Ff", "0x1230p-4",     "291",  1, -1 },
    { "%Ff", "-0x1230p-4",   "-291",  1, -1 },
    { "%Ff", "+0x1230p-4",    "291",  1, -1 },
    { "%Ff", "+0x.1230p12",   "291",  1, -1 },
    { "%Ff", "+0x123000p-12", "291",  1, -1 },
    { "%Ff", "0x123 p12",     "291",  1, 5 },
    { "%Ff", "0x9 9",           "9",  1, 3 },
    { "%Ff", "0x01",            "1",  1, 4 },
    { "%Ff", "0x23",           "35",  1, 4 },
    { "%Ff", "0x45",           "69",  1, 4 },
    { "%Ff", "0x67",          "103",  1, 4 },
    { "%Ff", "0x89",          "137",  1, 4 },
    { "%Ff", "0xAB",          "171",  1, 4 },
    { "%Ff", "0xCD",          "205",  1, 4 },
    { "%Ff", "0xEF",          "239",  1, 4 },
    { "%Ff", "0xab",          "171",  1, 4 },
    { "%Ff", "0xcd",          "205",  1, 4 },
    { "%Ff", "0xef",          "239",  1, 4 },
    { "%Ff", "0x100p0A",      "256",  1, 7 },
    { "%Ff", "0x1p9",         "512",  1, -1 },

    /* invalid hex floats */
    { "%Ff", "0x",     "-999",  0, 2 },
    { "%Ff", "-0x",    "-999",  0, 3 },
    { "%Ff", "+0x",    "-999",  0, 3 },
    { "%Ff", "0x-",    "-999",  0, 2 },
    { "%Ff", "0x+",    "-999",  0, 2 },
    { "%Ff", "0x.",    "-999",  0, 3 },
    { "%Ff", "-0x.",   "-999",  0, 4 },
    { "%Ff", "+0x.",   "-999",  0, 4 },
    { "%Ff", "0x.p",   "-999",  0, 3 },
    { "%Ff", "-0x.p",  "-999",  0, 4 },
    { "%Ff", "+0x.p",  "-999",  0, 4 },
    { "%Ff", "0x.P",   "-999",  0, 3 },
    { "%Ff", "-0x.P",  "-999",  0, 4 },
    { "%Ff", "+0x.P",  "-999",  0, 4 },
    { "%Ff", ".p123",  "-999",  0, 1 },
    { "%Ff", "-.p123", "-999",  0, 2 },
    { "%Ff", "+.p123", "-999",  0, 2 },
    { "%Ff", "0x1p",   "-999",  0, 4 },
    { "%Ff", "0x1p-",  "-999",  0, 5 },
    { "%Ff", "0x1p+",  "-999",  0, 5 },
    { "%Ff", "0x123p 12", "291",  0, 6 },
    { "%Ff", "0x 123p12", "291",  0, 2 },

  };

  int         i, j, ignore, got_ret, want_ret, got_upto, want_upto;
  mpf_t       got, want;
  double      got_d;
  long        want_ftell;
  int         error = 0;
  fun_t       fun;
  const char  *name;
  char        fmt[128];

  mpf_init (got);
  mpf_init (want);

  for (i = 0; i < numberof (data); i++)
    {
      mpf_set_str_or_abort (want, data[i].want, 10);

      ASSERT_ALWAYS (strlen (data[i].fmt) + 2 < sizeof (fmt));
      strcpy (fmt, data[i].fmt);
      strcat (fmt, "%n");

      ignore = (strchr (fmt, '*') != NULL);

      for (j = 0; j <= 3; j++)
        {
          want_ret = data[i].ret;

          want_ftell = data[i].ftell;
          if (want_ftell == -1)
            want_ftell = strlen (data[i].input);
          want_upto = want_ftell;

          if (want_ret == -1 || (want_ret == 0 && ! ignore))
            want_upto = -555;

          switch (j) {
          case 0:
            name = "gmp_sscanf";
            fun = fun_gmp_sscanf;
            break;
          case 1:
            name = "gmp_fscanf";
            fun = fun_gmp_fscanf;
            break;
          case 2:
            if (! libc_scanf_convert (fmt))
              continue;
            name = "standard sscanf";
            fun = fun_sscanf;
            break;
          case 3:
            if (! libc_scanf_convert (fmt))
              continue;
            name = "standard fscanf";
            fun = fun_fscanf;
            break;
          default:
            ASSERT_ALWAYS (0);
            break;
          }

          got_upto = -555;
          got_ftell = -1;

          switch (j) {
          case 0:
          case 1:
            mpf_set_si (got, -999L);
            if (ignore)
              got_ret = (*fun) (data[i].input, fmt, &got_upto, NULL);
            else
              got_ret = (*fun) (data[i].input, fmt, got, &got_upto);
            break;
          case 2:
          case 3:
            got_d = -999L;
            if (ignore)
              got_ret = (*fun) (data[i].input, fmt, &got_upto, NULL);
            else
              got_ret = (*fun) (data[i].input, fmt, &got_d, &got_upto);
            mpf_set_d (got, got_d);
            break;
          default:
            ASSERT_ALWAYS (0);
            break;
          }

          MPF_CHECK_FORMAT (got);

          if (got_ret != want_ret)
            {
              printf ("%s wrong return value\n", name);
              error = 1;
            }
          if (want_ret == 1 && mpf_cmp (want, got) != 0)
            {
              printf ("%s wrong result\n", name);
              error = 1;
            }
          if (got_upto != want_upto)
            {
              printf ("%s wrong upto\n", name);
              error = 1;
            }
          if (got_ftell != -1 && want_ftell != -1 && got_ftell != want_ftell)
            {
              printf ("%s wrong ftell\n", name);
              error = 1;
            }
          if (error)
            {
              printf    ("  fmt   \"%s\"\n", data[i].fmt);
              printf    ("  input \"%s\"\n", data[i].input);
              printf    ("  ret   want=%d\n", want_ret);
              printf    ("        got =%d\n", got_ret);
              mpf_trace ("  value want", want);
              mpf_trace ("        got ", got);
              printf    ("  upto  want=%d\n", want_upto);
              printf    ("        got =%d\n", got_upto);
              if (got_ftell != -1)
                {
                  printf    ("  ftell want =%ld\n", want_ftell);
                  printf    ("        got  =%ld\n", got_ftell);
                }
              abort ();
            }
        }
    }

  mpf_clear (got);
  mpf_clear (want);
}
Esempio n. 8
0
void
check_rand (void)
{
  unsigned long      max_prec = 15;
  unsigned long      min_prec = __GMPF_BITS_TO_PREC (1);
  gmp_randstate_ptr  rands = RANDS;
  unsigned long      x, prec;
  mpf_t              r, s;
  int                i;

  mpf_init (r);
  mpf_init (s);
  refmpf_set_prec_limbs (s, 2*max_prec+10);

  for (i = 0; i < 50; i++)
    {
      /* input, a random non-zero ulong, exponentially distributed */
      do {
        x = gmp_urandomb_ui (rands,
                             gmp_urandomm_ui (rands, BITS_PER_ULONG) + 1);
      } while (x == 0);

      /* result precision */
      prec = gmp_urandomm_ui (rands, max_prec-min_prec) + min_prec;
      refmpf_set_prec_limbs (r, prec);

      mpf_sqrt_ui (r, x);
      MPF_CHECK_FORMAT (r);

      /* Expect to prec limbs of result.
         In the current implementation there's no stripping of low zero
         limbs in mpf_sqrt_ui, not even on perfect squares, so size should
         be exactly prec.  */
      if (SIZ(r) != prec)
        {
          printf ("mpf_sqrt_ui result not enough result limbs\n");
          printf    ("  x=%lu\n", x);
          printf    ("  want prec=%lu\n", prec);
          mpf_trace ("  r", r);
          printf    ("  r size %ld\n", (long) SIZ(r));
          printf    ("  r prec %ld\n", (long) PREC(r));
          abort ();
        }

      /* Must have r^2 <= x, since r has been truncated. */
      mpf_mul (s, r, r);
      if (! (mpf_cmp_ui (s, x) <= 0))
        {
          printf    ("mpf_sqrt_ui result too big\n");
          printf    ("  x=%lu\n", x);
          printf    ("  want prec=%lu\n", prec);
          mpf_trace ("  r", r);
          mpf_trace ("  s", s);
          abort ();
        }

      /* Must have (r+ulp)^2 > x.
         No overflow from refmpf_add_ulp since r is only prec limbs. */
      refmpf_add_ulp (r);
      mpf_mul (s, r, r);
      if (! (mpf_cmp_ui (s, x) > 0))
        {
          printf    ("mpf_sqrt_ui result too small\n");
          printf    ("  x=%lu\n", x);
          printf    ("  want prec=%lu\n", prec);
          mpf_trace ("  r+ulp", r);
          mpf_trace ("  s", s);
          abort ();
        }
    }

  mpf_clear (r);
  mpf_clear (s);
}
void
check_limbdata (void)
{
#define M  GMP_NUMB_MAX
  
  static const struct {
    mp_exp_t       exp;
    mp_size_t      size;
    mp_limb_t      d[10];
    unsigned long  want;

  } data[] = {

    /* in the comments here, a "_" indicates a digit (ie. limb) position not
       included in the d data, and therefore zero */

    { 0, 0, { 0 }, 0L },    /* 0 */

    { 1,  1, { 1 }, 1L },   /* 1 */
    { 1, -1, { 1 }, -1L },  /* -1 */

    { 0,  1, { 1 }, 0L },   /* .1 */
    { 0, -1, { 1 }, 0L },   /* -.1 */

    { -1,  1, { 1 }, 0L },  /* ._1 */
    { -1, -1, { 1 }, 0L },  /* -._1 */

    { -999,          1, { 1 }, 0L },   /* .___1 small */
    { MP_EXP_T_MIN,  1, { 1 }, 0L },   /* .____1 very small */

    { 999,          1, { 1 }, 0L },    /* 1____. big */
    { MP_EXP_T_MAX, 1, { 1 }, 0L },    /* 1_____. very big */

    { 1, 2, { 999, 2 }, 2L },                  /* 2.9 */
    { 5, 8, { 7, 8, 9, 3, 0, 0, 0, 1 }, 3L },  /* 10003.987 */

    { 2, 2, { M, M },    LONG_MAX }, /* FF. */
    { 2, 2, { M, M, M }, LONG_MAX }, /* FF.F */
    { 3, 3, { M, M, M }, LONG_MAX }, /* FFF. */

#if GMP_NUMB_BITS >= BITS_PER_ULONG
    /* normal case, numb bigger than long */
    { 2,  1, { 1 },    0L },      /* 1_. */
    { 2,  2, { 0, 1 }, 0L },      /* 10. */
    { 2,  2, { 999, 1 }, 999L },  /* 19. */
    { 3,  2, { 999, 1 }, 0L },    /* 19_. */

#else
    /* nails case, numb smaller than long */
    { 2,  1, { 1 }, 1L << GMP_NUMB_BITS },  /* 1_. */
    { 3,  1, { 1 }, 0L },                   /* 1__. */

    { 2,  2, { 99, 1 },    99L + (1L << GMP_NUMB_BITS) },  /* 19. */
    { 3,  2, { 1, 99 },    1L << GMP_NUMB_BITS },          /* 91_. */
    { 3,  3, { 0, 1, 99 }, 1L << GMP_NUMB_BITS },          /* 910. */

#endif
  };

  mpf_t          f;
  unsigned long  got;
  int            i;
  mp_limb_t      buf[20 + numberof(data[i].d)];

  for (i = 0; i < numberof (data); i++)
    {
      refmpn_fill (buf, 10, CNST_LIMB(0xDEADBEEF));
      refmpn_copy (buf+10, data[i].d, ABS(data[i].size));
      refmpn_fill (buf+10+ABS(data[i].size), 10, CNST_LIMB(0xDEADBEEF));

      PTR(f) = buf+10;
      EXP(f) = data[i].exp;
      SIZ(f) = data[i].size;
      PREC(f) = numberof (data[i].d);
      MPF_CHECK_FORMAT (f);

      got = mpf_get_si (f);
      if (got != data[i].want)
        {
          printf    ("mpf_get_si wrong at limb data[%d]\n", i);
          mpf_trace ("  f", f);
          mpn_trace ("  d", data[i].d, data[i].size);
          printf    ("  size %ld\n", (long) data[i].size);
          printf    ("  exp %ld\n", (long) data[i].exp);
          printf    ("  got   %lu (0x%lX)\n", got, got);
          printf    ("  want  %lu (0x%lX)\n", data[i].want, data[i].want);
          abort();
        }
    }
}
Esempio n. 10
0
void
check_one (mpz_srcptr z)
{
  static const int shift[] = {
    0, 1, BITS_PER_MP_LIMB, 2*BITS_PER_MP_LIMB, 5*BITS_PER_MP_LIMB
  };

  int    sh, shneg, neg;
  mpf_t  f;
  mpz_t  got, want;

  mpf_init2 (f, mpz_sizeinbase(z,2));
  mpz_init (got);
  mpz_init (want);

  for (sh = 0; sh < numberof(shift); sh++)
    {
      for (shneg = 0; shneg <= 1; shneg++)
        {
          for (neg = 0; neg <= 1; neg++)
            {
              mpf_set_z (f, z);
              mpz_set (want, z);
            
              if (neg)
                {
                  mpf_neg (f, f);
                  mpz_neg (want, want);
                }

              if (shneg)
                {
                  mpz_tdiv_q_2exp (want, want, shift[sh]);
                  mpf_div_2exp (f, f, shift[sh]);
                }
              else
                {
                  mpz_mul_2exp (want, want, shift[sh]);
                  mpf_mul_2exp (f, f, shift[sh]);
                }

              mpz_set_f (got, f);
              MPZ_CHECK_FORMAT (got);

              if (mpz_cmp (got, want) != 0)
                {
                  printf ("wrong result\n");
                  printf ("  shift  %d\n", shneg ? -shift[sh] : shift[sh]);
                  printf ("  neg    %d\n", neg);
                  mpf_trace ("     f", f);
                  mpz_trace ("   got", got);
                  mpz_trace ("  want", want);
                  abort ();
                }
            }
        }
    }

  mpf_clear (f);
  mpz_clear (got);
  mpz_clear (want);
}
Esempio n. 11
0
void
check_data (void)
{
    static const struct {
        struct {
            int        exp, size;
            mp_limb_t  d[10];
        } x, y, want;

    } data[] = {
        { { 123, 2, { 8, 9 } },             { 123, 1, { 9 } }, { 122, 1, { 8 } } },

        /* f - f == 0, various sizes.
           These exercise a past problem (gmp 4.1.3 and earlier) where the
           result exponent was not zeroed on a zero result like this.  */
        { { 0, 0 }, { 0, 0 }, { 0, 0 } },
        { { 99, 1, { 1 } },             { 99, 1, { 1 } },             { 0, 0 } },
        { { 99, 2, { 123, 456 } },      { 99, 2, { 123, 456 } },      { 0, 0 } },
        { { 99, 3, { 123, 456, 789 } }, { 99, 3, { 123, 456, 789 } }, { 0, 0 } },

        /* High limbs cancel, leaving just the low limbs of the longer operand.
           This exercises a past problem (gmp 4.1.3 and earlier) where high zero
           limbs on the remainder were not stripped before truncating to the
           destination, causing loss of precision.  */
        { { 123, 2, { 8, 9 } },             { 123, 1, { 9 } }, { 122, 1, { 8 } } },
        { { 123, 3, { 8, 0, 9 } },          { 123, 1, { 9 } }, { 121, 1, { 8 } } },
        { { 123, 4, { 8, 0, 0, 9 } },       { 123, 1, { 9 } }, { 120, 1, { 8 } } },
        { { 123, 5, { 8, 0, 0, 0, 9 } },    { 123, 1, { 9 } }, { 119, 1, { 8 } } },
        { { 123, 6, { 8, 0, 0, 0, 0, 9 } }, { 123, 1, { 9 } }, { 118, 1, { 8 } } },

    };

    mpf_t  x, y, got, want;
    int  i, swap;

    mp_trace_base = 16;
    mpf_init (got);

    for (i = 0; i < numberof (data); i++)
    {
        for (swap = 0; swap <= 1; swap++)
        {
            PTR(x) = (mp_ptr) data[i].x.d;
            SIZ(x) = data[i].x.size;
            EXP(x) = data[i].x.exp;
            PREC(x) = numberof (data[i].x.d);
            MPF_CHECK_FORMAT (x);

            PTR(y) = (mp_ptr) data[i].y.d;
            SIZ(y) = data[i].y.size;
            EXP(y) = data[i].y.exp;
            PREC(y) = numberof (data[i].y.d);
            MPF_CHECK_FORMAT (y);

            PTR(want) = (mp_ptr) data[i].want.d;
            SIZ(want) = data[i].want.size;
            EXP(want) = data[i].want.exp;
            PREC(want) = numberof (data[i].want.d);
            MPF_CHECK_FORMAT (want);

            if (swap)
            {
                mpf_swap (x, y);
                SIZ(want) = - SIZ(want);
            }

            mpf_sub (got, x, y);
            /*           MPF_CHECK_FORMAT (got); */

            if (mpf_cmp (got, want) != 0)
            {
                printf ("check_data() wrong reault at data[%d] (operands%s swapped)\n", i, swap ? "" : " not");
                mpf_trace ("x   ", x);
                mpf_trace ("y   ", y);
                mpf_trace ("got ", got);
                mpf_trace ("want", want);
                abort ();
            }
        }
    }

    mpf_clear (got);
}
Esempio n. 12
0
void
check_rand1 (int argc, char **argv)
{
  mp_size_t size;
  mp_exp_t exp;
  int reps = 20000;
  int i;
  mpf_t x, y, y2;
  mp_size_t bprec = 100;
  mpf_t rerr, max_rerr, limit_rerr;

  if (argc > 1)
    {
      reps = strtol (argv[1], 0, 0);
      if (argc > 2)
	bprec = strtol (argv[2], 0, 0);
    }

  mpf_set_default_prec (bprec);

  mpf_init_set_ui (limit_rerr, 1);
  mpf_div_2exp (limit_rerr, limit_rerr, bprec);
#if VERBOSE
  mpf_dump (limit_rerr);
#endif
  mpf_init (rerr);
  mpf_init_set_ui (max_rerr, 0);

  mpf_init (x);
  mpf_init (y);
  mpf_init (y2);
  for (i = 0; i < reps; i++)
    {
      size = urandom () % SIZE;
      exp = urandom () % SIZE;
      mpf_random2 (x, size, exp);

      mpf_sqrt (y, x);
      MPF_CHECK_FORMAT (y);
      mpf_mul (y2, y, y);

      mpf_reldiff (rerr, x, y2);
      if (mpf_cmp (rerr, max_rerr) > 0)
	{
	  mpf_set (max_rerr, rerr);
#if VERBOSE
	  mpf_dump (max_rerr);
#endif
	  if (mpf_cmp (rerr, limit_rerr) > 0)
	    {
	      printf ("ERROR after %d tests\n", i);
	      printf ("   x = "); mpf_dump (x);
	      printf ("   y = "); mpf_dump (y);
	      printf ("  y2 = "); mpf_dump (y2);
	      printf ("   rerr       = "); mpf_dump (rerr);
	      printf ("   limit_rerr = "); mpf_dump (limit_rerr);
              printf ("in hex:\n");
              mp_trace_base = 16;
	      mpf_trace ("   x  ", x);
	      mpf_trace ("   y  ", y);
	      mpf_trace ("   y2 ", y2);
	      mpf_trace ("   rerr      ", rerr);
	      mpf_trace ("   limit_rerr", limit_rerr);
	      abort ();
	    }
	}
    }

  mpf_clear (limit_rerr);
  mpf_clear (rerr);
  mpf_clear (max_rerr);

  mpf_clear (x);
  mpf_clear (y);
  mpf_clear (y2);
}
Esempio n. 13
0
void
check_rand2 (void)
{
  unsigned long      max_prec = 20;
  unsigned long      min_prec = __GMPF_BITS_TO_PREC (1);
  gmp_randstate_ptr  rands = RANDS;
  unsigned long      x_prec, r_prec;
  mpf_t              x, r, s;
  int                i;

  mpf_init (x);
  mpf_init (r);
  mpf_init (s);
  refmpf_set_prec_limbs (s, 2*max_prec+10);

  for (i = 0; i < 500; i++)
    {
      /* input precision */
      x_prec = gmp_urandomm_ui (rands, max_prec-min_prec) + min_prec;
      refmpf_set_prec_limbs (x, x_prec);

      /* result precision */
      r_prec = gmp_urandomm_ui (rands, max_prec-min_prec) + min_prec;
      refmpf_set_prec_limbs (r, r_prec);

      mpf_random2 (x, x_prec, 1000);

      mpf_sqrt (r, x);
      MPF_CHECK_FORMAT (r);

      /* Expect to prec limbs of result.
         In the current implementation there's no stripping of low zero
         limbs in mpf_sqrt, so size should be exactly prec.  */
      if (SIZ(r) != r_prec)
        {
          printf ("mpf_sqrt wrong number of result limbs\n");
          mpf_trace ("  x", x);
          mpf_trace ("  r", r);
          printf    ("  r_prec=%lu\n", r_prec);
          printf    ("  SIZ(r)  %ld\n", (long) SIZ(r));
          printf    ("  PREC(r) %ld\n", (long) PREC(r));
          abort ();
        }

      /* Must have r^2 <= x, since r has been truncated. */
      mpf_mul (s, r, r);
      if (! (mpf_cmp (s, x) <= 0))
        {
          printf    ("mpf_sqrt result too big\n");
          mpf_trace ("  x", x);
          printf    ("  r_prec=%lu\n", r_prec);
          mpf_trace ("  r", r);
          mpf_trace ("  s", s);
          abort ();
        }

      /* Must have (r+ulp)^2 > x, or else r is too small. */
      refmpf_add_ulp (r);
      mpf_mul (s, r, r);
      if (! (mpf_cmp (s, x) > 0))
        {
          printf    ("mpf_sqrt result too small\n");
          mpf_trace ("  x", x);
          printf    ("  r_prec=%lu\n", r_prec);
          mpf_trace ("  r+ulp", r);
          mpf_trace ("  s", s);
          abort ();
        }
    }

  mpf_clear (x);
  mpf_clear (r);
  mpf_clear (s);
}
Esempio n. 14
0
void
check_data (void)
{
  static const struct
  {
    struct {
      int        exp, size;
      mp_limb_t  d[10];
    } x, y;
    mp_bitcnt_t bits;
    int want;

  } data[] = {
    { { 0, 0, { 0 } },             { 0, 0, { 0 } },    0, 1 },

    { { 0, 1, { 7 } },             { 0, 1, { 7 } },    0, 1 },
    { { 0, 1, { 7 } },             { 0, 1, { 7 } },   17, 1 },
    { { 0, 1, { 7 } },             { 0, 1, { 7 } }, 4711, 1 },

    { { 0, 1, { 7 } },             { 0, 1, { 6 } },    0, 1 },
    { { 0, 1, { 7 } },             { 0, 1, { 6 } },    2, 1 },
    { { 0, 1, { 7 } },             { 0, 1, { 6 } },    3, 0 },

    { { 0, 0, { 0 } },             { 0, 1, { 1 } },    0, 0 },
    { { 0, 1, { 1 } },             { 0,-1 ,{ 1 } },    0, 0 },
    { { 1, 1, { 1 } },             { 0, 1, { 1 } },    0, 0 },

    { { 0, 1, { 8 } },             { 0, 1, { 4 } },    0, 0 },

    { { 0, 2, { 0, 3 } },          { 0, 1, { 3 } }, 1000, 1 },
  };

  mpf_t  x, y;
  int got, got_swapped;
  int i;
  mp_trace_base = 16;

  for (i = 0; i < numberof (data); i++)
    {
      PTR(x) = (mp_ptr) data[i].x.d;
      SIZ(x) = data[i].x.size;
      EXP(x) = data[i].x.exp;
      PREC(x) = numberof (data[i].x.d);
      MPF_CHECK_FORMAT (x);

      PTR(y) = (mp_ptr) data[i].y.d;
      SIZ(y) = data[i].y.size;
      EXP(y) = data[i].y.exp;
      PREC(y) = numberof (data[i].y.d);
      MPF_CHECK_FORMAT (y);

      got         = mpf_eq (x, y, data[i].bits);
      got_swapped = mpf_eq (y, x, data[i].bits);

      if (got != got_swapped || got != data[i].want)
	{
	  printf ("check_data() wrong result at data[%d]\n", i);
	  mpf_trace ("x   ", x);
	  mpf_trace ("y   ", y);
	  printf ("got         %d\n", got);
	  printf ("got_swapped %d\n", got_swapped);
	  printf ("want        %d\n", data[i].want);
	  abort ();
        }
    }
}
Esempio n. 15
0
void
check_input (void)
{
  static const char *point[] = {
    ".", ",", "WU", "STR", "ZTV***"
  };

  static const struct {
    const char  *str;
    double      d;
  } data[] = {

    { "1%s",   1.0 },
    { "1%s0",  1.0 },
    { "1%s00", 1.0 },

    { "%s5",    0.5 },
    { "0%s5",   0.5 },
    { "00%s5",  0.5 },
    { "00%s50", 0.5 },

    { "1%s5",    1.5 },
    { "1%s5e1", 15.0 },
  };

  int     i, j, neg, ret;
  char    str[128];
  mpf_t   f;
  double  d;

  mpf_init (f);

  for (i = 0; i < numberof (point); i++)
    {
      decimal_point = (const char *) point[i];

      for (neg = 0; neg <= 1; neg++)
        {
          for (j = 0; j < numberof (data); j++)
            {
              strcpy (str, neg ? "-" : "");
              sprintf (str+strlen(str), data[j].str, decimal_point);

              d = data[j].d;
              if (neg)
                d = -d;

              mpf_set_d (f, 123.0);
              if (mpf_set_str (f, str, 10) != 0)
                {
                  printf ("mpf_set_str error\n");
                  printf ("  point  %s\n", decimal_point);
                  printf ("  str    %s\n", str);
                  abort ();
                }
              if (mpf_cmp_d (f, d) != 0)
                {
                  printf    ("mpf_set_str wrong result\n");
                  printf    ("  point  %s\n", decimal_point);
                  printf    ("  str    %s\n", str);
                  mpf_trace ("  f", f);
                  printf    ("  d=%g\n", d);
                  abort ();
                }

              mpf_set_d (f, 123.0);
              ret = gmp_sscanf (str, "%Ff", f);
              if (ret != 1)
                {
                  printf ("gmp_sscanf wrong return value\n");
                  printf ("  point  %s\n", decimal_point);
                  printf ("  str    %s\n", str);
                  printf ("  ret    %d\n", ret);
                  abort ();
                }
              if (mpf_cmp_d (f, d) != 0)
                {
                  printf    ("gmp_sscanf wrong result\n");
                  printf    ("  point  %s\n", decimal_point);
                  printf    ("  str    %s\n", str);
                  mpf_trace ("  f", f);
                  printf    ("  d=%g\n", d);
                  abort ();
                }
            }
        }
    }
  mpf_clear (f);
}