/*------------------------------------------------------------------------*/ static void init_ad_sieve(sieve_t *sieve, poly_search_t *poly) { uint32 i, j, p; sieve->num_primes = 0; sieve->num_primes_alloc = 100; sieve->primes = (sieve_prime_t *)xmalloc(sizeof(sieve_prime_t) * sieve->num_primes_alloc); sieve->sieve_array = (uint8 *)xmalloc(sizeof(uint8) * SIEVE_ARRAY_SIZE); mpz_divexact_ui(poly->tmp1, poly->gmp_high_coeff_begin, (mp_limb_t)HIGH_COEFF_MULTIPLIER); for (i = p = 0; i < PRECOMPUTED_NUM_PRIMES; i++) { uint32 power; uint8 log_val; p += prime_delta[i]; if (p > HIGH_COEFF_PRIME_LIMIT) break; log_val = floor(log(p) / M_LN2 + 0.5); power = p; for (j = 0; j < HIGH_COEFF_POWER_LIMIT; j++) { uint32 r = mpz_cdiv_ui(poly->tmp1, (mp_limb_t)power); if (sieve->num_primes >= sieve->num_primes_alloc) { sieve->num_primes_alloc *= 2; sieve->primes = (sieve_prime_t *)xrealloc( sieve->primes, sieve->num_primes_alloc * sizeof(sieve_prime_t)); } sieve->primes[sieve->num_primes].p = power; sieve->primes[sieve->num_primes].r = r; sieve->primes[sieve->num_primes].log_val = log_val; sieve->num_primes++; if ((uint32)(-1) / power < p) break; power *= p; } } sieve->curr_offset = 0; sieve_ad_block(sieve, poly); }
int main (int argc, char **argv) { mpz_t dividend; mpz_t quotient, remainder; mpz_t quotient2, remainder2; mpz_t temp; mp_size_t dividend_size; unsigned long divisor; int i; int reps = 10000; gmp_randstate_t rands; mpz_t bs; unsigned long bsi, size_range; unsigned long r_rq, r_q, r_r, r; tests_start (); gmp_randinit_default(rands); mpz_init (bs); if (argc == 2) reps = atoi (argv[1]); mpz_init (dividend); mpz_init (quotient); mpz_init (remainder); mpz_init (quotient2); mpz_init (remainder2); mpz_init (temp); for (i = 0; i < reps; i++) { mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 10 + 2; /* 0..2047 bit operands */ do { mpz_rrandomb (bs, rands, 64); divisor = mpz_get_ui (bs); } while (divisor == 0); mpz_urandomb (bs, rands, size_range); dividend_size = mpz_get_ui (bs); mpz_rrandomb (dividend, rands, dividend_size); mpz_urandomb (bs, rands, 2); bsi = mpz_get_ui (bs); if ((bsi & 1) != 0) mpz_neg (dividend, dividend); /* printf ("%ld\n", SIZ (dividend)); */ r_rq = mpz_cdiv_qr_ui (quotient, remainder, dividend, divisor); r_q = mpz_cdiv_q_ui (quotient2, dividend, divisor); r_r = mpz_cdiv_r_ui (remainder2, dividend, divisor); r = mpz_cdiv_ui (dividend, divisor); /* First determine that the quotients and remainders computed with different functions are equal. */ if (mpz_cmp (quotient, quotient2) != 0) dump_abort ("quotients from mpz_cdiv_qr_ui and mpz_cdiv_q_ui differ", dividend, divisor); if (mpz_cmp (remainder, remainder2) != 0) dump_abort ("remainders from mpz_cdiv_qr_ui and mpz_cdiv_r_ui differ", dividend, divisor); /* Check if the sign of the quotient is correct. */ if (mpz_cmp_ui (quotient, 0) != 0) if ((mpz_cmp_ui (quotient, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0)) dump_abort ("quotient sign wrong", dividend, divisor); /* Check if the remainder has the opposite sign as the (positive) divisor (quotient rounded towards minus infinity). */ if (mpz_cmp_ui (remainder, 0) != 0) if (mpz_cmp_ui (remainder, 0) > 0) dump_abort ("remainder sign wrong", dividend, divisor); mpz_mul_ui (temp, quotient, divisor); mpz_add (temp, temp, remainder); if (mpz_cmp (temp, dividend) != 0) dump_abort ("n mod d != n - [n/d]*d", dividend, divisor); mpz_abs (remainder, remainder); if (mpz_cmp_ui (remainder, divisor) >= 0) dump_abort ("remainder greater than divisor", dividend, divisor); if (mpz_cmp_ui (remainder, r_rq) != 0) dump_abort ("remainder returned from mpz_cdiv_qr_ui is wrong", dividend, divisor); if (mpz_cmp_ui (remainder, r_q) != 0) dump_abort ("remainder returned from mpz_cdiv_q_ui is wrong", dividend, divisor); if (mpz_cmp_ui (remainder, r_r) != 0) dump_abort ("remainder returned from mpz_cdiv_r_ui is wrong", dividend, divisor); if (mpz_cmp_ui (remainder, r) != 0) dump_abort ("remainder returned from mpz_cdiv_ui is wrong", dividend, divisor); } mpz_clear (bs); mpz_clear (dividend); mpz_clear (quotient); mpz_clear (remainder); mpz_clear (quotient2); mpz_clear (remainder2); mpz_clear (temp); gmp_randclear(rands); tests_end (); exit (0); }