Beispiel #1
0
static cl_fixnum
count_bits(cl_object x)
{
	cl_fixnum count;

	switch (ecl_t_of(x)) {
	case t_fixnum: {
		cl_fixnum i = ecl_fixnum(x);
		cl_fixnum j = (i < 0) ? ~i : i;
		for (count=0 ; j ; j >>= 1)
			if (j & 1) count++;
		break;
	}
	case t_bignum:
		if (_ecl_big_sign(x) >= 0)
			count = mpz_popcount(x->big.big_num);
		else {
			cl_object z = _ecl_big_register0();
			mpz_com(z->big.big_num, x->big.big_num);
			count = mpz_popcount(z->big.big_num);
			_ecl_big_register_free(z);
		}
		break;
	default:
                FEwrong_type_only_arg(ecl_make_fixnum(/*LOGCOUNT*/496), x, ecl_make_fixnum(/*INTEGER*/437));
	}
	return count;
}
Beispiel #2
0
static int
mpz_bitcount(__mpz_struct *x)
{
  if (mpz_sgn(x) >= 0) {
    return mpz_popcount(x);
  } else {
    object u = new_bignum();
    mpz_com(MP(u),x);
    return mpz_popcount(MP(u));
  }
}
Beispiel #3
0
static Variant HHVM_FUNCTION(gmp_popcount,
                             const Variant& data) {
  mpz_t gmpData;

  if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_POPCOUNT, gmpData, data)) {
    return false;
  }

  int64_t population = mpz_popcount(gmpData);
  mpz_clear(gmpData);

  return population;
}
Beispiel #4
0
static void d_pairing_pp_clear(pairing_pp_t p) {
  // TODO: Better to store a sentinel value in p->data?
  mpz_ptr q = p->pairing->r;
  mp_bitcnt_t m = (mp_bitcnt_t)mpz_sizeinbase(q, 2) + mpz_popcount(q);
  m = (m > 3 ? m - 3 : 0);
  mp_bitcnt_t i;
  pp_coeff_t *coeff = (pp_coeff_t *) p->data;
  pp_coeff_ptr pp;
  for (i=0; i<m; i++) {
    pp = coeff[i];
    element_clear(pp->a);
    element_clear(pp->b);
    element_clear(pp->c);
  }
  pbc_free(p->data);
}
Beispiel #5
0
static PyObject *
GMPy_MPZ_popcount(PyObject *self, PyObject *other)
{
    mp_bitcnt_t n;
    MPZ_Object *tempx;

    if ((tempx = GMPy_MPZ_From_Integer(other, NULL))) {
        n = mpz_popcount(tempx->z);
        Py_DECREF((PyObject*)tempx);
        if (n == (mp_bitcnt_t)(-1))
            return PyLong_FromLong(-1);
        else
            return PyIntOrLong_FromMpBitCnt(n);
    }
    else {
        TYPE_ERROR("popcount() requires 'mpz' argument");
        return NULL;
    }
}
Beispiel #6
0
void
check_data (void)
{
  static const struct {
    const char     *n;
    unsigned long  want;
  } data[] = {
    { "-1", ~ (unsigned long) 0 },
    { "-12345678", ~ (unsigned long) 0 },
    { "0", 0 },
    { "1", 1 },
    { "3", 2 },
    { "5", 2 },
    { "0xFFFF", 16 },
    { "0xFFFFFFFF", 32 },
    { "0xFFFFFFFFFFFFFFFF", 64 },
    { "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 128 },
  };

  unsigned long   got;
  int    i;
  mpz_t  n;

  mpz_init (n);
  for (i = 0; i < numberof (data); i++)
    {
      mpz_set_str_or_abort (n, data[i].n, 0);
      got = mpz_popcount (n);
      if (got != data[i].want)
	{
	  printf ("mpz_popcount wrong at data[%d]\n", i);
	  printf ("   n     \"%s\"\n", data[i].n);
	  printf ("         ");   mpz_out_str (stdout, 10, n); printf ("\n");
	  printf ("         0x"); mpz_out_str (stdout, 16, n); printf ("\n");
	  printf ("   got   %lu\n", got);
	  printf ("   want  %lu\n", data[i].want);
	  abort ();
	}
    }
  mpz_clear (n);
}
Beispiel #7
0
void
check_random (void)
{
  gmp_randstate_t rands;
  mpz_t bs;
  mpz_t arg;
  unsigned long arg_size, size_range;
  unsigned long got, ref;
  int i;

  gmp_randinit_default(rands);

  mpz_init (bs);
  mpz_init (arg);

  for (i = 0; i < 10000; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 11 + 2; /* 0..4096 bit operands */

      mpz_urandomb (bs, rands, size_range);
      arg_size = mpz_get_ui (bs);
      mpz_rrandomb (arg, rands, arg_size);

      got = mpz_popcount (arg);
      ref = refmpz_popcount (arg);
      if (got != ref)
	{
          printf ("mpz_popcount wrong on random\n"); 
          printf ("         ");   mpz_out_str (stdout, 10, arg); printf ("\n");
          printf ("         0x"); mpz_out_str (stdout, 16, arg); printf ("\n");
          printf ("   got   %lu\n", got);
          printf ("   want  %lu\n", ref);
          abort();                                    
	  abort ();
	}
    }
  mpz_clear (arg);
  mpz_clear (bs);
  gmp_randclear(rands);
}
Beispiel #8
0
void
check_onebit (void)
{
  mpz_t          n;
  unsigned long  i, got;

  mpz_init (n);
  for (i = 0; i < 5 * GMP_LIMB_BITS; i++)
    {
      mpz_setbit (n, i);
      got = mpz_popcount (n);
      if (got != 1)
	{
	  printf ("mpz_popcount wrong on single bit at %lu\n", i);
	  printf ("   got %lu, want 1\n", got);
	  abort();
	}
      mpz_clrbit (n, i);
    }
  mpz_clear (n);
}
Beispiel #9
0
void
generate_sq_res_0x100 (int limb_bits)
{
  int  i, res;

  nsq_res_0x100 = (0x100 + limb_bits - 1) / limb_bits;
  sq_res_0x100 = xmalloc (nsq_res_0x100 * sizeof (*sq_res_0x100));

  for (i = 0; i < nsq_res_0x100; i++)
    mpz_init_set_ui (sq_res_0x100[i], 0L);

  for (i = 0; i < 0x100; i++)
    {
      res = (i * i) % 0x100;
      mpz_setbit (sq_res_0x100[res / limb_bits],
                  (unsigned long) (res % limb_bits));
    }

  sq_res_0x100_num = 0;
  for (i = 0; i < nsq_res_0x100; i++)
    sq_res_0x100_num += mpz_popcount (sq_res_0x100[i]);
  sq_res_0x100_fraction = (double) sq_res_0x100_num / 256.0;
}
Beispiel #10
0
int GMPISCount(iset_t s)
{
  return (mpz_popcount(*s));
}
Beispiel #11
0
/* returns 0 on success		*/
int
gen_consts (int numb, int nail, int limb)
{
  mpz_t x, mask, y, last;
  unsigned long a, b;
  unsigned long ofl, ofe;

  printf ("/* This file is automatically generated by gen-fac.c */\n\n");
  printf ("#if GMP_NUMB_BITS != %d\n", numb);
  printf ("Error , error this data is for %d GMP_NUMB_BITS only\n", numb);
  printf ("#endif\n");
#if 0
  printf ("#if GMP_LIMB_BITS != %d\n", limb);
  printf ("Error , error this data is for %d GMP_LIMB_BITS only\n", limb);
  printf ("#endif\n");
#endif

  printf
    ("/* This table is 0!,1!,2!,3!,...,n! where n! has <= GMP_NUMB_BITS bits */\n");
  printf
    ("#define ONE_LIMB_FACTORIAL_TABLE CNST_LIMB(0x1),CNST_LIMB(0x1");
  mpz_init_set_ui (x, 1);
  mpz_init (last);
  for (b = 2;; b++)
    {
      mpz_mul_ui (x, x, b);	/* so b!=a       */
      if (mpz_sizeinbase (x, 2) > numb)
	break;
      printf ("),CNST_LIMB(0x");
      mpz_out_str (stdout, 16, x);
    }
  printf (")\n");

  printf
    ("\n/* This table is 0!,1!,2!/2,3!/2,...,n!/2^sn where n!/2^sn is an */\n");
  printf
    ("/* odd integer for each n, and n!/2^sn has <= GMP_NUMB_BITS bits */\n");
  printf
    ("#define ONE_LIMB_ODD_FACTORIAL_TABLE CNST_LIMB(0x1),CNST_LIMB(0x1),CNST_LIMB(0x1");
  mpz_set_ui (x, 1);
  for (b = 3;; b++)
    {
      for (a = b; (a & 1) == 0; a >>= 1);
      mpz_swap (last, x);
      mpz_mul_ui (x, last, a);
      if (mpz_sizeinbase (x, 2) > numb)
	break;
      printf ("),CNST_LIMB(0x");
      mpz_out_str (stdout, 16, x);
    }
  printf (")\n");
  printf
    ("#define ODD_FACTORIAL_TABLE_MAX CNST_LIMB(0x");
  mpz_out_str (stdout, 16, last);
  printf (")\n");

  ofl = b - 1;
  printf
    ("#define ODD_FACTORIAL_TABLE_LIMIT (%lu)\n", ofl);
  mpz_init2 (mask, numb + 1);
  mpz_setbit (mask, numb);
  mpz_sub_ui (mask, mask, 1);
  printf
    ("\n/* Previous table, continued, values modulo 2^GMP_NUMB_BITS */\n");
  printf
    ("#define ONE_LIMB_ODD_FACTORIAL_EXTTABLE CNST_LIMB(0x");
  mpz_and (x, x, mask);
  mpz_out_str (stdout, 16, x);
  mpz_init (y);
  mpz_bin_uiui (y, b, b/2);
  b++;
  for (;; b++)
    {
      for (a = b; (a & 1) == 0; a >>= 1);
      if (a == b) {
	mpz_divexact_ui (y, y, a/2+1);
	mpz_mul_ui (y, y, a);
      } else
	mpz_mul_2exp (y, y, 1);
      if (mpz_sizeinbase (y, 2) > numb)
	break;
      mpz_mul_ui (x, x, a);
      mpz_and (x, x, mask);
      printf ("),CNST_LIMB(0x");
      mpz_out_str (stdout, 16, x);
    }
  printf (")\n");
  ofe = b - 1;
  printf
    ("#define ODD_FACTORIAL_EXTTABLE_LIMIT (%lu)\n", ofe);

  printf
    ("\n/* This table is 1!!,3!!,...,(2n+1)!! where (2n+1)!! has <= GMP_NUMB_BITS bits */\n");
  printf
    ("#define ONE_LIMB_ODD_DOUBLEFACTORIAL_TABLE CNST_LIMB(0x1");
  mpz_set_ui (x, 1);
  for (b = 3;; b+=2)
    {
      mpz_swap (last, x);
      mpz_mul_ui (x, last, b);
      if (mpz_sizeinbase (x, 2) > numb)
	break;
      printf ("),CNST_LIMB(0x");
      mpz_out_str (stdout, 16, x);
    }
  printf (")\n");
  printf
    ("#define ODD_DOUBLEFACTORIAL_TABLE_MAX CNST_LIMB(0x");
  mpz_out_str (stdout, 16, last);
  printf (")\n");

  printf
    ("#define ODD_DOUBLEFACTORIAL_TABLE_LIMIT (%lu)\n", b - 2);

  printf
    ("\n/* This table x_1, x_2,... contains values s.t. x_n^n has <= GMP_NUMB_BITS bits */\n");
  printf
    ("#define NTH_ROOT_NUMB_MASK_TABLE (GMP_NUMB_MASK");
  for (b = 2;b <= 8; b++)
    {
      mpz_root (x, mask, b);
      printf ("),CNST_LIMB(0x");
      mpz_out_str (stdout, 16, x);
    }
  printf (")\n");

  mpz_add_ui (mask, mask, 1);
  printf
    ("\n/* This table contains inverses of odd factorials, modulo 2^GMP_NUMB_BITS */\n");
  printf
    ("\n/* It begins with (2!/2)^-1=1 */\n");
  printf
    ("#define ONE_LIMB_ODD_FACTORIAL_INVERSES_TABLE CNST_LIMB(0x1");
  mpz_set_ui (x, 1);
  for (b = 3;b <= ofe - 2; b++)
    {
      for (a = b; (a & 1) == 0; a >>= 1);
      mpz_mul_ui (x, x, a);
      mpz_invert (y, x, mask);
      printf ("),CNST_LIMB(0x");
      mpz_out_str (stdout, 16, y);
    }
  printf (")\n");

  ofe = (ofe / 16 + 1) * 16;

  printf
    ("\n/* This table contains 2n-popc(2n) for small n */\n");
  printf
    ("\n/* It begins with 2-1=1 (n=1) */\n");
  printf
    ("#define TABLE_2N_MINUS_POPC_2N 1");
  for (b = 4; b <= ofe; b += 2)
    {
      mpz_set_ui (x, b);
      printf (",%lu",b - mpz_popcount (x));
    }
  printf ("\n");
  printf
    ("#define TABLE_LIMIT_2N_MINUS_POPC_2N %lu\n", ofe + 1);


  ofl = (ofl + 1) / 2;
  printf
    ("#define ODD_CENTRAL_BINOMIAL_OFFSET (%lu)\n", ofl);
  printf
    ("\n/* This table contains binomial(2k,k)/2^t */\n");
  printf
    ("\n/* It begins with ODD_CENTRAL_BINOMIAL_TABLE_MIN */\n");
  printf
    ("#define ONE_LIMB_ODD_CENTRAL_BINOMIAL_TABLE ");
  for (b = ofl;; b++)
    {
      mpz_bin_uiui (x, 2 * b, b);
      mpz_remove_twos (x);
      if (mpz_sizeinbase (x, 2) > numb)
	break;
      if (b != ofl)
	printf ("),");
      printf("CNST_LIMB(0x");
      mpz_out_str (stdout, 16, x);
    }
  printf (")\n");

  ofe = b - 1;
  printf
    ("#define ODD_CENTRAL_BINOMIAL_TABLE_LIMIT (%lu)\n", ofe);

  printf
    ("\n/* This table contains the inverses of elements in the previous table. */\n");
  printf
    ("#define ONE_LIMB_ODD_CENTRAL_BINOMIAL_INVERSE_TABLE CNST_LIMB(0x");
  for (b = ofl; b <= ofe; b++)
    {
      mpz_bin_uiui (x, 2 * b, b);
      mpz_remove_twos (x);
      mpz_invert (x, x, mask);
      mpz_out_str (stdout, 16, x);
      if (b != ofe)
	printf ("),CNST_LIMB(0x");
    }
  printf (")\n");

  printf
    ("\n/* This table contains the values t in the formula binomial(2k,k)/2^t */\n");
  printf
    ("#define CENTRAL_BINOMIAL_2FAC_TABLE ");
  for (b = ofl; b <= ofe; b++)
    {
      mpz_bin_uiui (x, 2 * b, b);
      printf ("%d", mpz_remove_twos (x));
      if (b != ofe)
	printf (",");
    }
  printf ("\n");

  return 0;
}
Beispiel #12
0
/* Evaluate the expression E and put the result in R.  */
void
mpz_eval_expr (mpz_ptr r, expr_t e)
{
  mpz_t lhs, rhs;

  switch (e->op)
    {
    case LIT:
      mpz_set (r, e->operands.val);
      return;
    case PLUS:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_add (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MINUS:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_sub (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MULT:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_mul (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case DIV:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_fdiv_q (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MOD:
      mpz_init (rhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_abs (rhs, rhs);
      mpz_eval_mod_expr (r, e->operands.ops.lhs, rhs);
      mpz_clear (rhs);
      return;
    case REM:
      /* Check if lhs operand is POW expression and optimize for that case.  */
      if (e->operands.ops.lhs->op == POW)
	{
	  mpz_t powlhs, powrhs;
	  mpz_init (powlhs);
	  mpz_init (powrhs);
	  mpz_init (rhs);
	  mpz_eval_expr (powlhs, e->operands.ops.lhs->operands.ops.lhs);
	  mpz_eval_expr (powrhs, e->operands.ops.lhs->operands.ops.rhs);
	  mpz_eval_expr (rhs, e->operands.ops.rhs);
	  mpz_powm (r, powlhs, powrhs, rhs);
	  if (mpz_cmp_si (rhs, 0L) < 0)
	    mpz_neg (r, r);
	  mpz_clear (powlhs);
	  mpz_clear (powrhs);
	  mpz_clear (rhs);
	  return;
	}

      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_fdiv_r (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION >= 2
    case INVMOD:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_invert (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case POW:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_cmpabs_ui (lhs, 1) <= 0)
	{
	  /* For 0^rhs and 1^rhs, we just need to verify that
	     rhs is well-defined.  For (-1)^rhs we need to
	     determine (rhs mod 2).  For simplicity, compute
	     (rhs mod 2) for all three cases.  */
	  expr_t two, et;
	  two = malloc (sizeof (struct expr));
	  two -> op = LIT;
	  mpz_init_set_ui (two->operands.val, 2L);
	  makeexp (&et, MOD, e->operands.ops.rhs, two);
	  e->operands.ops.rhs = et;
	}

      mpz_eval_expr (rhs, e->operands.ops.rhs);
      if (mpz_cmp_si (rhs, 0L) == 0)
	/* x^0 is 1 */
	mpz_set_ui (r, 1L);
      else if (mpz_cmp_si (lhs, 0L) == 0)
	/* 0^y (where y != 0) is 0 */
	mpz_set_ui (r, 0L);
      else if (mpz_cmp_ui (lhs, 1L) == 0)
	/* 1^y is 1 */
	mpz_set_ui (r, 1L);
      else if (mpz_cmp_si (lhs, -1L) == 0)
	/* (-1)^y just depends on whether y is even or odd */
	mpz_set_si (r, (mpz_get_ui (rhs) & 1) ? -1L : 1L);
      else if (mpz_cmp_si (rhs, 0L) < 0)
	/* x^(-n) is 0 */
	mpz_set_ui (r, 0L);
      else
	{
	  unsigned long int cnt;
	  unsigned long int y;
	  /* error if exponent does not fit into an unsigned long int.  */
	  if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	    goto pow_err;

	  y = mpz_get_ui (rhs);
	  /* x^y == (x/(2^c))^y * 2^(c*y) */
#if __GNU_MP_VERSION >= 2
	  cnt = mpz_scan1 (lhs, 0);
#else
	  cnt = 0;
#endif
	  if (cnt != 0)
	    {
	      if (y * cnt / cnt != y)
		goto pow_err;
	      mpz_tdiv_q_2exp (lhs, lhs, cnt);
	      mpz_pow_ui (r, lhs, y);
	      mpz_mul_2exp (r, r, y * cnt);
	    }
	  else
	    mpz_pow_ui (r, lhs, y);
	}
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    pow_err:
      error = "result of `pow' operator too large";
      mpz_clear (lhs); mpz_clear (rhs);
      longjmp (errjmpbuf, 1);
    case GCD:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_gcd (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case LCM:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_lcm (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case AND:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_and (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case IOR:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_ior (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case XOR:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_xor (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case NEG:
      mpz_eval_expr (r, e->operands.ops.lhs);
      mpz_neg (r, r);
      return;
    case NOT:
      mpz_eval_expr (r, e->operands.ops.lhs);
      mpz_com (r, r);
      return;
    case SQRT:
      mpz_init (lhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_sgn (lhs) < 0)
	{
	  error = "cannot take square root of negative numbers";
	  mpz_clear (lhs);
	  longjmp (errjmpbuf, 1);
	}
      mpz_sqrt (r, lhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case ROOT:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      if (mpz_sgn (rhs) <= 0)
	{
	  error = "cannot take non-positive root orders";
	  mpz_clear (lhs); mpz_clear (rhs);
	  longjmp (errjmpbuf, 1);
	}
      if (mpz_sgn (lhs) < 0 && (mpz_get_ui (rhs) & 1) == 0)
	{
	  error = "cannot take even root orders of negative numbers";
	  mpz_clear (lhs); mpz_clear (rhs);
	  longjmp (errjmpbuf, 1);
	}

      {
	unsigned long int nth = mpz_get_ui (rhs);
	if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	  {
	    /* If we are asked to take an awfully large root order, cheat and
	       ask for the largest order we can pass to mpz_root.  This saves
	       some error prone special cases.  */
	    nth = ~(unsigned long int) 0;
	  }
	mpz_root (r, lhs, nth);
      }
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case FAC:
      mpz_eval_expr (r, e->operands.ops.lhs);
      if (mpz_size (r) > 1)
	{
	  error = "result of `!' operator too large";
	  longjmp (errjmpbuf, 1);
	}
      mpz_fac_ui (r, mpz_get_ui (r));
      return;
#if __GNU_MP_VERSION >= 2
    case POPCNT:
      mpz_eval_expr (r, e->operands.ops.lhs);
      { long int cnt;
	cnt = mpz_popcount (r);
	mpz_set_si (r, cnt);
      }
      return;
    case HAMDIST:
      { long int cnt;
	mpz_init (lhs); mpz_init (rhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	mpz_eval_expr (rhs, e->operands.ops.rhs);
	cnt = mpz_hamdist (lhs, rhs);
	mpz_clear (lhs); mpz_clear (rhs);
	mpz_set_si (r, cnt);
      }
      return;
#endif
    case LOG2:
      mpz_eval_expr (r, e->operands.ops.lhs);
      { unsigned long int cnt;
	if (mpz_sgn (r) <= 0)
	  {
	    error = "logarithm of non-positive number";
	    longjmp (errjmpbuf, 1);
	  }
	cnt = mpz_sizeinbase (r, 2);
	mpz_set_ui (r, cnt - 1);
      }
      return;
    case LOG:
      { unsigned long int cnt;
	mpz_init (lhs); mpz_init (rhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	mpz_eval_expr (rhs, e->operands.ops.rhs);
	if (mpz_sgn (lhs) <= 0)
	  {
	    error = "logarithm of non-positive number";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	if (mpz_cmp_ui (rhs, 256) >= 0)
	  {
	    error = "logarithm base too large";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	cnt = mpz_sizeinbase (lhs, mpz_get_ui (rhs));
	mpz_set_ui (r, cnt - 1);
	mpz_clear (lhs); mpz_clear (rhs);
      }
      return;
    case FERMAT:
      {
	unsigned long int t;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	t = (unsigned long int) 1 << mpz_get_ui (lhs);
	if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0 || t == 0)
	  {
	    error = "too large Mersenne number index";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	mpz_set_ui (r, 1);
	mpz_mul_2exp (r, r, t);
	mpz_add_ui (r, r, 1);
	mpz_clear (lhs);
      }
      return;
    case MERSENNE:
      mpz_init (lhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0)
	{
	  error = "too large Mersenne number index";
	  mpz_clear (lhs);
	  longjmp (errjmpbuf, 1);
	}
      mpz_set_ui (r, 1);
      mpz_mul_2exp (r, r, mpz_get_ui (lhs));
      mpz_sub_ui (r, r, 1);
      mpz_clear (lhs);
      return;
    case FIBONACCI:
      { mpz_t t;
	unsigned long int n, i;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
	  {
	    error = "Fibonacci index out of range";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	n = mpz_get_ui (lhs);
	mpz_clear (lhs);

#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
	mpz_fib_ui (r, n);
#else
	mpz_init_set_ui (t, 1);
	mpz_set_ui (r, 1);

	if (n <= 2)
	  mpz_set_ui (r, 1);
	else
	  {
	    for (i = 3; i <= n; i++)
	      {
		mpz_add (t, t, r);
		mpz_swap (t, r);
	      }
	  }
	mpz_clear (t);
#endif
      }
      return;
    case RANDOM:
      {
	unsigned long int n;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
	  {
	    error = "random number size out of range";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	n = mpz_get_ui (lhs);
	mpz_clear (lhs);
	mpz_urandomb (r, rstate, n);
      }
      return;
    case NEXTPRIME:
      {
	mpz_eval_expr (r, e->operands.ops.lhs);
	mpz_nextprime (r, r);
      }
      return;
    case BINOM:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      {
	unsigned long int k;
	if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	  {
	    error = "k too large in (n over k) expression";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	k = mpz_get_ui (rhs);
	mpz_bin_ui (r, lhs, k);
      }
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case TIMING:
      {
	int t0;
	t0 = cputime ();
	mpz_eval_expr (r, e->operands.ops.lhs);
	printf ("time: %d\n", cputime () - t0);
      }
      return;
    default:
      abort ();
    }
}
Beispiel #13
0
void
generate_mod (int limb_bits, int nail_bits)
{
  int    numb_bits = limb_bits - nail_bits;
  int    i, divisor;

  mpz_init_set_ui (pp, 0L);
  mpz_init_set_ui (pp_norm, 0L);
  mpz_init_set_ui (pp_inverted, 0L);

  /* no more than limb_bits many factors in a one limb modulus (and of
     course in reality nothing like that many) */
  factor_alloc = limb_bits;
  factor = xmalloc (factor_alloc * sizeof (*factor));
  rawfactor = xmalloc (factor_alloc * sizeof (*rawfactor));

  if (numb_bits % 4 != 0)
    {
      strcpy (mod34_excuse, "GMP_NUMB_BITS % 4 != 0");
      goto use_pp;
    }

  max_divisor = 2*limb_bits;
  max_divisor_bits = log2_ceil (max_divisor);

  if (numb_bits / 4 < max_divisor_bits)
    {
      /* Wind back to one limb worth of max_divisor, if that will let us use
         mpn_mod_34lsub1.  */
      max_divisor = limb_bits;
      max_divisor_bits = log2_ceil (max_divisor);

      if (numb_bits / 4 < max_divisor_bits)
        {
          strcpy (mod34_excuse, "GMP_NUMB_BITS / 4 too small");
          goto use_pp;
        }
    }

  {
    /* Can use mpn_mod_34lsub1, find small factors of 2^mod34_bits-1. */
    mpz_t  m, q, r;
    int    multiplicity;

    mod34_bits = (numb_bits / 4) * 3;

    /* mpn_mod_34lsub1 returns a full limb value, PERFSQR_MOD_34 folds it at
       the mod34_bits mark, adding the two halves for a remainder of at most
       mod34_bits+1 many bits */
    mod_bits = mod34_bits + 1;

    mpz_init_set_ui (m, 1L);
    mpz_mul_2exp (m, m, mod34_bits);
    mpz_sub_ui (m, m, 1L);

    mpz_init (q);
    mpz_init (r);

    for (i = 3; i <= max_divisor; i++)
      {
        if (! isprime (i))
          continue;

        mpz_tdiv_qr_ui (q, r, m, (unsigned long) i);
        if (mpz_sgn (r) != 0)
          continue;

        /* if a repeated prime is found it's used as an i^n in one factor */
        divisor = 1;
        multiplicity = 0;
        do
          {
            if (divisor > max_divisor / i)
              break;
            multiplicity++;
            mpz_set (m, q);
            mpz_tdiv_qr_ui (q, r, m, (unsigned long) i);
          }
        while (mpz_sgn (r) == 0);

        assert (nrawfactor < factor_alloc);
        rawfactor[nrawfactor].divisor = i;
        rawfactor[nrawfactor].multiplicity = multiplicity;
        nrawfactor++;
      }

    mpz_clear (m);
    mpz_clear (q);
    mpz_clear (r);
  }

  if (nrawfactor <= 2)
    {
      mpz_t  new_pp;

      sprintf (mod34_excuse, "only %d small factor%s",
               nrawfactor, nrawfactor == 1 ? "" : "s");

    use_pp:
      /* reset to two limbs of max_divisor, in case the mpn_mod_34lsub1 code
         tried with just one */
      max_divisor = 2*limb_bits;
      max_divisor_bits = log2_ceil (max_divisor);

      mpz_init (new_pp);
      nrawfactor = 0;
      mod_bits = MIN (numb_bits, limb_bits - max_divisor_bits);

      /* one copy of each small prime */
      mpz_set_ui (pp, 1L);
      for (i = 3; i <= max_divisor; i++)
        {
          if (! isprime (i))
            continue;

          mpz_mul_ui (new_pp, pp, (unsigned long) i);
          if (mpz_sizeinbase (new_pp, 2) > mod_bits)
            break;
          mpz_set (pp, new_pp);

          assert (nrawfactor < factor_alloc);
          rawfactor[nrawfactor].divisor = i;
          rawfactor[nrawfactor].multiplicity = 1;
          nrawfactor++;
        }

      /* Plus an extra copy of one or more of the primes selected, if that
         still fits in max_divisor and the total in mod_bits.  Usually only
         3 or 5 will be candidates */
      for (i = nrawfactor-1; i >= 0; i--)
        {
          if (rawfactor[i].divisor > max_divisor / rawfactor[i].divisor)
            continue;
          mpz_mul_ui (new_pp, pp, (unsigned long) rawfactor[i].divisor);
          if (mpz_sizeinbase (new_pp, 2) > mod_bits)
            continue;
          mpz_set (pp, new_pp);

          rawfactor[i].multiplicity++;
        }

      mod_bits = mpz_sizeinbase (pp, 2);

      mpz_set (pp_norm, pp);
      while (mpz_sizeinbase (pp_norm, 2) < numb_bits)
        mpz_add (pp_norm, pp_norm, pp_norm);

      mpz_preinv_invert (pp_inverted, pp_norm, numb_bits);

      mpz_clear (new_pp);
    }

  /* start the factor array */
  for (i = 0; i < nrawfactor; i++)
    {
      int  j;
      assert (nfactor < factor_alloc);
      factor[nfactor].divisor = 1;
      for (j = 0; j < rawfactor[i].multiplicity; j++)
        factor[nfactor].divisor *= rawfactor[i].divisor;
      nfactor++;
    }

 combine:
  /* Combine entries in the factor array.  Combine the smallest entry with
     the biggest one that will fit with it (ie. under max_divisor), then
     repeat that with the new smallest entry. */
  qsort (factor, nfactor, sizeof (factor[0]), f_cmp_divisor);
  for (i = nfactor-1; i >= 1; i--)
    {
      if (factor[i].divisor <= max_divisor / factor[0].divisor)
        {
          factor[0].divisor *= factor[i].divisor;
          COLLAPSE_ELEMENT (factor, i, nfactor);
          goto combine;
        }
    }

  total_fraction = 1.0;
  for (i = 0; i < nfactor; i++)
    {
      mpz_init (factor[i].inverse);
      mpz_invert_ui_2exp (factor[i].inverse,
                          (unsigned long) factor[i].divisor,
                          (unsigned long) mod_bits);

      mpz_init (factor[i].mask);
      square_mask (factor[i].mask, factor[i].divisor);

      /* fraction of possible squares */
      factor[i].fraction = (double) mpz_popcount (factor[i].mask)
        / factor[i].divisor;

      /* total fraction of possible squares */
      total_fraction *= factor[i].fraction;
    }

  /* best tests first (ie. smallest fraction) */
  qsort (factor, nfactor, sizeof (factor[0]), f_cmp_fraction);
}
Beispiel #14
0
inline int Solver::popcount(BIGINT x){
    return (int)mpz_popcount(x.get_mpz_t());
}
Beispiel #15
0
static void
e_mpz_popcount (mpz_ptr w, mpz_srcptr x)
{
  mpz_set_ui (w, mpz_popcount (x));
}