Beispiel #1
0
void
check_rand (void)
{
  unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
  gmp_randstate_t  rands;
  mpf_t              got, u;
  unsigned long      prec, v;
  int                i;

  /* The nails code in mpf_mul_ui currently isn't exact, so suppress these
     tests for now.  */
  if (BITS_PER_UI > GMP_NUMB_BITS)
    return;

  mpf_init (got);
  mpf_init (u);
  gmp_randinit_default(rands);

  for (i = 0; i < 200; i++)
    {
      /* got precision */
      prec = min_prec + gmp_urandomm_ui (rands, 15L);
      refmpf_set_prec_limbs (got, prec);

      /* u precision */
      prec = min_prec + gmp_urandomm_ui (rands, 15L);
      refmpf_set_prec_limbs (u, prec);

      /* u, possibly negative */
      mpf_rrandomb (u, rands, PREC(u), (mp_exp_t) 20);
      if (gmp_urandomb_ui (rands, 1L))
        mpf_neg (u, u);

      /* v, 0 to BITS_PER_ULONG bits (inclusive) */
      prec = gmp_urandomm_ui (rands, BITS_PER_ULONG+1);
      v = gmp_urandomb_ui (rands, prec);

      if ((i % 2) == 0)
        {
          /* separate */
          mpf_mul_ui (got, u, v);
          check_one ("separate", got, u, v);
        }
      else
        {
          /* overlap */
          prec = refmpf_set_overlap (got, u);
          mpf_mul_ui (got, got, v);
          check_one ("overlap src==dst", got, u, v);

          mpf_set_prec_raw (got, prec);
        }
    }

  mpf_clear (got);
  mpf_clear (u);
  gmp_randclear(rands);
}
Beispiel #2
0
int
main (int argc, char **argv)
{
  mp_ptr ap, bp, rp, refp;
  gmp_randstate_ptr rands;
  int test;
  TMP_DECL;
  TMP_MARK;

  tests_start ();
  rands = RANDS;

  ap = TMP_ALLOC_LIMBS (MAX_N);
  bp = TMP_ALLOC_LIMBS (MAX_N);
  rp = TMP_ALLOC_LIMBS (MAX_N + 2);
  refp = TMP_ALLOC_LIMBS (MAX_N + 2);

  for (test = 0; test < COUNT; test++)
    {
      mp_size_t an, bn, rn;
      unsigned size_log;

      size_log = 1 + gmp_urandomm_ui (rands, SIZE_LOG);
      an = 1 + gmp_urandomm_ui(rands, 1L << size_log);

      size_log = 1 + gmp_urandomm_ui (rands, SIZE_LOG);
      bn = 1 + gmp_urandomm_ui(rands, 1L << size_log);

      /* Make sure an >= bn */
      if (an < bn)
	MP_SIZE_T_SWAP (an, bn);

      mpn_random2 (ap, an);
      mpn_random2 (bp, bn);

      refmpn_mulmid (refp, ap, an, bp, bn);
      mpn_mulmid (rp, ap, an, bp, bn);

      rn = an + 3 - bn;
      if (mpn_cmp (refp, rp, rn))
	{
	  printf ("ERROR in test %d, an = %d, bn = %d, rn = %d\n",
		  test, (int) an, (int) bn, (int) rn);
	  printf("a: "); mpn_dump (ap, an);
	  printf("b: "); mpn_dump (bp, bn);
	  printf("r:   "); mpn_dump (rp, rn);
	  printf("ref: "); mpn_dump (refp, rn);

	  abort();
	}
    }
  TMP_FREE;
  tests_end ();
  return 0;
}
Beispiel #3
0
void
check_rand (void)
{
  unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
  gmp_randstate_t  rands;
  unsigned long  prec;
  mpf_t  got;
  mpq_t  q;
  int    i;

  mpf_init (got);
  mpq_init (q);
  gmp_randinit_default(rands);

  for (i = 0; i < 400; i++)
    {
      /* result precision */
      prec = min_prec + gmp_urandomm_ui (rands, 20L);
      refmpf_set_prec_limbs (got, prec);

      /* num */
      prec = gmp_urandomm_ui (rands, 20L * GMP_NUMB_BITS);
      mpz_rrandomb (mpq_numref(q), rands, prec);

      /* possibly negative num */
      if (gmp_urandomb_ui (rands, 1L))
        mpz_neg (mpq_numref(q), mpq_numref(q));

      /* den, non-zero */
      do {
        prec = gmp_urandomm_ui (rands, 20L * GMP_NUMB_BITS);
        mpz_rrandomb (mpq_denref(q), rands, prec);
      } while (mpz_sgn (mpq_denref(q)) <= 0);

      check_one (got, q);
    }

  mpf_clear (got);
  mpq_clear (q);
  gmp_randclear(rands);
}
Beispiel #4
0
int
main (int argc, char **argv)
{
  gmp_randstate_ptr rands;
  int i;
  unsigned a_bits;
  unsigned b_bits;
  mpz_t a;
  mpz_t b;

  tests_start ();
  rands = RANDS;
  mpz_init (a);
  mpz_init (b);

  for (i = 0; i < 300; i++)
    {
      mp_size_t asize;
      a_bits = 1 + gmp_urandomm_ui (rands, 1000);
      b_bits = 1 + gmp_urandomm_ui (rands, GMP_NUMB_BITS);

      mpz_rrandomb (a, rands, a_bits);
      mpz_rrandomb (b, rands, b_bits);

      asize = SIZ(a);
      if (!asize)
	asize = 1;
      if (mpz_sgn (b) == 0)
	mpz_set_ui (b, 1);

      check_one (PTR(a), asize, PTR(b)[0]);
    }

  mpz_clear (a);
  mpz_clear (b);

  tests_end ();
  return 0;
}
Beispiel #5
0
/* Exercise calls mpf(x,x,x) */
void
check_reuse_three (void)
{
  unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
  gmp_randstate_ptr  rands = RANDS;
  unsigned long  result_prec, input_prec, set_prec;
  mpf_t  got;
  int    i;

  mpf_init (got);

  for (i = 0; i < 8; i++)
    {
      result_prec = min_prec + gmp_urandomm_ui (rands, 15L);
      input_prec = min_prec + gmp_urandomm_ui (rands, 15L);

      set_prec = MAX (result_prec, input_prec);
      refmpf_set_prec_limbs (got, set_prec);

      /* input, non-zero, possibly negative */
      PREC(got) = input_prec;
      do {
        mpf_random2 (got, input_prec, (mp_exp_t) 20);
      } while (SIZ(got) == 0);
      if (gmp_urandomb_ui (rands, 1L))
        mpf_neg (got, got);

      PREC(got) = result_prec;

      mpf_div (got, got, got);

      /* expect exactly 1.0 always */
      ASSERT_ALWAYS (mpf_cmp_ui (got, 1L) == 0);

      PREC(got) = set_prec;
    }

  mpf_clear (got);
}
Beispiel #6
0
template <class FT> void BKZReduction<FT>::rerandomize_block(int min_row, int max_row, int density)
{
    if (max_row - min_row < 2)
        return;

    // 1. permute rows
    size_t niter = 4 * (max_row - min_row);  // some guestimate

    for (size_t i = 0; i < niter; ++i)
    {
        size_t a = gmp_urandomm_ui(RandGen::get_gmp_state(), max_row - min_row - 1) + min_row;
        size_t b = a;
        while (b == a)
        {
            b = gmp_urandomm_ui(RandGen::get_gmp_state(), max_row - min_row - 1) + min_row;
        }
        m.move_row(b, a);
    }

    // 2. triangular transformation matrix with coefficients in -1,0,1
    m.row_op_begin(min_row, max_row);
    FT x;
    for (long a = min_row; a < max_row - 2; ++a)
    {
        for (long i = 0; i < density; i++)
        {
            size_t b = gmp_urandomm_ui(RandGen::get_gmp_state(), max_row - (a + 1) - 1) + a + 1;
            if (gmp_urandomm_ui(RandGen::get_gmp_state(), 2))
                m.row_add(a, b);
            else
                m.row_sub(a, b);
        }
    }
    m.row_op_end(min_row, max_row);

    return;
}
Beispiel #7
0
static void
check_rand (void)
{
  gmp_randstate_ptr rands = RANDS;
  int     i;
  mpz_t   z;
  double  got;
  long    got_exp;
  unsigned long  bits;

  mpz_init (z);

  for (i = 0; i < 200; i++)
    {
      bits = gmp_urandomm_ui (rands, 512L);
      mpz_urandomb (z, rands, bits);

      got = mpz_get_d_2exp (&got_exp, z);
      if (mpz_sgn (z) == 0)
        continue;
      bits = mpz_sizeinbase (z, 2);

      if (got < 0.5 || got >= 1.0)
        {
          printf    ("mpz_get_d_2exp out of range, expect 0.5 <= got < 1.0\n");
          mpz_trace ("   z    ", z);
          d_trace   ("   got  ", got);
          printf    ("   got exp  %ld\n", got_exp);
          abort();
        }

      /* FIXME: If mpz_get_d_2exp rounds upwards we might have got_exp ==
         bits+1, so leave this test disabled until we decide if that's what
         should happen, or not.  */
#if 0
      if (got_exp != bits)
        {
          printf    ("mpz_get_d_2exp wrong exponent\n", i);
          mpz_trace ("   z    ", z);
          d_trace   ("   bits ", bits);
          d_trace   ("   got  ", got);
          printf    ("   got exp  %ld\n", got_exp);
          abort();
        }
#endif
    }
  mpz_clear (z);
}
Beispiel #8
0
/* Expect numbers generated by rstate to obey the limit requested. */
void
check_one (const char *name, gmp_randstate_ptr rstate)
{
  static const unsigned long  n_table[] = {
    1, 2, 3, 4, 5, 6, 7, 8,
    123, 456, 789,

    255, 256, 257,
    1023, 1024, 1025,
    32767, 32768, 32769,

    ULONG_MAX/2-2, ULONG_MAX/2-1, ULONG_MAX/2, ULONG_MAX/2+1, ULONG_MAX/2+2,

    ULONG_MAX-2, ULONG_MAX-1, ULONG_MAX,
  };

  unsigned long  got, n;
  int    i, j;

  for (i = 0; i < numberof (n_table); i++)
    {
      n = n_table[i];

      for (j = 0; j < 5; j++)
        {
          got = gmp_urandomm_ui (rstate, n);
          if (got >= n)
            {
              printf ("Return value out of range:\n");
              printf ("  algorithm: %s\n", name);
              printf ("  n:     %#lx\n", n);
              printf ("  got:   %#lx\n", got);
              abort ();
            }
        }
    }
}
Beispiel #9
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);
}
Beispiel #10
0
void
mpz_errandomb (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits)
{
  mpz_rrandomb (rop, rstate, gmp_urandomm_ui (rstate, nbits));
}
Beispiel #11
0
int
main (int argc, char **argv)
{
  gmp_randstate_ptr rands;

  mp_ptr ap, rp, pp, scratch;
  int count = COUNT;
  unsigned i;
  TMP_DECL;

  TMP_MARK;

  if (argc > 1)
    {
      char *end;
      count = strtol (argv[1], &end, 0);
      if (*end || count <= 0)
	{
	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
	  return 1;
	}
    }

  tests_start ();
  rands = RANDS;

  ap = TMP_ALLOC_LIMBS (MAX_LIMBS);
  rp = TMP_ALLOC_LIMBS (MAX_LIMBS);
  pp = TMP_ALLOC_LIMBS (MAX_LIMBS);
  scratch = TMP_ALLOC_LIMBS (3*MAX_LIMBS); /* For mpn_powlo */

  for (i = 0; i < count; i++)
    {
      mp_size_t n;
      mp_limb_t k;
      int c;

      n = 1 + gmp_urandomm_ui (rands, MAX_LIMBS);

      if (i & 1)
	mpn_random2 (ap, n);
      else
	mpn_random (ap, n);

      ap[0] |= 1;

      if (i < 100)
	k = 3 + 2*i;
      else
	{
	  mpn_random (&k, 1);
	  if (k < 3)
	    k = 3;
	  else
	    k |= 1;
	}
      mpn_broot (rp, ap, n, k);
      mpn_powlo (pp, rp, &k, 1, n, scratch);

      MPN_CMP (c, ap, pp, n);
      if (c != 0)
	{
	  gmp_fprintf (stderr,
		       "mpn_broot returned bad result: %u limbs\n",
		       (unsigned) n);
	  gmp_fprintf (stderr, "k   = %Mx\n", k);
	  gmp_fprintf (stderr, "a   = %Nx\n", ap, n);
	  gmp_fprintf (stderr, "r   = %Nx\n", rp, n);
	  gmp_fprintf (stderr, "r^n = %Nx\n", pp, n);
	  abort ();
	}
    }
  TMP_FREE;
  tests_end ();
  return 0;
}
Beispiel #12
0
int
main (int argc, char **argv)
{
  mp_ptr ap, bp, refp, pp, scratch;
  int count = COUNT;
  int test;
  gmp_randstate_ptr rands;
  TMP_DECL;
  TMP_MARK;

  if (argc > 1)
    {
      char *end;
      count = strtol (argv[1], &end, 0);
      if (*end || count <= 0)
	{
	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
	  return 1;
	}
    }

  tests_start ();
  rands = RANDS;

#define mpn_mullo_itch(n) (0)

  ap = TMP_ALLOC_LIMBS (MAX_N);
  bp = TMP_ALLOC_LIMBS (MAX_N);
  refp = TMP_ALLOC_LIMBS (MAX_N * 2);
  pp = 1+TMP_ALLOC_LIMBS (MAX_N + 2);
  scratch
    = 1+TMP_ALLOC_LIMBS (mpn_mullo_itch (MAX_N) + 2);

  for (test = 0; test < count; test++)
    {
      unsigned size_min;
      unsigned size_range;
      mp_size_t n;
      mp_size_t itch;
      mp_limb_t p_before, p_after, s_before, s_after;

      for (size_min = 1; (1L << size_min) < MIN_N; size_min++)
	;

      /* We generate an in the MIN_N <= n <= (1 << size_range). */
      size_range = size_min
	+ gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min);

      n = MIN_N
	+ gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_N);

      mpn_random2 (ap, n);
      mpn_random2 (bp, n);
      mpn_random2 (pp-1, n + 2);
      p_before = pp[-1];
      p_after = pp[n];

      itch = mpn_mullo_itch (n);
      ASSERT_ALWAYS (itch <= mpn_mullo_itch (MAX_N));
      mpn_random2 (scratch-1, itch+2);
      s_before = scratch[-1];
      s_after = scratch[itch];

      mpn_mullo_n (pp, ap, bp, n);
      mpn_mul_n (refp, ap, bp, n);
      if (pp[-1] != p_before || pp[n] != p_after
	  || scratch[-1] != s_before || scratch[itch] != s_after
	  || mpn_cmp (refp, pp, n) != 0)
	{
	  printf ("ERROR in test %d, n = %d",
		  test, (int) n);
	  if (pp[-1] != p_before)
	    {
	      printf ("before pp:"); mpn_dump (pp -1, 1);
	      printf ("keep:   "); mpn_dump (&p_before, 1);
	    }
	  if (pp[n] != p_after)
	    {
	      printf ("after pp:"); mpn_dump (pp + n, 1);
	      printf ("keep:   "); mpn_dump (&p_after, 1);
	    }
	  if (scratch[-1] != s_before)
	    {
	      printf ("before scratch:"); mpn_dump (scratch-1, 1);
	      printf ("keep:   "); mpn_dump (&s_before, 1);
	    }
	  if (scratch[itch] != s_after)
	    {
	      printf ("after scratch:"); mpn_dump (scratch + itch, 1);
	      printf ("keep:   "); mpn_dump (&s_after, 1);
	    }
	  mpn_dump (ap, n);
	  mpn_dump (bp, n);
	  mpn_dump (pp, n);
	  mpn_dump (refp, n);

	  abort();
	}
    }
  TMP_FREE;
  tests_end ();
  return 0;
}
Beispiel #13
0
int
main (int argc, char **argv)
{
  mp_ptr ip, dp, scratch;
  int count = COUNT;
  int test;
  gmp_randstate_ptr rands;
  TMP_DECL;
  TMP_MARK;

  if (argc > 1)
    {
      char *end;
      count = strtol (argv[1], &end, 0);
      if (*end || count <= 0)
	{
	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
	  return 1;
	}
    }

  tests_start ();
  rands = RANDS;

  dp = TMP_ALLOC_LIMBS (MAX_N);
  ip = 1+TMP_ALLOC_LIMBS (MAX_N + 2);
  scratch
    = 1+TMP_ALLOC_LIMBS (mpn_invert_itch (MAX_N) + 2);

  for (test = 0; test < count; test++)
    {
      unsigned size_min;
      unsigned size_range;
      mp_size_t n;
      mp_size_t itch;
      mp_limb_t i_before, i_after, s_before, s_after;

      for (size_min = 1; (1L << size_min) < MIN_N; size_min++)
	;

      /* We generate an in the MIN_N <= n <= (1 << size_range). */
      size_range = size_min
	+ gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min);

      n = MIN_N
	+ gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_N);

      mpn_random2 (dp, n);

      mpn_random2 (ip-1, n + 2);
      i_before = ip[-1];
      i_after = ip[n];

      itch = mpn_invert_itch (n);
      ASSERT_ALWAYS (itch <= mpn_invert_itch (MAX_N));
      mpn_random2 (scratch-1, itch+2);
      s_before = scratch[-1];
      s_after = scratch[itch];

      dp[n-1] |= GMP_NUMB_HIGHBIT;
      mpn_invert (ip, dp, n, scratch);
      if (ip[-1] != i_before || ip[n] != i_after
	  || scratch[-1] != s_before || scratch[itch] != s_after
	  || ! invert_valid(ip, dp, n))
	{
	  printf ("ERROR in test %d, n = %d\n",
		  test, (int) n);
	  if (ip[-1] != i_before)
	    {
	      printf ("before ip:"); mpn_dump (ip -1, 1);
	      printf ("keep:   "); mpn_dump (&i_before, 1);
	    }
	  if (ip[n] != i_after)
	    {
	      printf ("after ip:"); mpn_dump (ip + n, 1);
	      printf ("keep:   "); mpn_dump (&i_after, 1);
	    }
	  if (scratch[-1] != s_before)
	    {
	      printf ("before scratch:"); mpn_dump (scratch-1, 1);
	      printf ("keep:   "); mpn_dump (&s_before, 1);
	    }
	  if (scratch[itch] != s_after)
	    {
	      printf ("after scratch:"); mpn_dump (scratch + itch, 1);
	      printf ("keep:   "); mpn_dump (&s_after, 1);
	    }
	  mpn_dump (dp, n);
	  mpn_dump (ip, n);

	  abort();
	}
    }
  TMP_FREE;
  tests_end ();
  return 0;
}
Beispiel #14
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);
}
Beispiel #15
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);
}
Beispiel #16
0
void
check_rand (void)
{
  unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
  gmp_randstate_ptr  rands = RANDS;
  unsigned long  prec;
  mpf_t  got, u, v;
  int    i;

  mpf_init (got);
  mpf_init (u);
  mpf_init (v);

  /* separate */
  for (i = 0; i < 100; i++)
    {
      /* got precision */
      prec = min_prec + gmp_urandomm_ui (rands, 15L);
      refmpf_set_prec_limbs (got, prec);

      /* u */
      prec = min_prec + gmp_urandomm_ui (rands, 15L);
      refmpf_set_prec_limbs (u, prec);
      do {
        mpf_random2 (u, PREC(u), (mp_exp_t) 20);
      } while (SIZ(u) == 0);
      if (gmp_urandomb_ui (rands, 1L))
        mpf_neg (u, u);

      /* v */
      prec = min_prec + gmp_urandomm_ui (rands, 15L);
      refmpf_set_prec_limbs (v, prec);
      do {
        mpf_random2 (v, PREC(v), (mp_exp_t) 20);
      } while (SIZ(v) == 0);
      if (gmp_urandomb_ui (rands, 1L))
        mpf_neg (v, v);

      switch (i % 3) {
      case 0:
        mpf_div (got, u, v);
        check_one ("separate", got, u, v);
        break;
      case 1:
        prec = refmpf_set_overlap (got, u);
        mpf_div (got, got, v);
        check_one ("dst == u", got, u, v);
        mpf_set_prec_raw (got, prec);
        break;
      case 2:
        prec = refmpf_set_overlap (got, v);
        mpf_div (got, u, got);
        check_one ("dst == v", got, u, v);
        mpf_set_prec_raw (got, prec);
        break;
      }
    }

  mpf_clear (got);
  mpf_clear (u);
  mpf_clear (v);
}
static void
check_set_str (mpfr_exp_t exp_max)
{
  mpc_t expected;
  mpc_t got;
  char *str;

  mpfr_prec_t prec;
  mpfr_exp_t exp_min;
  int base;

  mpc_init2 (expected, 1024);
  mpc_init2 (got, 1024);

  exp_min = mpfr_get_emin ();
  if (exp_max <= 0)
    exp_max = mpfr_get_emax ();
  else if (exp_max > mpfr_get_emax ())
    exp_max = mpfr_get_emax();
  if (-exp_max > exp_min)
    exp_min = - exp_max;

  for (prec = 2; prec < 1024; prec += 7)
    {
      mpc_set_prec (got, prec);
      mpc_set_prec (expected, prec);

      base = 2 + (int) gmp_urandomm_ui (rands, 35);
         /* uses external variable rands from random.c */

      mpfr_set_nan (MPC_RE (expected));
      mpfr_set_inf (MPC_IM (expected), prec % 2 - 1);
      str = mpc_get_str (base, 0, expected, MPC_RNDNN);
      if (mpfr_nan_p (MPC_RE (got)) == 0
          || mpfr_cmp (MPC_IM (got), MPC_IM (expected)) != 0)
        {
          printf ("Error: mpc_set_str o mpc_get_str != Id\n"
                  "in base %u with str=\"%s\"\n", base, str);
          MPC_OUT (expected);
          printf ("     ");
          MPC_OUT (got);
          exit (1);
        }
      mpc_free_str (str);

      test_default_random (expected, exp_min, exp_max, 128, 25);
      str = mpc_get_str (base, 0, expected, MPC_RNDNN);
      if (mpc_set_str (got, str, base, MPC_RNDNN) == -1
          || mpc_cmp (got, expected) != 0)
        {
          printf ("Error: mpc_set_str o mpc_get_str != Id\n"
                  "in base %u with str=\"%s\"\n", base, str);
          MPC_OUT (expected);
          printf ("     ");
          MPC_OUT (got);
          exit (1);
        }
      mpc_free_str (str);
    }

#ifdef HAVE_SETLOCALE
  {
    /* Check with ',' as a decimal point */
    char *old_locale;

    old_locale = setlocale (LC_ALL, "de_DE");
    if (old_locale != NULL)
      {
        str = mpc_get_str (10, 0, expected, MPC_RNDNN);
        if (mpc_set_str (got, str, 10, MPC_RNDNN) == -1
            || mpc_cmp (got, expected) != 0)
          {
            printf ("Error: mpc_set_str o mpc_get_str != Id\n"
                    "with str=\"%s\"\n", str);
            MPC_OUT (expected);
            printf ("     ");
            MPC_OUT (got);
            exit (1);
          }
        mpc_free_str (str);

        setlocale (LC_ALL, old_locale);
      }
  }
#endif /* HAVE_SETLOCALE */

  /* the real part has a zero exponent in base ten (fixed in r439) */
  mpc_set_prec (expected, 37);
  mpc_set_prec (got, 37);
  mpc_set_str (expected, "921FC04EDp-35  ", 16, GMP_RNDN);
  str = mpc_get_str (10, 0, expected, MPC_RNDNN);
  if (mpc_set_str (got, str, 10, MPC_RNDNN) == -1
      || mpc_cmp (got, expected) != 0)
    {
      printf ("Error: mpc_set_str o mpc_get_str != Id\n"
              "with str=\"%s\"\n", str);
      MPC_OUT (expected);
      printf ("     ");
      MPC_OUT (got);
      exit (1);
    }
  mpc_free_str (str);

  str = mpc_get_str (1, 0, expected, MPC_RNDNN);
  if (str != NULL)
    {
      printf ("Error: mpc_get_str with base==1 should fail\n");
      exit (1);
    }

  mpc_clear (expected);
  mpc_clear (got);
}