void eu065(char *ans) { int N = 99; mpz_t n, d, r; mpz_init(n); mpz_init(d); mpz_init(r); mpz_set_ui(n, eterm(N)); mpz_set_ui(d, 1); for (int i = N-1; i >= 0; i--) { mpz_swap(n, d); int t = eterm(i); mpz_addmul_ui(n, d, t); mpz_gcd(r, n, d); mpz_div(n, n, r); mpz_div(d, d, r); } sprintf(ans, "%d", digitsum(n)); mpz_clear(r); mpz_clear(d); mpz_clear(n); }
void decode_all(int* array, header h, int level) { if(!level) { return finish(array); } int* new_array = malloc(sizeof(int)*headers[level-1].size); int index = 0; mpz_t number, spill; mpz_init(number); mpz_init(spill); for(int i = 0; i < h.size; i++) { mpz_ui_pow_ui(spill, 2, M); mpz_set(number, remainders[level-1][i]); mpz_addmul_ui(number, spill, array[i]); int min = headers[level-1].chunksize > (headers[level-1].size - index)?(headers[level-1].size - index):headers[level-1].chunksize; for(int j = 0; j < min; j++) { new_array[index + min - j - 1] = mpz_fdiv_q_ui(number, number, headers[level-1].K); } index += min; } return decode_all(new_array, headers[level - 1], level - 1); }
void next_term(ui k) { ui k2 = k * 2U + 1U; mpz_addmul_ui(acc, num, 2U); mpz_mul_ui(acc, acc, k2); mpz_mul_ui(den, den, k2); mpz_mul_ui(num, num, k); }
int main(int argc, char **argv) { int n; mpz_t a, b; if (argc>1) n=atoi(argv[1]); else n=1; getnum(a); getnum(b); mpz_addmul_ui(a,b,(unsigned long int)n); gmp_printf("%Zd\n",a); return 0; }
// Compute 0, 1, 2 power sums of sizes of sets. void zdd_count_2(restrict mpz_ptr z0, restrict mpz_ptr z1, restrict mpz_ptr z2) { uint32_t r = zdd_root(), s = zdd_size(); restrict mpz_ptr *t0 = malloc(sizeof(*t0) * s); restrict mpz_ptr *t1 = malloc(sizeof(*t1) * s); restrict mpz_ptr *t2 = malloc(sizeof(*t2) * s); for(int i = 0; i < s; i++) t0[i] = NULL; // Count elements in ZDD rooted at node n. // Along with t1 size of solutions. mpz_ptr recurse(uint32_t n) { if (t0[n]) return t0[n]; t0[n] = malloc(sizeof(mpz_t)); mpz_init(t0[n]); t1[n] = malloc(sizeof(mpz_t)); mpz_init(t1[n]); t2[n] = malloc(sizeof(mpz_t)); mpz_init(t2[n]); if (n <= 1) { // t0[1] should be 1. mpz_set_ui(t0[n], n); // t1[n], t2[n] should be zero. // Another reason why 0^0 = 1. return t0[n]; } uint32_t x = pool[n]->lo; uint32_t y = pool[n]->hi; x = 1 >= x ? x : x - r + 2; y = 1 >= y ? y : y - r + 2; mpz_add(t0[n], recurse(x), recurse(y)); mpz_add(t1[n], t1[x], t1[y]); mpz_add(t1[n], t1[n], t0[y]); mpz_add(t2[n], t2[x], t2[y]); mpz_addmul_ui(t2[n], t1[y], 2); mpz_add(t2[n], t2[n], t0[y]); return t0[n]; } r = 1 >= r ? r : 2; mpz_set(z0, recurse(r)); mpz_set(z1, t1[r]); mpz_set(z2, t2[r]); for(int i = 0; i < s; i++) { if (t0[i]) { mpz_clear(t0[i]); free(t0[i]); mpz_clear(t1[i]); free(t1[i]); mpz_clear(t2[i]); free(t2[i]); } } }
void main() { char* hex = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d"; mpz_t decimal; mpz_init(decimal); int exponent = 0; for (int i = strlen(hex)-1; i >= 0; i--) { int number = hex2decimal(hex[i]); // decimal += number * (int)Math.pow(16, exponent); mpz_t power; // mpz_t must be initialized before mpz_ui_pow_ui() mpz_init(power); mpz_ui_pow_ui(power, 16, exponent); mpz_addmul_ui(decimal, power, number); // printf("hex: %c, number: %d, exponent: %d, decimal: ", hex[i], number, exponent); // mpz_out_str(stdout, 10, decimal); // printf("\n"); exponent += 1; } char* builder = malloc(sizeof(strlen(hex))); int divider = 64; mpz_t number; mpz_init_set(number, decimal); int index = 0; while (mpz_cmp_ui(number, divider) > 0) { mpz_t quotient; int remainder = mpz_tdiv_q_ui(quotient, number, divider); char letter = decimal2base64(remainder); builder[index] = letter; index++; mpz_set(number, quotient); } mpz_t quotient; int remainder = mpz_tdiv_q_ui(quotient, number, divider); char letter = decimal2base64(remainder); builder[index] = letter; index++; builder[index] = '\0'; char* result = malloc(sizeof(strlen(builder)+1)); strcpy(result, builder); reverse(result); puts(result); char* base64 = "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t"; printf("hex: %s\n", hex); printf("decimal: "); mpz_out_str(stdout, 10, decimal); printf("\n"); printf("base64: %s\n", base64); printf(strcmp(result, base64) == 0 ? "passed\n" : "failed\n"); }
/** * \fn void conversion10(mpz_t conv, unsigned char* buffer, unsigned int blocs) * \brief conversion d'une numération en base 256 en un entier en base 10 * \param conv l'entier converti * \param buffer numération en base 256 * */ void conversion10(mpz_t conv, unsigned char* buffer, unsigned int blocs) // base 256 -> base 10 { int i; mpz_t temp; mpz_init(temp); for(i=0;i<blocs;i++) { mpz_ui_pow_ui(temp,256,blocs-i-1); mpz_addmul_ui(conv,temp,buffer[i]); } mpz_clear(temp); }
void testmain (int argc, char **argv) { unsigned i; mpz_t a, b, res, ref; mpz_init (a); mpz_init (b); mpz_init_set_ui (res, 5); mpz_init (ref); for (i = 0; i < COUNT; i++) { mini_random_op3 (OP_MUL, MAXBITS, a, b, ref); if (i & 1) { mpz_add (ref, ref, res); if (mpz_fits_ulong_p (b)) mpz_addmul_ui (res, a, mpz_get_ui (b)); else mpz_addmul (res, a, b); } else { mpz_sub (ref, res, ref); if (mpz_fits_ulong_p (b)) mpz_submul_ui (res, a, mpz_get_ui (b)); else mpz_submul (res, a, b); } if (mpz_cmp (res, ref)) { if (i & 1) fprintf (stderr, "mpz_addmul failed:\n"); else fprintf (stderr, "mpz_submul failed:\n"); dump ("a", a); dump ("b", b); dump ("r", res); dump ("ref", ref); abort (); } } mpz_clear (a); mpz_clear (b); mpz_clear (res); mpz_clear (ref); }
static void ec_discriminant(mpz_t delta, mpz_t a, mpz_t b) { /* delta(E(a, b)) = 4 * a^3 + 27 * b^2 */ mpz_t tmp; mpz_init(tmp); mpz_mul(delta, a, a); mpz_mul(delta, delta, a); mpz_mul_ui(delta, delta, 4); mpz_mul(tmp, b, b); mpz_addmul_ui(delta, tmp, 27); mpz_clear(tmp); }
static int ec_order(mpz_t order, mpz_t a, mpz_t b, unsigned long n) { /* use the inefficient naive approach to count the points of an elliptic * curve E(a, b) over finite field GF(n): * |(E(a, b))/GF(n)| = * n + 1 + sum (x in GF(n)) (jacobi_symbol((x^3 + a*x + b), n)) */ unsigned long i; mpz_t tmp; int order_exists; if (!(n & 1)) { order_exists = 0; } else { mpz_init(tmp); mpz_set_ui(order, n); mpz_add_ui(order, order, 1); for (i = 0; i < n; ++i) { mpz_set_ui(tmp, i); mpz_mul_ui(tmp, tmp, i); mpz_mul_ui(tmp, tmp, i); mpz_addmul_ui(tmp, a, i); mpz_add(tmp, tmp, b); mpz_set_si(tmp, mpz_kronecker_ui(tmp, n)); mpz_add(order, order, tmp); } order_exists = 1; mpz_clear(tmp); } return order_exists; }
void check_one_ui (mpz_ptr w, mpz_ptr x, unsigned long y) { mpz_t want, got; mpz_init (want); mpz_init (got); mpz_mul_ui (want, x, (unsigned long) y); mpz_add (want, w, want); mpz_set (got, w); mpz_addmul_ui (got, x, (unsigned long) y); MPZ_CHECK_FORMAT (got); if (mpz_cmp (want, got) != 0) { printf ("mpz_addmul_ui fail\n"); fail: mpz_trace ("w", w); mpz_trace ("x", x); printf ("y=0x%lX %lu\n", y, y); mpz_trace ("want", want); mpz_trace ("got ", got); abort (); } mpz_mul_ui (want, x, y); mpz_sub (want, w, want); mpz_set (got, w); mpz_submul_ui (got, x, y); MPZ_CHECK_FORMAT (got); if (mpz_cmp (want, got) != 0) { printf ("mpz_submul_ui fail\n"); goto fail; } mpz_clear (want); mpz_clear (got); }
/* Calculate (b^e) mod (2^n-k) for e=1074888996, n=19937 and k=20023, needed by the seeding function below. */ static void mangle_seed (mpz_ptr r) { mpz_t t, b; unsigned long e = 0x40118124; unsigned long bit = 0x20000000; mpz_init2 (t, 19937L); mpz_init_set (b, r); do { mpz_mul (r, r, r); reduce: for (;;) { mpz_tdiv_q_2exp (t, r, 19937L); if (SIZ (t) == 0) break; mpz_tdiv_r_2exp (r, r, 19937L); mpz_addmul_ui (r, t, 20023L); } if ((e & bit) != 0) { e ^= bit; mpz_mul (r, r, b); goto reduce; } bit >>= 1; } while (bit != 0); mpz_clear (t); mpz_clear (b); }
void burns::get(mpz_t X, const vector<uint64>& x) const { mpz_t Mi; mpz_init(Mi); mpz_set_ui(X, 0); for(int i=0; i < size(); i++) { const monty& m = mb.field(i); // Mi = M / m_i mpz_divexact_ui(Mi, M, m.modulus()); uint64 y = m.get(m.mul(x[i], mrc[i])); // X += Mi y mpz_addmul_ui(X, Mi, y); } mpz_clear(Mi); // Reduce mod M mpz_mod(X, X, M); }
/*-------------------------------------------------------------------------*/ void sieve_xy_run_deg5(root_sieve_t *rs, uint64 lattice_size, double line_min, double line_max) { uint32 i, j; sieve_xy_t *xy = &rs->xydata; hit_t hitlist[MAX_CRT_FACTORS]; uint32 num_lattice_primes; uint32 num_lattices; uint32 y_blocks; int64 curr_y; double direction[3] = {0, 1, 0}; xy->lattice_size = lattice_size; xy->dbl_lattice_size = (double)lattice_size; uint64_2gmp(lattice_size, xy->mp_lattice_size); mpz_set_d(xy->y_base, line_min / lattice_size - 1); mpz_mul(xy->y_base, xy->y_base, xy->mp_lattice_size); y_blocks = (line_max - line_min) / lattice_size + 1; if (y_blocks > xy->y_blocks) { xy->x_line_min = (double *)xrealloc(xy->x_line_min, y_blocks * sizeof(double)); xy->x_line_max = (double *)xrealloc(xy->x_line_max, y_blocks * sizeof(double)); } xy->y_blocks = y_blocks; xy->num_lattices = 0; if (lattice_size == 1) { num_lattice_primes = xy->num_lattice_primes = 0; num_lattices = 1; if (num_lattices > xy->num_lattices) { xy->lattices = (lattice_t *)xrealloc(xy->lattices, num_lattices * sizeof(lattice_t)); } memset(xy->lattices, 0, sizeof(lattice_t)); } else { num_lattice_primes = xy->num_lattice_primes = find_lattice_primes(rs->primes, rs->num_primes, lattice_size, xy->lattice_primes); find_hits(xy->lattice_primes, num_lattice_primes, hitlist); for (i = 0, num_lattices = 1; i < num_lattice_primes; i++) { num_lattices *= hitlist[i].num_roots; } if (num_lattices > xy->num_lattices) { xy->lattices = (lattice_t *)xrealloc(xy->lattices, num_lattices * sizeof(lattice_t)); } compute_lattices(hitlist, num_lattice_primes, xy->lattices, lattice_size, num_lattices, 2); } xy->num_lattices = num_lattices; line_min = -10000; line_max = 10000; direction[0] = 1; direction[1] = 0; direction[2] = 0; curr_y = gmp2int64(xy->y_base); for (i = 0; i < y_blocks; i++) { dpoly_t apoly = rs->apoly; apoly.coeff[2] += rs->dbl_p * curr_y; apoly.coeff[1] -= rs->dbl_d * curr_y; compute_line_size(rs->max_norm, &apoly, rs->dbl_p, rs->dbl_d, direction, line_min, line_max, &line_min, &line_max); if (line_min >= line_max) { xy->x_line_min[i] = 0; xy->x_line_max[i] = 0; line_min = -10000; line_max = 10000; } else { xy->x_line_min[i] = line_min; xy->x_line_max[i] = line_max; } curr_y += lattice_size; } for (i = y_blocks; i; i--) { if (xy->x_line_min[i-1] != xy->x_line_max[i-1]) break; } y_blocks = i; for (i = 0; i < y_blocks; i++) { if (xy->x_line_min[i] != xy->x_line_max[i]) break; } mpz_addmul_ui(xy->y_base, xy->mp_lattice_size, i); y_blocks -= i; if (i > 0) { for (j = 0; j < y_blocks; j++) { xy->x_line_min[j] = xy->x_line_min[j+i]; xy->x_line_max[j] = xy->x_line_max[j+i]; } } xy->y_blocks = y_blocks; #if 0 printf("\n%.0lf %u %u\n", (double)lattice_size, y_blocks, num_lattices); #endif sieve_x_run_deg5(rs); }
Integer& Integer::axpyin(Integer& res, const Integer& a, const uint64_t x) { if (isZero(a) || isZero(x)) return res; mpz_addmul_ui( (mpz_ptr)&res.gmp_rep, (mpz_srcptr)&a.gmp_rep, x); return res; }
void* worker(void* arg) { State& state = *((State*) arg); long k = state.k; #ifdef USE_THREADS pthread_mutex_lock(&state.lock); #endif while (1) { if (state.next * BLOCK_SIZE < state.bound) { // need to generate more modular data long next = state.next++; #ifdef USE_THREADS pthread_mutex_unlock(&state.lock); #endif Item* item = new Item; mpz_set_ui(item->modulus, 1); mpz_set_ui(item->residue, 0); for (long p = max(5, state.table->next_prime(next * BLOCK_SIZE)); p < state.bound && p < (next+1) * BLOCK_SIZE; p = state.table->next_prime(p)) { if (k % (p-1) == 0) continue; // compute B_k mod p long b = bern_modp(p, k); // CRT into running total long x = MulMod(SubMod(b, mpz_fdiv_ui(item->residue, p), p), InvMod(mpz_fdiv_ui(item->modulus, p), p), p); mpz_addmul_ui(item->residue, item->modulus, x); mpz_mul_ui(item->modulus, item->modulus, p); } #ifdef USE_THREADS pthread_mutex_lock(&state.lock); #endif state.items.insert(item); } else { // all modular data has been generated if (state.items.size() <= 1) { // no more CRTs for this thread to perform #ifdef USE_THREADS pthread_mutex_unlock(&state.lock); #endif return NULL; } // CRT two smallest items together Item* item1 = *(state.items.begin()); state.items.erase(state.items.begin()); Item* item2 = *(state.items.begin()); state.items.erase(state.items.begin()); #ifdef USE_THREADS pthread_mutex_unlock(&state.lock); #endif Item* item3 = CRT(item1, item2); delete item1; delete item2; #ifdef USE_THREADS pthread_mutex_lock(&state.lock); #endif state.items.insert(item3); } } }
/* compute in s an approximation of S3 = c*sum((h(k)+h(n+k))*y^k/k!/(n+k)!,k=0..infinity) where h(k) = 1 + 1/2 + ... + 1/k k=0: h(n) k=1: 1+h(n+1) k=2: 3/2+h(n+2) Returns e such that the error is bounded by 2^e ulp(s). */ static mpfr_exp_t mpfr_yn_s3 (mpfr_ptr s, mpfr_srcptr y, mpfr_srcptr c, unsigned long n) { unsigned long k, zz; mpfr_t t, u; mpz_t p, q; /* p/q will store h(k)+h(n+k) */ mpfr_exp_t exps, expU; zz = mpfr_get_ui (y, MPFR_RNDU); /* y = z^2/4 */ MPFR_ASSERTN (zz < ULONG_MAX - 2); zz += 2; /* z^2 <= 2^zz */ mpz_init_set_ui (p, 0); mpz_init_set_ui (q, 1); /* initialize p/q to h(n) */ for (k = 1; k <= n; k++) { /* p/q + 1/k = (k*p+q)/(q*k) */ mpz_mul_ui (p, p, k); mpz_add (p, p, q); mpz_mul_ui (q, q, k); } mpfr_init2 (t, MPFR_PREC(s)); mpfr_init2 (u, MPFR_PREC(s)); mpfr_fac_ui (t, n, MPFR_RNDN); mpfr_div (t, c, t, MPFR_RNDN); /* c/n! */ mpfr_mul_z (u, t, p, MPFR_RNDN); mpfr_div_z (s, u, q, MPFR_RNDN); exps = MPFR_EXP (s); expU = exps; for (k = 1; ;k ++) { /* update t */ mpfr_mul (t, t, y, MPFR_RNDN); mpfr_div_ui (t, t, k, MPFR_RNDN); mpfr_div_ui (t, t, n + k, MPFR_RNDN); /* update p/q: p/q + 1/k + 1/(n+k) = [p*k*(n+k) + q*(n+k) + q*k]/(q*k*(n+k)) */ mpz_mul_ui (p, p, k); mpz_mul_ui (p, p, n + k); mpz_addmul_ui (p, q, n + 2 * k); mpz_mul_ui (q, q, k); mpz_mul_ui (q, q, n + k); mpfr_mul_z (u, t, p, MPFR_RNDN); mpfr_div_z (u, u, q, MPFR_RNDN); exps = MPFR_EXP (u); if (exps > expU) expU = exps; mpfr_add (s, s, u, MPFR_RNDN); exps = MPFR_EXP (s); if (exps > expU) expU = exps; if (MPFR_EXP (u) + (mpfr_exp_t) MPFR_PREC (u) < MPFR_EXP (s) && zz / (2 * k) < k + n) break; } mpfr_clear (t); mpfr_clear (u); mpz_clear (p); mpz_clear (q); exps = expU - MPFR_EXP (s); /* the error is bounded by (6k^2+33/2k+11) 2^exps ulps <= 8*(k+2)^2 2^exps ulps */ return 3 + 2 * MPFR_INT_CEIL_LOG2(k + 2) + exps; }
int main(int argc,char *argv[]) { mpf_t pi,qi,ci; mpz_t pstack,qstack,gstack; long d=100,out=0,threads=1,depth,psize,qsize; double begin, mid0, mid3, mid4, end; double wbegin, wmid0, wmid3, wmid4, wend; prog_name = argv[0]; if (argc==1) { fprintf(stderr,"\nSyntax: %s <digits> <option> <threads>\n",prog_name); fprintf(stderr," <digits> digits of pi to output\n"); fprintf(stderr," <option> 0 - just run (default)\n"); fprintf(stderr," 1 - output digits\n"); fprintf(stderr," <threads> number of threads (default 1)\n"); exit(1); } if (argc>1) d = strtoul(argv[1],0,0); if (argc>2) out = atoi(argv[2]); if (argc>3) threads = atoi(argv[3]); terms = d/DIGITS_PER_ITER; depth = 0; while ((1L<<depth)<terms) depth++; depth++; fprintf(stderr,"#terms=%ld, depth=%ld, threads=%ld cores=%d\n", terms, depth, threads, get_nprocs()); begin = cpu_time(); wbegin = wall_clock(); mpz_init(pstack); mpz_init(qstack); mpz_init(gstack); /* begin binary splitting process */ if (terms<=0) { mpz_set_ui(pstack,1); mpz_set_ui(qstack,0); mpz_set_ui(gstack,1); } else { #ifdef _OPENMP #pragma omp parallel num_threads(threads) #pragma omp single nowait { bs(0,terms,1,pstack,qstack,gstack); } #else bs(0,terms,1,pstack,qstack,gstack); #endif } mid0 = cpu_time(); wmid0 = wall_clock(); fprintf(stderr,"bs cputime = %6.2f wallclock = %6.2f factor = %6.1f\n", mid0-begin,wmid0-wbegin,(mid0-begin)/(wmid0-wbegin)); fflush(stderr); mpz_clear(gstack); /* prepare to convert integers to floats */ mpf_set_default_prec((long)(d*BITS_PER_DIGIT+16)); /* p*(C/D)*sqrt(C) pi = ----------------- (q+A*p) */ psize = mpz_sizeinbase(pstack,10); qsize = mpz_sizeinbase(qstack,10); mpz_addmul_ui(qstack,pstack,A); mpz_mul_ui(pstack,pstack,C/D); mpf_init(pi); mpf_set_z(pi,pstack); mpz_clear(pstack); mpf_init(qi); mpf_set_z(qi,qstack); mpz_clear(qstack); /* final step */ mid3 = cpu_time(); wmid3 = wall_clock(); #ifdef _OPENMP #pragma omp parallel num_threads(threads) #pragma omp single nowait { #pragma omp task shared(qi,pi) { mpf_div(qi,pi,qi); mpf_clear(pi); } #pragma omp task shared(ci) { mpf_init(ci); mpf_sqrt_ui(ci,C); } #pragma omp taskwait } #else mpf_div(qi, pi, qi); mpf_clear(pi); mpf_init(ci); mpf_sqrt_ui(ci, C); #endif mid4 = cpu_time(); wmid4 = wall_clock(); fprintf(stderr,"div/sqrt cputime = %6.2f wallclock = %6.2f factor = %6.1f\n", mid4-mid3,wmid4-wmid3,(mid4-mid3)/(wmid4-wmid3)); mpf_mul(qi,qi,ci); mpf_clear(ci); end = cpu_time(); wend = wall_clock(); fprintf(stderr,"mul cputime = %6.2f wallclock = %6.2f factor = %6.1f\n", end-mid4,wend-wmid4,(end-mid4)/(wend-wmid4)); fprintf(stderr,"total cputime = %6.2f wallclock = %6.2f factor = %6.1f\n", end-begin,wend-wbegin,(end-begin)/(wend-wbegin)); fflush(stderr); fprintf(stderr," P size=%ld digits (%f)\n" " Q size=%ld digits (%f)\n", psize, (double)psize/d, qsize, (double)qsize/d); /* output Pi and timing statistics */ if (out&1) { fprintf(stdout,"pi(0,%ld)=\n", terms); mpf_out_str(stdout,10,d,qi); fprintf(stdout,"\n"); } /* free float resources */ mpf_clear(qi); exit (0); }
/* See: Daniel J. Bernstein and Jonathan P. Sorenson, * Modular Exponentiation via the explicit Chinese Remainder Theorem * * memory: MPZSPV_NORMALISE_STRIDE floats */ void mpzspv_to_mpzv (mpzspv_t x, spv_size_t offset, mpzv_t mpzv, spv_size_t len, mpzspm_t mpzspm) { unsigned int i; spv_size_t k, l; float *f = (float *) malloc (MPZSPV_NORMALISE_STRIDE * sizeof (float)); float prime_recip; sp_t t; spm_t *spm = mpzspm->spm; mpz_t mt; if (f == NULL) { fprintf (stderr, "Cannot allocate memory in mpzspv_to_mpzv\n"); exit (1); } ASSERT (mpzspv_verify (x, offset, len, mpzspm)); mpz_init (mt); for (l = 0; l < len; l += MPZSPV_NORMALISE_STRIDE) { spv_size_t stride = MIN (MPZSPV_NORMALISE_STRIDE, len - l); for (k = 0; k < stride; k++) { f[k] = 0.5; mpz_set_ui (mpzv[k + l], 0); } for (i = 0; i < mpzspm->sp_num; i++) { prime_recip = 1.0f / (float) spm[i]->sp; for (k = 0; k < stride; k++) { t = sp_mul (x[i][l + k + offset], mpzspm->crt3[i], spm[i]->sp, spm[i]->mul_c); if (sizeof (sp_t) > sizeof (unsigned long)) { mpz_set_sp (mt, t); mpz_addmul (mpzv[l + k], mpzspm->crt1[i], mt); } else { mpz_addmul_ui (mpzv[l + k], mpzspm->crt1[i], t); } f[k] += (float) t * prime_recip; } } for (k = 0; k < stride; k++) mpz_add (mpzv[l + k], mpzv[l + k], mpzspm->crt2[(unsigned int) f[k]]); } mpz_clear (mt); free (f); }
int main(int argc, char **argv) { mpz_t min, rop, sievesize; unsigned long r; unsigned long loop_count = 0; FILE *fp = stdout; bool *sieve[128]; int *primes, *primes_start, *sieve_loc; size_t prime_size, loc_size; mpz_init(min); mpz_init(rop); mpz_init(sievesize); mpz_set_str(min, argv[1], 0); mpz_set_ui(sievesize, SIEVESIZE); r = mpz_fdiv_ui(min, PRIMORAL); r = (97 - r + PRIMORAL) % PRIMORAL; mpz_add_ui(rop, min, r); primes_start = (int *) primesieve_generate_primes(0, MAX_SIEVE_PRIME, &prime_size, INT_PRIMES); for (primes = primes_start; *primes <= 7; primes++); prime_size -= (primes - primes_start); //loc_size = 6 * prime_size; loc_size = 8 * prime_size; //padding sieve_loc = (int *) malloc(sizeof(int) * loc_size); struct timeval start_t; struct timeval end_t; gettimeofday(&start_t, NULL); #pragma omp parallel { mpz_t candidate_plus; mpz_init(candidate_plus); int tid = omp_get_thread_num(); sieve[tid] = (bool *) malloc(sizeof(bool) * SIEVESIZE); if(sieve[tid]==NULL) printf("%d nil\n", tid); memset(sieve[tid], true, SIEVESIZE); #pragma omp for schedule(static, 16) for (int i = 0; i < prime_size; i++) { //printf("%d:%d\n",tid,i); int p = primes[i]; int inv = modinv_i(PRIMORAL, p); for (int j = 0; j < 6; j++) { mpz_add_ui(candidate_plus, rop, offsets[j]); unsigned long cmodp = mpz_fdiv_ui(candidate_plus, p); int index = ((p - cmodp) * inv) % p; sieve_loc[i * 8 + j] = index; } } mpz_clear(candidate_plus); } gettimeofday(&end_t, NULL); float duration = (end_t.tv_sec - start_t.tv_sec) * 1E6 + (end_t.tv_usec - start_t.tv_usec); printf("running time:%f\n", duration); mpz_t tmp[4]; mpz_t candidate[4]; mpz_init(tmp[0]); mpz_init(tmp[1]); mpz_init(tmp[2]); mpz_init(tmp[3]); mpz_init(candidate[0]); mpz_init(candidate[1]); mpz_init(candidate[2]); mpz_init(candidate[3]); while (1) { //step 1 //printf("Sieving\n"); gettimeofday(&start_t, NULL); for (int i = 0; i < prime_size; i++) { //printf("thread %d:prime%d\n", tid, primes[i]); for (int j = 0; j < 6; j++) { //o = sieve_loc[sieve_loc_index]; unsigned int o = sieve_loc[8 * i + j]; while (o < SIEVESIZE) { sieve[0][o] = false; o += primes[i]; } sieve_loc[8 * i + j] = o - SIEVESIZE; } } /*for(int i=0;i<SIEVESIZE;i++) if(sieve[0][i]) printf("1\n"); else printf("0\n"); for(int i=0;i<prime_size;i++){ for(int j=0;j<6;j++) printf("%d:%d\n",primes[i], sieve_loc[8*i+j]); } break;*/ gettimeofday(&end_t, NULL); duration = (end_t.tv_sec - start_t.tv_sec) * 1E6 + (end_t.tv_usec - start_t.tv_usec); printf("running time1:%f\n", duration); gettimeofday(&start_t, NULL); #pragma omp parallel { int tid = omp_get_thread_num(); //int num = omp_get_num_threads(); /*#pragma omp for for (int i = 0; i < prime_size; i++) { //printf("thread %d:prime%d\n", tid, primes[i]); for (int j = 0; j < 6; j++) { //o = sieve_loc[sieve_loc_index]; unsigned int o = sieve_loc[8 * i + j]; while (o < SIEVESIZE) { sieve[tid][o] = false; o += primes[i]; } sieve_loc[8 * i + j] = o - SIEVESIZE; } }*/ //#pragma omp barrier #pragma omp for for (int i = 0; i < SIEVESIZE; i++) { /*bool flag = true; for (int j = 0; j < num; j++) { flag = flag && sieve[j][i]; sieve[j][i] = true; }*/ if (sieve[0][i]) { mpz_set_ui(tmp[tid], i); mpz_addmul_ui(tmp[tid], sievesize, loop_count); mpz_set(candidate[tid], rop); mpz_addmul_ui(candidate[tid], tmp[tid], PRIMORAL); if (is_fermat_valid(candidate[tid])) { mpz_out_str(fp, 16, candidate[tid]); exit(0); } } //printf("thread %d:i%d\n", tid, i); if(!sieve[0][i]) sieve[0][i] = true; } /*#pragma omp barrier #pragma omp for for (int i = 0; i < prime_size; i++) { for (int j = 0; j < 6; j++) sieve[tid][i*8+j]=true; }*/ } gettimeofday(&end_t, NULL); duration = (end_t.tv_sec - start_t.tv_sec) * 1E6 + (end_t.tv_usec - start_t.tv_usec); printf("running time2:%f\n", duration); loop_count++; } return 0; }
/* * Run the randomized quadratic frobenius test to check whether [n] is a a * prime. The Parameter [k] determines how many times the test will be run at * most. If the test returns "composite", it will not be run again. */ int main(int argc, char *argv[]) { Primality result; #define VARS n, b, c, bb4c mpz_t VARS; uint64_t n_, b_ = 0, c_; uint64_t false_positives = 0; uint64_t lower_bound = 5, upper_bound = 1000000; mpz_inits(VARS, NULL); if (argc > 2) lower_bound = strtoul(argv[1], NULL, 10); if (argc > 1) upper_bound = strtoul(argv[argc > 2 ? 2 : 1], NULL, 10); printf("%lu to %lu\n", lower_bound, upper_bound); for (n_ = lower_bound | 1; n_ <= upper_bound; n_+=2) { mpz_set_ui(n, n_); if (mpz_perfect_square_p(n) || mpz_probab_prime_p(n, 100)) continue; #ifdef SMALL_C for (c_ = 2; c_ < n_; c_++) { if (jacobi(n_ - c_, n_) != 1) continue; #else c_ = n_ - 4; mpz_sub_ui(c, n, 4); #endif for (b_ = 1; b_ < n_; b_++) { mpz_mul(bb4c, b, b); mpz_addmul_ui(bb4c, c, 4); mpz_mod(bb4c, bb4c, n); if (mpz_jacobi(bb4c, n) == -1) break; if (b_ % 1000 == 999) { fprintf(stderr, "Could not find a valid parameter pair (b, c)\n"); goto next_n; } } #ifdef SMALL_C break; } #endif result = steps_3_4_5(n, b, c); if (result != composite) { false_positives++; fflush(stdout); printf("Found a false positive: n = %lu, b = %lu, c = %lu\n", n_, b_, c_); } if (n_ % 10000000 == 1) { fprintf(stderr, "."); fflush(stderr); } next_n: ; } printf("\nA total number of %lu false positives were found among the numbers %lu,...,%lu\n", false_positives, lower_bound, upper_bound); mpz_clears(VARS, NULL); return 0; }