/* Print "name=value\n" to stdout for a limb, nail doesn't have to be zero. */
void
mp_limb_trace (const char *name, mp_limb_t n)
{
#if GMP_NAIL_BITS != 0
  mp_limb_t  a[2];
  a[0] = n & GMP_NUMB_MASK;
  a[1] = n >> GMP_NUMB_BITS;
  mpn_trace (name, a, (mp_size_t) 2);
#else
  mpn_trace (name, &n, (mp_size_t) 1);
#endif
}
Ejemplo n.º 2
0
void
check_data (void)
{
  static const struct {
    double     d;
    mp_size_t  want_size;
    mp_limb_t  want_data[2];
  } data[] = {

    {  0.0,  0 },
    {  1.0,  1, { 1 } },
    { -1.0, -1, { 1 } },

    {  123.0,  1, { 123 } },
    { -123.0, -1, { 123 } },
  };

  mpz_t  z;
  int    i;

  for (i = 0; i < numberof (data); i++)
    {
      mpz_init (z);
      mpz_set_d (z, data[i].d);
      MPZ_CHECK_FORMAT (z);
      if (z->_mp_size != data[i].want_size
          || refmpn_cmp_allowzero (z->_mp_d, data[i].want_data,
                                   ABS (data[i].want_size)) != 0)
        {
          printf ("mpz_set_d wrong on data[%d]\n", i);
        bad:
          d_trace   ("  d  ", data[i].d);
          printf    ("  got  size %ld\n", (long) z->_mp_size);
          printf    ("  want size %ld\n", (long) data[i].want_size);
          mpn_trace ("  got  z", z->_mp_d, z->_mp_size);
          mpn_trace ("  want z", data[i].want_data, data[i].want_size);
          abort();
        }
      mpz_clear (z);

      mpz_init_set_d (z, data[i].d);
      MPZ_CHECK_FORMAT (z);
      if (z->_mp_size != data[i].want_size
          || refmpn_cmp_allowzero (z->_mp_d, data[i].want_data,
                                   ABS (data[i].want_size)) != 0)
        {
          printf ("mpz_init_set_d wrong on data[%d]\n", i);
          goto bad;
        }
      mpz_clear (z);
    }
}
Ejemplo n.º 3
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));
}
Ejemplo n.º 4
0
void
check_one (const char *name, int i,
           mp_srcptr src, mp_limb_t n,
           mp_srcptr got, mp_srcptr want, mp_size_t size)
{
  if (! refmpn_equal_anynail (got, want, size))
    {
      printf ("Wrong at %s i=%d\n", name, i);
      mpn_trace ("  src", src,  size);
      mpn_trace ("    n", &n,   (mp_size_t) 1);
      mpn_trace ("  got", got,  size);
      mpn_trace (" want", want, size);
      abort ();
    }
}
/* Print "namenum=value\n" to stdout for an mpn style ptr,size.
   "name" should have a "%d" to get the number.  */
void
mpn_tracen (const char *name, int num, mp_srcptr ptr, mp_size_t size)
{
  if (name != NULL && name[0] != '\0')
    {
      printf (name, num);
      putchar ('=');
    }
  mpn_trace (NULL, ptr, size);
}
Ejemplo n.º 6
0
void
check (void)
{
  unsigned long  i, got, want;

  x[SIZE] = 1;
  for (i = 0; i < SIZE*GMP_NUMB_BITS; i++)
    {
      got = refmpn_scan1 (x, i);
      want = mpn_scan1 (x, i);
      if (got != want)
        {
          printf ("mpn_scan1\n");
          printf ("  i     %lu\n", i);
          printf ("  got   %lu\n", got);
          printf ("  want  %lu\n", want);
          mpn_trace ("  x    ", x, SIZE);
          abort ();
        }
    }

  x[SIZE] = 0;
  for (i = 0; i < SIZE*GMP_NUMB_BITS; i++)
    {
      got = refmpn_scan0 (x, i);
      want = mpn_scan0 (x, i);
      if (got != want)
        {
          printf ("mpn_scan0\n");
          printf ("  i     %lu\n", i);
          printf ("  got   %lu\n", got);
          printf ("  want  %lu\n", want);
          mpn_trace ("  x    ", x, SIZE);
          abort ();
        }
    }
}
Ejemplo n.º 7
0
/* Exercise values 2^n+1, while such a value fits the mantissa of a double. */
void
check_twobit (void)
{
  int        i, mant_bits;
  double     got, want;
  mp_size_t  nsize, sign;
  mp_ptr     np;

  mant_bits = tests_dbl_mant_bits ();
  if (mant_bits == 0)
    return;

  np = refmpn_malloc_limbs (BITS_TO_LIMBS (mant_bits));
  want = 3.0;
  for (i = 1; i < mant_bits; i++)
    {
      nsize = BITS_TO_LIMBS (i+1);
      refmpn_zero (np, nsize);
      np[i/GMP_NUMB_BITS] = CNST_LIMB(1) << (i % GMP_NUMB_BITS);
      np[0] |= 1;

      for (sign = 0; sign >= -1; sign--)
        {
          got = mpn_get_d (np, nsize, sign, 0);
          if (got != want)
            {
              printf    ("mpn_get_d wrong on 2^%d + 1\n", i);
              printf    ("   sign     %ld\n", (long) sign);
              mpn_trace ("   n        ", np, nsize);
              printf    ("   nsize    %ld\n", (long) nsize);
              d_trace   ("   want     ", want);
              d_trace   ("   got      ", got);
              abort();
            }
          want = -want;
        }

      want = 2.0 * want - 1.0;
    }

  free (np);
}
Ejemplo n.º 8
0
void
verify (const char *name, int i,
        mp_srcptr src, mp_limb_t n,
        mp_limb_t got_c, mp_limb_t want_c,
        mp_srcptr got, mp_srcptr want, mp_size_t size)
{
    if (got[size] != MAGIC)
    {
        printf ("Overwrite at %s i=%d\n", name, i);
        abort ();
    }

    if (got_c != want_c || ! refmpn_equal_anynail (got, want, size))
    {
        printf ("Wrong at %s i=%d size=%ld\n", name, i, size);
        mpn_trace ("   src", src,  size);
        mpn_trace ("     n", &n,   (mp_size_t) 1);
        mpn_trace ("   got", got,  size);
        mpn_trace ("  want", want, size);
        mpn_trace (" got c", &got_c,  (mp_size_t) 1);
        mpn_trace ("want c", &want_c, (mp_size_t) 1);
        abort ();
    }
}
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();
        }
    }
}
Ejemplo n.º 10
0
/* Exercise various 2^n values, with various exponents and positive and
   negative.  */
void
check_onebit (void)
{
  static const int bit_table[] = {
    0, 1, 2, 3,
    GMP_NUMB_BITS - 2, GMP_NUMB_BITS - 1,
    GMP_NUMB_BITS,
    GMP_NUMB_BITS + 1, GMP_NUMB_BITS + 2,
    2 * GMP_NUMB_BITS - 2, 2 * GMP_NUMB_BITS - 1,
    2 * GMP_NUMB_BITS,
    2 * GMP_NUMB_BITS + 1, 2 * GMP_NUMB_BITS + 2,
    3 * GMP_NUMB_BITS - 2, 3 * GMP_NUMB_BITS - 1,
    3 * GMP_NUMB_BITS,
    3 * GMP_NUMB_BITS + 1, 3 * GMP_NUMB_BITS + 2,
    4 * GMP_NUMB_BITS - 2, 4 * GMP_NUMB_BITS - 1,
    4 * GMP_NUMB_BITS,
    4 * GMP_NUMB_BITS + 1, 4 * GMP_NUMB_BITS + 2,
    5 * GMP_NUMB_BITS - 2, 5 * GMP_NUMB_BITS - 1,
    5 * GMP_NUMB_BITS,
    5 * GMP_NUMB_BITS + 1, 5 * GMP_NUMB_BITS + 2,
    6 * GMP_NUMB_BITS - 2, 6 * GMP_NUMB_BITS - 1,
    6 * GMP_NUMB_BITS,
    6 * GMP_NUMB_BITS + 1, 6 * GMP_NUMB_BITS + 2,
  };
  static const int exp_table[] = {
    0, -100, -10, -1, 1, 10, 100,
  };

  /* FIXME: It'd be better to base this on the float format. */
  int     limit = 511;

  int        bit_i, exp_i, i;
  double     got, want;
  mp_size_t  nsize, sign;
  long       bit, exp, want_bit;
  mp_limb_t  np[20];

  for (bit_i = 0; bit_i < numberof (bit_table); bit_i++)
    {
      bit = bit_table[bit_i];

      nsize = BITS_TO_LIMBS (bit+1);
      refmpn_zero (np, nsize);
      np[bit/GMP_NUMB_BITS] = CNST_LIMB(1) << (bit % GMP_NUMB_BITS);

      for (exp_i = 0; exp_i < numberof (exp_table); exp_i++)
        {
          exp = exp_table[exp_i];

          want_bit = bit + exp;
          if (want_bit > limit || want_bit < -limit)
            continue;

          want = 1.0;
          for (i = 0; i < want_bit; i++)
            want *= 2.0;
          for (i = 0; i > want_bit; i--)
            want *= 0.5;

          for (sign = 0; sign >= -1; sign--, want = -want)
            {
              got = mpn_get_d (np, nsize, sign, exp);
              if (got != want)
                {
                  printf    ("mpn_get_d wrong on 2^n\n");
                  printf    ("   bit      %ld\n", bit);
                  printf    ("   exp      %ld\n", exp);
                  printf    ("   want_bit %ld\n", want_bit);
                  printf    ("   sign     %ld\n", (long) sign);
                  mpn_trace ("   n        ", np, nsize);
                  printf    ("   nsize    %ld\n", (long) nsize);
                  d_trace   ("   want     ", want);
                  d_trace   ("   got      ", got);
                  abort();
                }
            }
        }
    }
}
Ejemplo n.º 11
0
void
check_rand (void)
{
  gmp_randstate_t rands;
  int            rep, i;
  unsigned long  mant_bits;
  long           exp, exp_min, exp_max;
  double         got, want, d;
  mp_size_t      nalloc, nsize, sign;
  mp_limb_t      nhigh_mask;
  mp_ptr         np;
  
  gmp_randinit_default(rands);
  
  mant_bits = tests_dbl_mant_bits ();
  if (mant_bits == 0)
    return;

  /* Allow for vax D format with exponent 127 to -128 only.
     FIXME: Do something to probe for a valid exponent range.  */
  exp_min = -100 - mant_bits;
  exp_max =  100 - mant_bits;

  /* space for mant_bits */
  nalloc = BITS_TO_LIMBS (mant_bits);
  np = refmpn_malloc_limbs (nalloc);
  nhigh_mask = MP_LIMB_T_MAX
    >> (GMP_NAIL_BITS + nalloc * GMP_NUMB_BITS - mant_bits);

  for (rep = 0; rep < 200; rep++)
    {
      /* random exp_min to exp_max, inclusive */
      exp = exp_min + (long) gmp_urandomm_ui (rands, exp_max - exp_min + 1);

      /* mant_bits worth of random at np */
      if (rep & 1)
        mpn_randomb (np, rands, nalloc);
      else
        mpn_rrandom (np, rands,nalloc);
      nsize = nalloc;
      np[nsize-1] &= nhigh_mask;
      MPN_NORMALIZE (np, nsize);
      if (nsize == 0)
        continue;

      sign = (mp_size_t) gmp_urandomb_ui (rands, 1L) - 1;

      /* want = {np,nsize}, converting one bit at a time */
      want = 0.0;
      for (i = 0, d = 1.0; i < mant_bits; i++, d *= 2.0)
        if (np[i/GMP_NUMB_BITS] & (CNST_LIMB(1) << (i%GMP_NUMB_BITS)))
          want += d;
      if (sign < 0)
        want = -want;

      /* want = want * 2^exp */
      for (i = 0; i < exp; i++)
        want *= 2.0;
      for (i = 0; i > exp; i--)
        want *= 0.5;

      got = mpn_get_d (np, nsize, sign, exp);

      if (got != want)
        {
          printf    ("mpn_get_d wrong on random data\n");
          printf    ("   sign     %ld\n", (long) sign);
          mpn_trace ("   n        ", np, nsize);
          printf    ("   nsize    %ld\n", (long) nsize);
          printf    ("   exp      %ld\n", exp);
          d_trace   ("   want     ", want);
          d_trace   ("   got      ", got);
          abort();
        }
    }

  free (np);
  gmp_randclear(rands);
}
void
check_data (void)
{
  static const struct {
    mp_limb_t  n[1];
    mp_size_t  nsize;
    mp_limb_t  d;
    mp_size_t  qxn;
    mp_limb_t  want_q[5];
    mp_limb_t  want_r;
  } data[] = {
    { { 0 }, 1, 1, 0,
      { 0 }, 0},

    { { 5 }, 1, 2, 0,
      { 2 }, 1},

#if GMP_NUMB_BITS == 32
    { { 0x3C }, 1, 0xF2, 1,
      { 0x3F789854, 0 }, 0x98 },
#endif

#if GMP_NUMB_BITS == 64
    { { 0x3C }, 1, 0xF2, 1,
      { CNST_LIMB(0x3F789854A0CB1B81), 0 }, 0x0E },

    /* This case exposed some wrong code generated by SGI cc on mips64 irix
       6.5 with -n32 -O2, in the fractional loop for normalized divisor
       using udiv_qrnnd_preinv.  A test "x>al" in one of the sub_ddmmss
       expansions came out wrong, leading to an incorrect quotient.  */
    { { CNST_LIMB(0x3C00000000000000) }, 1, CNST_LIMB(0xF200000000000000), 1,
      { CNST_LIMB(0x3F789854A0CB1B81), 0 }, CNST_LIMB(0x0E00000000000000) },
#endif
  };

  mp_limb_t  dinv, got_r, got_q[numberof(data[0].want_q)];
  mp_size_t  qsize;
  int        i, shift;

  for (i = 0; i < numberof (data); i++)
    {
      qsize = data[i].nsize + data[i].qxn;
      ASSERT_ALWAYS (qsize <= numberof (got_q));

      got_r = mpn_divrem_1 (got_q, data[i].qxn, data[i].n, data[i].nsize,
                            data[i].d);
      if (got_r != data[i].want_r
          || refmpn_cmp (got_q, data[i].want_q, qsize) != 0)
        {
          printf        ("mpn_divrem_1 wrong at data[%d]\n", i);
        bad:
          mpn_trace     ("  n", data[i].n, data[i].nsize);
          printf        ("  nsize=%ld\n", (long) data[i].nsize);
          mp_limb_trace ("  d", data[i].d);
          printf        ("  qxn=%ld\n", (long) data[i].qxn);
          mpn_trace     ("  want q", data[i].want_q, qsize);
          mpn_trace     ("  got  q", got_q, qsize);
          mp_limb_trace ("  want r", data[i].want_r);
          mp_limb_trace ("  got  r", got_r);
          abort ();
        }

      /* test if available */
#if USE_PREINV_DIVREM_1 || HAVE_NATIVE_mpn_preinv_divrem_1
      shift = refmpn_count_leading_zeros (data[i].d);
      dinv = refmpn_invert_limb (data[i].d << shift);
      got_r = mpn_preinv_divrem_1 (got_q, data[i].qxn,
                                   data[i].n, data[i].nsize,
                                   data[i].d, dinv, shift);
      if (got_r != data[i].want_r
          || refmpn_cmp (got_q, data[i].want_q, qsize) != 0)
        {
          printf        ("mpn_preinv divrem_1 wrong at data[%d]\n", i);
          printf        ("  shift=%d\n", shift);
          mp_limb_trace ("  dinv", dinv);
          goto bad;
        }
#endif
    }
}