Ejemplo n.º 1
0
size_t
mpn_sizeinbase (mp_srcptr xp, mp_size_t xsize, int base)
{
  int lb_base, cnt;
  mp_size_t totbits;

  ASSERT (xsize >= 0);
  ASSERT (base >= 2);
  ASSERT (base < numberof (__mp_bases));

  /* Special case for X == 0.  */
  if (xsize == 0)
    return 1;

  /* Calculate the total number of significant bits of X.  */
  count_leading_zeros (cnt, xp[xsize-1]);
  totbits = xsize * BITS_PER_MP_LIMB - cnt;

  if (POW2_P (base))
    {
      /* Special case for powers of 2, giving exact result.  */
      lb_base = __mp_bases[base].big_base;
      return (totbits + lb_base - 1) / lb_base;
    }
  else
    return (size_t) (totbits * __mp_bases[base].chars_per_bit_exactly) + 1;
}
Ejemplo n.º 2
0
Archivo: misc.c Proyecto: Cl3Kener/gmp
/* Whether the absolute value of z is a power of 2. */
int
mpz_pow2abs_p (mpz_srcptr z)
{
  mp_size_t  size, i;
  mp_srcptr  ptr;

  size = SIZ (z);
  if (size == 0)
    return 0;  /* zero is not a power of 2 */
  size = ABS (size);

  ptr = PTR (z);
  for (i = 0; i < size-1; i++)
    if (ptr[i] != 0)
      return 0;  /* non-zero low limb means not a power of 2 */

  return POW2_P (ptr[i]);  /* high limb power of 2 */
}
Ejemplo n.º 3
0
void
table (int limb_bits, int nail_bits)
{
  int  numb_bits = limb_bits - nail_bits;
  int  base;

  printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n");
  printf ("\n");
  printf ("#include \"mpir.h\"\n");
  printf ("#include \"gmp-impl.h\"\n");
  printf ("\n");
  printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
  printf ("Error, error, this data is for %d bits\n", numb_bits);
  printf ("#endif\n");
  printf ("\n");
  puts ("const struct bases mp_bases[257] =\n{");
  puts ("  /*   0 */ { 0, 0.0, 0 },");
  puts ("  /*   1 */ { 0, 1e37, 0 },");
  for (base = 2; base <= 256; base++)
    {
      generate (limb_bits, nail_bits, base);

      printf ("  /* %3u */ { ", base);
      if (POW2_P (base))
	{
          printf ("%u, %.16f, 0x%x },\n",
                  chars_per_limb, chars_per_bit_exactly, ulog2 (base) - 1);
	}
      else
	{
          printf ("%u, %.16f, CNST_LIMB(0x",
                  chars_per_limb, chars_per_bit_exactly);
	  mpz_out_str (stdout, 16, big_base);
          printf ("), CNST_LIMB(0x");
	  mpz_out_str (stdout, 16, big_base_inverted);
          printf (") },\n");
	}
    }

  puts ("};");
}
Ejemplo n.º 4
0
unsigned long
gmp_urandomm_ui (gmp_randstate_ptr rstate, unsigned long n)
{
  mp_limb_t      a[LIMBS_PER_ULONG];
  unsigned long  ret, bits, leading;
  int            i;

  if (UNLIKELY (n == 0))
    DIVIDE_BY_ZERO;

  /* start with zeros, since if bits==0 then _gmp_rand will store nothing at
     all (bits==0 arises when n==1), or if bits <= GMP_NUMB_BITS then it
     will store only a[0].  */
  a[0] = 0;
#if LIMBS_PER_ULONG > 1
  a[1] = 0;
#endif

  count_leading_zeros (leading, (mp_limb_t) n);
  bits = GMP_LIMB_BITS - leading - (POW2_P(n) != 0);

  for (i = 0; i < MAX_URANDOMM_ITER; i++)
    {
      _gmp_rand (a, rstate, bits);
#if LIMBS_PER_ULONG == 1
      ret = a[0];
#else
      ret = a[0] | (a[1] << GMP_NUMB_BITS);
#endif
      if (LIKELY (ret < n))   /* usually one iteration suffices */
        goto done;
    }

  /* Too many iterations, there must be something degenerate about the
     rstate algorithm.  Return r%n.  */
  ret -= n;
  ASSERT (ret < n);

 done:
  return ret;
}
Ejemplo n.º 5
0
int
main (int argc, char *argv[])
{
  mp_limb_t  want_bb, want_bb_inv;
  int        base, want_chars_per_limb;

  want_chars_per_limb = refmpn_chars_per_limb (10);
  if (MP_BASES_CHARS_PER_LIMB_10 != want_chars_per_limb)
    {
      printf ("MP_BASES_CHARS_PER_LIMB_10 wrong\n");
      abort ();
    }

  want_bb = refmpn_big_base (10);
  if (MP_BASES_BIG_BASE_10 != want_bb)
    {
      printf ("MP_BASES_BIG_BASE_10 wrong\n");
      abort ();
    }

  want_bb_inv = refmpn_invert_limb
    (want_bb << refmpn_count_leading_zeros (want_bb));
  if (MP_BASES_BIG_BASE_INVERTED_10 != want_bb_inv)
    {
      printf ("MP_BASES_BIG_BASE_INVERTED_10 wrong\n");
      abort ();
    }

  if (MP_BASES_NORMALIZATION_STEPS_10
      != refmpn_count_leading_zeros (MP_BASES_BIG_BASE_10))
    {
      printf ("MP_BASES_NORMALIZATION_STEPS_10 wrong\n");
      abort ();
    }

  for (base = 2; base < numberof (mp_bases); base++)
    {
      want_chars_per_limb = refmpn_chars_per_limb (base);
      if (mp_bases[base].chars_per_limb != want_chars_per_limb)
        {
          printf ("mp_bases[%d].chars_per_limb wrong\n", base);
          printf ("  got  %d\n", mp_bases[base].chars_per_limb);
          printf ("  want %d\n", want_chars_per_limb);
          abort ();
        }

      if (POW2_P (base))
        {
          want_bb = refmpn_count_trailing_zeros ((mp_limb_t) base);
          if (mp_bases[base].big_base != want_bb)
            {
              printf ("mp_bases[%d].big_base (log2 of base) wrong\n", base);
              abort ();
            }
        }
      else
        {
          want_bb = refmpn_big_base (base);
          if (mp_bases[base].big_base != want_bb)
            {
              printf ("mp_bases[%d].big_base wrong\n", base);
              abort ();
            }

#if USE_PREINV_DIVREM_1
          want_bb_inv = refmpn_invert_limb
            (want_bb << refmpn_count_leading_zeros (want_bb));
          if (mp_bases[base].big_base_inverted != want_bb_inv)
            {
              printf ("mp_bases[%d].big_base_inverted wrong\n", base);
              abort ();
            }
#endif
        }
    }

  exit (0);
}
Ejemplo n.º 6
0
char *
mpz_get_str (char *res_str, int base, mpz_srcptr x)
{
  mp_ptr xp;
  mp_size_t x_size = SIZ (x);
  char *return_str;
  size_t str_size;
  size_t alloc_size = 0;
  const char *num_to_text;
  int i;
  TMP_DECL;

  if (base >= 0)
    {
      num_to_text = "0123456789abcdefghijklmnopqrstuvwxyz";
      if (base <= 1)
	base = 10;
      else if (base > 36)
	{
	  num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	  if (base > 62)
	    return NULL;
	}
    }
  else
    {
      base = -base;
      if (base <= 1)
	base = 10;
      else if (base > 36)
	return NULL;
      num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    }

  /* allocate string for the user if necessary */
  if (res_str == NULL)
    {
      /* digits, null terminator, possible minus sign */
      MPN_SIZEINBASE (alloc_size, PTR(x), ABS(x_size), base);
      alloc_size += 1 + (x_size<0);
      res_str = (char *) (*__gmp_allocate_func) (alloc_size);
    }
  return_str = res_str;

  if (x_size < 0)
    {
      *res_str++ = '-';
      x_size = -x_size;
    }

  /* mpn_get_str clobbers its input on non power-of-2 bases */
  TMP_MARK;
  xp = PTR (x);
  if (! POW2_P (base))
    {
      xp = TMP_ALLOC_LIMBS (x_size | 1);  /* |1 in case x_size==0 */
      MPN_COPY (xp, PTR (x), x_size);
    }

  str_size = mpn_get_str ((unsigned char *) res_str, base, xp, x_size);
  ASSERT (alloc_size == 0 || str_size <= alloc_size - (SIZ(x) < 0));

  /* Convert result to printable chars.  */
  for (i = 0; i < str_size; i++)
    res_str[i] = num_to_text[(int) res_str[i]];
  res_str[str_size] = 0;

  TMP_FREE;

  /* if allocated then resize down to the actual space required */
  if (alloc_size != 0)
    {
      size_t  actual_size = str_size + 1 + (res_str - return_str);
      ASSERT (actual_size == strlen (return_str) + 1);
      __GMP_REALLOCATE_FUNC_MAYBE_TYPE (return_str, alloc_size, actual_size,
					char);
    }
  return return_str;
}
Ejemplo n.º 7
0
void
table (int limb_bits, int nail_bits)
{
  int  numb_bits = limb_bits - nail_bits;
  int  base;
  mpz_t r, t, logb2, log2b;

  mpz_init (r);
  mpz_init (t);
  mpz_init (logb2);
  mpz_init (log2b);

  printf ("/* This file generated by gen-bases.c - DO NOT EDIT. */\n");
  printf ("\n");
  printf ("#include \"gmp.h\"\n");
  printf ("#include \"gmp-impl.h\"\n");
  printf ("\n");
  printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
  printf ("Error, error, this data is for %d bits\n", numb_bits);
  printf ("#endif\n");
  printf ("\n");
  puts ("const struct bases mp_bases[257] =\n{");
  puts ("  /*   0 */ { 0, 0, 0, 0, 0 },");
  puts ("  /*   1 */ { 0, 0, 0, 0, 0 },");
  for (base = 2; base <= 256; base++)
    {
      generate (limb_bits, nail_bits, base);
      mp_2logb (r, base, limb_bits + 8);
      mpz_tdiv_q_2exp (logb2, r, 8);
      mpz_set_ui (t, 1);
      mpz_mul_2exp (t, t, 2*limb_bits + 5);
      mpz_sub_ui (t, t, 1);
      mpz_add_ui (r, r, 1);
      mpz_tdiv_q (log2b, t, r);

      printf ("  /* %3u */ { ", base);
      if (POW2_P (base))
	{
          mpz_set_ui (big_base, ulog2 (base) - 1);
	  mpz_set_ui (big_base_inverted, 0);
	}

      printf ("%u,", chars_per_limb);
      printf (" CNST_LIMB(0x");
      mpz_out_str (stdout, 16, logb2);
      printf ("), CNST_LIMB(0x");
      mpz_out_str (stdout, 16, log2b);
      printf ("), CNST_LIMB(0x");
      mpz_out_str (stdout, 16, big_base);
      printf ("), CNST_LIMB(0x");
      mpz_out_str (stdout, 16, big_base_inverted);
      printf (") },\n");
    }

  puts ("};");

  mpz_clear (r);
  mpz_clear (t);
  mpz_clear (logb2);
  mpz_clear (log2b);

}
Ejemplo n.º 8
0
size_t
mpz_out_str (FILE *stream, int base, mpz_srcptr x)
{
  mp_ptr xp;
  mp_size_t x_size = SIZ (x);
  unsigned char *str;
  size_t str_size;
  size_t i;
  size_t written;
  const char *num_to_text;
  TMP_DECL;

  if (stream == 0)
    stream = stdout;

  if (base >= 0)
    {
      num_to_text = "0123456789abcdefghijklmnopqrstuvwxyz";
      if (base <= 1)
	base = 10;
      else if (base > 36)
	{
	  num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	  if (base > 62)
	    return 0;
	}
    }
  else
    {
      base = -base;
      if (base <= 1)
	base = 10;
      else if (base > 36)
	return 0;
      num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    }

  written = 0;

  if (x_size < 0)
    {
      fputc ('-', stream);
      x_size = -x_size;
      written = 1;
    }

  TMP_MARK;

  DIGITS_IN_BASE_PER_LIMB (str_size, x_size, base);
  str_size += 3;
  str = (unsigned char *) TMP_ALLOC (str_size);

  xp = PTR (x);
  if (! POW2_P (base))
    {
      xp = TMP_ALLOC_LIMBS (x_size | 1);  /* |1 in case x_size==0 */
      MPN_COPY (xp, PTR (x), x_size);
    }

  str_size = mpn_get_str (str, base, xp, x_size);

  /* Convert result to printable chars.  */
  for (i = 0; i < str_size; i++)
    str[i] = num_to_text[str[i]];
  str[str_size] = 0;

  {
    size_t fwret;
    fwret = fwrite ((char *) str, 1, str_size, stream);
    written += fwret;
  }

  TMP_FREE;
  return ferror (stream) ? 0 : written;
}
Ejemplo n.º 9
0
void
mpz_urandomm (mpz_ptr rop, gmp_randstate_t rstate, mpz_srcptr n)
{
  mp_ptr rp, np, nlast;
  mp_size_t nbits, size;
  int count;
  int pow2;
  int cmp;
  TMP_DECL;

  size = ABSIZ (n);
  if (size == 0)
    DIVIDE_BY_ZERO;

  nlast = &PTR (n)[size - 1];

  /* Detect whether n is a power of 2.  */
  pow2 = POW2_P (*nlast);
  if (pow2 != 0)
    for (np = PTR (n); np < nlast; np++)
      if (*np != 0)
	{
	  pow2 = 0;		/* Mark n as `not a power of two'.  */
	  break;
	}

  count_leading_zeros (count, *nlast);
  nbits = size * GMP_NUMB_BITS - (count - GMP_NAIL_BITS) - pow2;
  if (nbits == 0)		/* nbits == 0 means that n was == 1.  */
    {
      SIZ (rop) = 0;
      return;
    }

  TMP_MARK;
  np = PTR (n);
  if (rop == n)
    {
      mp_ptr tp;
      tp = TMP_ALLOC_LIMBS (size);
      MPN_COPY (tp, np, size);
      np = tp;
    }

  /* Here the allocated size can be one too much if n is a power of
     (2^GMP_NUMB_BITS) but it's convenient for using mpn_cmp below.  */
  rp = MPZ_REALLOC (rop, size);
  /* Clear last limb to prevent the case in which size is one too much.  */
  rp[size - 1] = 0;

  count = MAX_URANDOMM_ITER;	/* Set iteration count limit.  */
  do
    {
      _gmp_rand (rp, rstate, nbits);
      MPN_CMP (cmp, rp, np, size);
    }
  while (cmp >= 0 && --count != 0);

  if (count == 0)
    /* Too many iterations; return result mod n == result - n */
    mpn_sub_n (rp, rp, np, size);

  MPN_NORMALIZE (rp, size);
  SIZ (rop) = size;
  TMP_FREE;
}
Ejemplo n.º 10
0
int
main (int argc, char *argv[])
{
  mp_limb_t  bb, h, l, bb_inv;
  int        i, j;

  for (i = 2; i < numberof (mp_bases); i++)
    {
      if (POW2_P (i))
        {
          count_trailing_zeros (j, i);
          if (mp_bases[i].big_base != (mp_limb_t) j)
            {
              printf ("mp_bases[%d].big_base (trailing zeros) wrong\n", i);
              abort ();
            }
        }
      else
        {
          bb = 1;
          for (j = 0; j < mp_bases[i].chars_per_limb; j++)
            {
              umul_ppmm (h, bb, bb, i);
              if (h != 0 || (bb & GMP_NAIL_MASK) != 0)
                {
                  printf ("mp_bases[%d].chars_per_limb overflow\n", i);
                  abort ();
                }
            }
          umul_ppmm (h, l, bb, i);
          if (h == 0 && (l & GMP_NAIL_MASK) == 0)
            {
              printf ("mp_bases[%d].chars_per_limb too small\n", i);
              abort ();
            }

          if (mp_bases[i].big_base != bb)
            {
              printf ("mp_bases[%d].big_base wrong\n", i);
              abort ();
            }

          invert_limb (bb_inv, bb << refmpn_count_leading_zeros (bb));
          if (mp_bases[i].big_base_inverted != bb_inv)
            {
              printf ("mp_bases[%d].big_base_inverted wrong\n", i);
              abort ();
            }
        }
    }

  if (MP_BASES_CHARS_PER_LIMB_10 != mp_bases[10].chars_per_limb)
    {
      printf ("MP_BASES_CHARS_PER_LIMB_10 not the same as mp_bases[10].chars_per_limb\n");
      abort ();
    }

  if (MP_BASES_BIG_BASE_10 != mp_bases[10].big_base)
    {
      printf ("MP_BASES_BIG_BASE_10 not the same as mp_bases[10].big_base\n");
      abort ();
    }

  if (MP_BASES_BIG_BASE_INVERTED_10 != mp_bases[10].big_base_inverted)
    {
      printf ("MP_BASES_BIG_BASE_INVERTED_10 not the same as mp_bases[10].big_base_inverted\n");
      abort ();
    }

  if (MP_BASES_NORMALIZATION_STEPS_10
      != refmpn_count_leading_zeros (MP_BASES_BIG_BASE_10))
    {
      printf ("MP_BASES_NORMALIZATION_STEPS_10 wrong\n");
      abort ();
    }

  exit (0);
}