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; }
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)); } }
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; }
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); }
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; } }
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); }
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); }
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); }
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; }
int GMPISCount(iset_t s) { return (mpz_popcount(*s)); }
/* 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; }
/* 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 (); } }
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); }
inline int Solver::popcount(BIGINT x){ return (int)mpz_popcount(x.get_mpz_t()); }
static void e_mpz_popcount (mpz_ptr w, mpz_srcptr x) { mpz_set_ui (w, mpz_popcount (x)); }