/* Don't need to save/restore exponent range: the cache does it. Catalan's constant is G = sum((-1)^k/(2*k+1)^2, k=0..infinity). We compute it using formula (31) of Victor Adamchik's page "33 representations for Catalan's constant" http://www-2.cs.cmu.edu/~adamchik/articles/catalan/catalan.htm G = Pi/8*log(2+sqrt(3)) + 3/8*sum(k!^2/(2k)!/(2k+1)^2,k=0..infinity) */ int mpfr_const_catalan_internal (mpfr_ptr g, mp_rnd_t rnd_mode) { mpfr_t x, y, z; mpz_t T, P, Q; mp_prec_t pg, p; int inex; MPFR_ZIV_DECL (loop); MPFR_GROUP_DECL (group); MPFR_LOG_FUNC (("rnd_mode=%d", rnd_mode), ("g[%#R]=%R inex=%d", g, g, inex)); /* Here are the WC (max prec = 100.000.000) Once we have found a chain of 11, we only look for bigger chain. Found 3 '1' at 0 Found 5 '1' at 9 Found 6 '0' at 34 Found 9 '1' at 176 Found 11 '1' at 705 Found 12 '0' at 913 Found 14 '1' at 12762 Found 15 '1' at 152561 Found 16 '0' at 171725 Found 18 '0' at 525355 Found 20 '0' at 529245 Found 21 '1' at 6390133 Found 22 '0' at 7806417 Found 25 '1' at 11936239 Found 27 '1' at 51752950 */ pg = MPFR_PREC (g); p = pg + 9; p += MPFR_INT_CEIL_LOG2 (p); MPFR_GROUP_INIT_3 (group, p, x, y, z); mpz_init (T); mpz_init (P); mpz_init (Q); MPFR_ZIV_INIT (loop, p); for (;;) { mpfr_sqrt_ui (x, 3, GMP_RNDU); mpfr_add_ui (x, x, 2, GMP_RNDU); mpfr_log (x, x, GMP_RNDU); mpfr_const_pi (y, GMP_RNDU); mpfr_mul (x, x, y, GMP_RNDN); S (T, P, Q, 0, (p - 1) / 2); mpz_mul_ui (T, T, 3); mpfr_set_z (y, T, GMP_RNDU); mpfr_set_z (z, Q, GMP_RNDD); mpfr_div (y, y, z, GMP_RNDN); mpfr_add (x, x, y, GMP_RNDN); mpfr_div_2ui (x, x, 3, GMP_RNDN); if (MPFR_LIKELY (MPFR_CAN_ROUND (x, p - 5, pg, rnd_mode))) break; /* Fixme: Is it possible? */ MPFR_ZIV_NEXT (loop, p); MPFR_GROUP_REPREC_3 (group, p, x, y, z); } MPFR_ZIV_FREE (loop); inex = mpfr_set (g, x, rnd_mode); MPFR_GROUP_CLEAR (group); mpz_clear (T); mpz_clear (P); mpz_clear (Q); return inex; }
void C_BigInt::operator *= (const uint32_t inMultiplicand) { mpz_mul_ui (mGMPint, mGMPint, inMultiplicand) ; }
void genNextLevelPrime(mpz_t prime, mpz_t r, mpz_t s, size_t length, gmp_randstate_t rand_state) { size_t k; mpz_t sinv; /* s^(-1) - inverse of s (mod r) */ mpz_t pow; /* 2^(n-1) */ mpz_t dprod; /* 2rs */ mpz_t Q; /* [pow / dprod] - integer part */ mpz_t R; /* remainder of pow/dprod */ mpz_t cond; /* temporary variable for 2*s*s^(-1) - 1 to check condition */ mpz_t Po; /* Po = 2*s*s^(-1) - 1 + Q*2rs, if 2*s*s^(-1) - 1 > R */ /* Po = 2*s*s^(-1) - 1 + (Q+1)*2rs, if 2*s*s^(-1) - 1 < R*/ mpz_init(prime); mpz_init(sinv); mpz_init(pow); mpz_init(dprod); mpz_init(Q); mpz_init(R); mpz_init(cond); mpz_init(Po); inverse(sinv, s, r); mpz_ui_pow_ui(pow, 2, length-1); /* find product 2rs */ mpz_mul_ui(dprod, r, 2); mpz_mul(dprod, dprod, s); /* compute Q and R */ mpz_fdiv_qr(Q, R, pow, dprod); /* compute 2*s*s^(-1) - 1 for condition check */ mpz_mul_ui(cond, s, 2); mpz_mul(cond, cond, sinv); mpz_sub_ui(cond, cond, 1); if(mpz_cmp(cond, R) > 0) { mpz_mul(Po, Q, dprod); mpz_add(Po, Po, cond); } else /* cond < R */ { mpz_add_ui(Q, Q, 1); mpz_mul(Po, Q, dprod); mpz_add(Po, Po, cond); } /* TODO: fix the magic number and use 2k < 2^t limit */ for(k = 0; k < 0.35*(length-1); ++k) { mpz_mul_ui(prime, dprod, k); mpz_add(prime, prime, Po); /* exit loop if the number is definately prime (return value is 2) */ if(mpz_probab_prime_p(prime, 40)) break; } mpz_clear(sinv); mpz_clear(pow); mpz_clear(dprod); mpz_clear(Q); mpz_clear(R); mpz_clear(cond); mpz_clear(Po); }
void *chudnovsky_chunk(void *arguments) { unsigned long int k, threek, total_iterations; mpz_t a, b, c, d, e, rt, rb; mpf_t rtf, rbf, r; struct thread_args *args = (struct thread_args *)arguments; total_iterations = args->iter; /* Init libgmp variables */ mpz_inits(a, b, c, d, e, rt, rb, NULL); mpf_inits(rtf, rbf, r, NULL); /* Main loop of a thread */ while (1) { /* Check which k needs calculation */ pthread_mutex_lock(&args->start_mutex); k = args->k; args->k++; pthread_mutex_unlock(&args->start_mutex); /* If all ks are done, say return */ if (k > total_iterations) break; /* 3k */ threek = k * 3; /* (6k!) */ mpz_fac_ui(a, threek << 1); /* 545140134k */ mpz_set_ui(b, BCONST1); mpz_mul_ui(b, b, k); /* 13591409 + 545140134k */ mpz_add_ui(b, b, BCONST2); /* (3k)! */ mpz_fac_ui(c, threek); /* (k!)^3 */ mpz_fac_ui(d, k); mpz_pow_ui(d, d, DCONST1); /* (-640320)^3k */ mpz_set_ui(e, ECONST1); mpz_pow_ui(e, e, threek); if ((threek & 1) == 1) mpz_neg(e, e); /* Get everything together */ /* (6k)! (13591409 + 545140134k) */ mpz_mul(rt, a, b); /* (3k)! (k!)^3 */ mpz_mul(rb, c, d); mpz_mul(rb, rb, e); /* Switch to floats */ mpf_set_z(rtf, rt); mpf_set_z(rbf, rb); /* divide top/bottom */ mpf_div(r, rtf, rbf); /* add result to the sum */ pthread_mutex_lock(&args->sum_mutex); mpf_add(args->sum, args->sum, r); pthread_mutex_unlock(&args->sum_mutex); } /* Deinit variables, result is passed via args->sum */ mpz_clears(a, b, c, d, e, rt, rb, NULL); mpf_clears(rtf, rbf, r, NULL); }
int main(int argc, char *argv[]) { if(argc != 4) { printf("Three arguments required\n"); printf("Usage: %s a b c calculates pi(a*b^c)\n", argv[0]); exit(1); } //Legacy GMP code below; the input must fit in a 64 bit unsigned integer mpz_t n; mpz_init(n); mpz_ui_pow_ui(n, atol(argv[2]), atol(argv[3])); mpz_mul_ui(n, n, atol(argv[1])); uint64_t n2 = mpz_get_ui(n); mpz_clear(n); uint64_t* s = calloc(n2/64+3, sizeof(uint64_t)); assert(s != NULL); //for wheel mod 30 uint64_t wheel_pattern[15]; init(wheel_pattern); uint64_t k; for(k=0; k <= n2/64; k++) s[k] = wheel_pattern[k%15]; uint64_t sieve_to = floor(sqrt(n2)); uint64_t i,j; i=7; //7 is the first number > 1 which is relatively prime to 30 while (i <= sieve_to) { if(TEST(s, i) != 0) //Only sieve by primes { switch(i%30) { case 1: for(j=i*i; j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+6); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+10); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+12); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+16); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+18); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+22); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+28); j<=n2; j+= 30*i) CLEAR(s, j); break; case 7: for(j=i*i; j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+4); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+6); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+10); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+12); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+16); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+22); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+24); j<=n2; j+= 30*i) CLEAR(s, j); break; case 11: for(j=i*(i+0); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+2); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+6); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+8); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+12); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+18); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+20); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+26); j<=n2; j+= 30*i) CLEAR(s, j); break; case 13: for(j=i*(i+0); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+4); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+6); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+10); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+16); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+18); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+24); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+28); j<=n2; j+= 30*i) CLEAR(s, j); break; case 17: for(j=i*(i+0); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+2); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+6); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+12); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+14); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+20); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+24); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+26); j<=n2; j+= 30*i) CLEAR(s, j); break; case 19: for(j=i*(i+0); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+4); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+10); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+12); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+18); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+22); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+24); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+28); j<=n2; j+= 30*i) CLEAR(s, j); break; case 23: for(j=i*(i+0); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+6); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+8); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+14); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+18); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+20); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+24); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+26); j<=n2; j+= 30*i) CLEAR(s, j); break; case 29: for(j=i*(i+0); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+2); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+8); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+12); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+14); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+18); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+20); j<=n2; j+= 30*i) CLEAR(s, j); for(j=i*(i+24); j<=n2; j+= 30*i) CLEAR(s, j); break; default: printf("Error\n"); exit(1); } } i += get_next(i); //Advance pointer to the next number } #if 0 for(i=0; i<=n2; i++) if(TEST(s,i)>0) printf("%" PRIu64 "\n",i); #endif //Note ridiculous macro format required to print unit64_t without generating a compiler warning printf("%" PRIu64 "\n", count_bits(s, 0, n2)+2); free(s); return(0); }
int mpfr_set_str (mpfr_ptr x, __gmp_const char *str, int base, mp_rnd_t rnd_mode) { mpz_t mantissa; int negative, inex; long k = 0; unsigned char c; long e; mp_prec_t q; mpfr_t y, z; if (base < 2 || base > 36) return 1; if (strcasecmp(str, "NaN") == 0) { MPFR_SET_NAN(x); /* MPFR_RET_NAN not used as the return value isn't a ternary value */ __mpfr_flags |= MPFR_FLAGS_NAN; return 0; } negative = *str == '-'; if (negative || *str == '+') str++; if (strcasecmp(str, "Inf") == 0) { MPFR_CLEAR_NAN(x); MPFR_SET_INF(x); if (negative) MPFR_SET_NEG(x); else MPFR_SET_POS(x); return 0; } mpz_init(mantissa); mpz_set_ui(mantissa, 0); while (*str == '0') str++; /* skip initial zeros */ /* allowed characters are '0' to '0'+base-1 if base <= 10, and '0' to '9' plus 'a' to 'a'+base-11 if 10 < base <= 36 */ while (c = *str, (isdigit(c) && c < '0' + base) || (islower(c) && c < 'a'-10 + base)) { str++; mpz_mul_ui(mantissa, mantissa, base); mpz_add_ui(mantissa, mantissa, isdigit(c) ? c - '0' : c - ('a'-10)); } /* k is the number of non-zero digits before the decimal point */ if (*str == '.') { str++; while (c = *str, (isdigit(c) && c < '0' + base) || (islower(c) && c < 'a'-10 + base)) { if (k == LONG_MAX) { mpz_clear(mantissa); return -1; } k++; str++; mpz_mul_ui(mantissa, mantissa, base); mpz_add_ui(mantissa, mantissa, isdigit(c) ? c - '0' : c - ('a'-10)); } } if (*str == '\0') /* no exponent */ { e = -k; } else if ((base <= 10 && (*str == 'e' || *str == 'E')) || *str == '@') { char *endptr; if (*++str == '\0') /* exponent character but no exponent */ { mpz_clear(mantissa); return 1; } errno = 0; e = strtol(str, &endptr, 10); /* signed exponent after 'e', 'E' or '@' */ if (*endptr != '\0') { mpz_clear(mantissa); return 1; } if (errno) { mpz_clear(mantissa); return -1; } if (e < 0 && (unsigned long) e - k < (unsigned long) LONG_MIN) { mpz_clear(mantissa); return -1; } e -= k; } else /* unexpected character */ { mpz_clear(mantissa); return 1; } /* the number is mantissa*base^expn */ q = MPFR_PREC(x) & ~(mp_prec_t) (BITS_PER_MP_LIMB - 1); mpfr_init(y); mpfr_init(z); do { q += BITS_PER_MP_LIMB; mpfr_set_prec(y, q); mpfr_set_z(y, mantissa, GMP_RNDN); /* error <= 1/2*ulp(y) */ mpfr_set_prec(z, q); if (e > 0) { inex = mpfr_ui_pow_ui(z, base, e, GMP_RNDN); mpfr_mul(y, y, z, GMP_RNDN); } else if (e < 0) { inex = mpfr_ui_pow_ui(z, base, -e, GMP_RNDN); mpfr_div(y, y, z, GMP_RNDN); } else inex = 1; if (negative) mpfr_neg(y, y, GMP_RNDN); } while (mpfr_can_round(y, q-inex, GMP_RNDN, rnd_mode, MPFR_PREC(x))==0 && q<=2*MPFR_PREC(x)); mpfr_set(x, y, rnd_mode); mpz_clear(mantissa); mpfr_clear(y); mpfr_clear(z); return 0; }
/* Compute the first 2^m terms from the hypergeometric series with x = p / 2^r */ static int GENERIC (mpfr_ptr y, mpz_srcptr p, long r, int m) { unsigned long n,i,k,j,l; int is_p_one; mpz_t* P,*S; #ifdef A mpz_t *T; #endif mpz_t* ptoj; #ifdef R_IS_RATIONAL mpz_t* qtoj; mpfr_t tmp; #endif mp_exp_t diff, expo; mp_prec_t precy = MPFR_PREC(y); MPFR_TMP_DECL(marker); MPFR_TMP_MARK(marker); MPFR_CLEAR_FLAGS(y); n = 1UL << m; P = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t)); S = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t)); ptoj = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t)); /* ptoj[i] = mantissa^(2^i) */ #ifdef A T = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t)); #endif #ifdef R_IS_RATIONAL qtoj = (mpz_t*) MPFR_TMP_ALLOC ((m+1) * sizeof(mpz_t)); #endif for (i = 0 ; i <= m ; i++) { mpz_init (P[i]); mpz_init (S[i]); mpz_init (ptoj[i]); #ifdef R_IS_RATIONAL mpz_init (qtoj[i]); #endif #ifdef A mpz_init (T[i]); #endif } mpz_set (ptoj[0], p); #ifdef C # if C2 != 1 mpz_mul_ui (ptoj[0], ptoj[0], C2); # endif #endif is_p_one = mpz_cmp_ui(ptoj[0], 1) == 0; #ifdef A # ifdef B mpz_set_ui (T[0], A1 * B1); # else mpz_set_ui (T[0], A1); # endif #endif if (!is_p_one) for (i = 1 ; i < m ; i++) mpz_mul (ptoj[i], ptoj[i-1], ptoj[i-1]); #ifdef R_IS_RATIONAL mpz_set_si (qtoj[0], r); for (i = 1 ; i <= m ; i++) mpz_mul(qtoj[i], qtoj[i-1], qtoj[i-1]); #endif mpz_set_ui (P[0], 1); mpz_set_ui (S[0], 1); k = 0; for (i = 1 ; i < n ; i++) { k++; #ifdef A # ifdef B mpz_set_ui (T[k], (A1 + A2*i)*(B1+B2*i)); # else mpz_set_ui (T[k], A1 + A2*i); # endif #endif #ifdef C # ifdef NO_FACTORIAL mpz_set_ui (P[k], (C1 + C2 * (i-1))); mpz_set_ui (S[k], 1); # else mpz_set_ui (P[k], (i+1) * (C1 + C2 * (i-1))); mpz_set_ui (S[k], i+1); # endif #else # ifdef NO_FACTORIAL mpz_set_ui (P[k], 1); # else mpz_set_ui (P[k], i+1); # endif mpz_set (S[k], P[k]); #endif for (j = i+1, l = 0 ; (j & 1) == 0 ; l++, j>>=1, k--) { if (!is_p_one) mpz_mul (S[k], S[k], ptoj[l]); #ifdef A # ifdef B # if (A2*B2) != 1 mpz_mul_ui (P[k], P[k], A2*B2); # endif # else # if A2 != 1 mpz_mul_ui (P[k], P[k], A2); # endif #endif mpz_mul (S[k], S[k], T[k-1]); #endif mpz_mul (S[k-1], S[k-1], P[k]); #ifdef R_IS_RATIONAL mpz_mul (S[k-1], S[k-1], qtoj[l]); #else mpz_mul_2exp (S[k-1], S[k-1], r*(1<<l)); #endif mpz_add (S[k-1], S[k-1], S[k]); mpz_mul (P[k-1], P[k-1], P[k]); #ifdef A mpz_mul (T[k-1], T[k-1], T[k]); #endif } } diff = mpz_sizeinbase(S[0],2) - 2*precy; expo = diff; if (diff >= 0) mpz_div_2exp(S[0],S[0],diff); else mpz_mul_2exp(S[0],S[0],-diff); diff = mpz_sizeinbase(P[0],2) - precy; expo -= diff; if (diff >=0) mpz_div_2exp(P[0],P[0],diff); else mpz_mul_2exp(P[0],P[0],-diff); mpz_tdiv_q(S[0], S[0], P[0]); mpfr_set_z(y, S[0], GMP_RNDD); MPFR_SET_EXP (y, MPFR_GET_EXP (y) + expo); #ifdef R_IS_RATIONAL /* exact division */ mpz_div_ui (qtoj[m], qtoj[m], r); mpfr_init2 (tmp, MPFR_PREC(y)); mpfr_set_z (tmp, qtoj[m] , GMP_RNDD); mpfr_div (y, y, tmp, GMP_RNDD); mpfr_clear (tmp); #else mpfr_div_2ui(y, y, r*(i-1), GMP_RNDN); #endif for (i = 0 ; i <= m ; i++) { mpz_clear (P[i]); mpz_clear (S[i]); mpz_clear (ptoj[i]); #ifdef R_IS_RATIONAL mpz_clear (qtoj[i]); #endif #ifdef A mpz_clear (T[i]); #endif } MPFR_TMP_FREE (marker); return 0; }
bool try_depth(ulong depth) { frame_t *cur = &(stack[depth]); frame_t *next = &(stack[depth + 1]); int final = (depth + 1 >= max_depth) ? 1 : 0; bool locally_solved = 0; ulong bits_num, bits_den; ++count; if ((count & 0xfffffff) == 0) report_progress(depth); mpq_inv(next->q, cur->q); /* if final, we only care whether we can reach 1 */ if (final) { mpq_sub(next->q, next->q, rone); if (mpq_sgn(next->q) < 0) return 0; mpq_div(next->q, next->q, r); if (mpz_cmp_ui(mpq_denref(next->q), (ulong)1) != 0) return 0; next->count = mpz_strict_get_ui(mpq_numref(next->q)); report_depth(depth + 1); return 1; } if (mpq_cmp(next->q, limit) <= 0) { next->count = (ulong)0; } else { /* count = floor((q - limit) / r) */ mpq_sub(limit_calc, next->q, limit); mpq_div(limit_calc, limit_calc, r); mpz_fdiv_q(limit_div, mpq_numref(limit_calc), mpq_denref(limit_calc)); next->count = mpz_strict_get_ui(limit_div); /* q -= count * r */ mpq_set(limit_calc, r); mpz_mul_ui(mpq_numref(limit_calc), mpq_numref(limit_calc), next->count); mpq_canonicalize(limit_calc); mpq_sub(next->q, next->q, limit_calc); } /* now we've guaranteed curq - r <= limit, so all values we find are * useful. */ /* while ((q -= r) > 0) { ... } */ while (1) { mpq_sub(next->q, next->q, r); if (mpq_sgn(next->q) <= 0) return locally_solved; ++next->count; if (mpq_equal(next->q, rone)) { report_depth(depth + 1); max_depth = depth + 1; solved = 1; return 1; } ++next->actual; bits_num = mpz_bitsize(mpq_numref(next->q)); if (!next->best_bits_num || next->best_bits_num >= bits_num) { next->best_bits_num = bits_num; bits_den = mpz_bitsize(mpq_denref(next->q)); if (!next->best_bits_den || next->best_bits_den > bits_den) next->best_bits_den = bits_den; } /* and recurse */ if (try_depth(depth + 1)) locally_solved = 1; } /* not reached */ }
/* s <- 1 + r/1! + r^2/2! + ... + r^l/l! while MPFR_EXP(r^l/l!)+MPFR_EXPR(r)>-q using Brent/Kung method with O(sqrt(l)) multiplications. Return l. Uses m multiplications of full size and 2l/m of decreasing size, i.e. a total equivalent to about m+l/m full multiplications, i.e. 2*sqrt(l) for m=sqrt(l). Version using mpz. ss must have at least (sizer+1) limbs. The error is bounded by (l^2+4*l) ulps where l is the return value. */ static int mpfr_exp2_aux2 (mpz_t s, mpfr_srcptr r, int q, int *exps) { int expr, l, m, i, sizer, *expR, expt, ql; unsigned long int c; mpz_t t, *R, rr, tmp; TMP_DECL(marker); /* estimate value of l */ l = q / (-MPFR_EXP(r)); m = (int) _mpfr_isqrt (l); /* we access R[2], thus we need m >= 2 */ if (m < 2) m = 2; TMP_MARK(marker); R = (mpz_t*) TMP_ALLOC((m+1)*sizeof(mpz_t)); /* R[i] stands for r^i */ expR = (int*) TMP_ALLOC((m+1)*sizeof(int)); /* exponent for R[i] */ sizer = 1 + (MPFR_PREC(r)-1)/BITS_PER_MP_LIMB; mpz_init(tmp); MY_INIT_MPZ(rr, sizer+2); MY_INIT_MPZ(t, 2*sizer); /* double size for products */ mpz_set_ui(s, 0); *exps = 1-q; /* initialize s to zero, 1 ulp = 2^(1-q) */ for (i=0;i<=m;i++) MY_INIT_MPZ(R[i], sizer+2); expR[1] = mpfr_get_z_exp(R[1], r); /* exact operation: no error */ expR[1] = mpz_normalize2(R[1], R[1], expR[1], 1-q); /* error <= 1 ulp */ mpz_mul(t, R[1], R[1]); /* err(t) <= 2 ulps */ mpz_div_2exp(R[2], t, q-1); /* err(R[2]) <= 3 ulps */ expR[2] = 1-q; for (i=3;i<=m;i++) { mpz_mul(t, R[i-1], R[1]); /* err(t) <= 2*i-2 */ mpz_div_2exp(R[i], t, q-1); /* err(R[i]) <= 2*i-1 ulps */ expR[i] = 1-q; } mpz_set_ui(R[0], 1); mpz_mul_2exp(R[0], R[0], q-1); expR[0]=1-q; /* R[0]=1 */ mpz_set_ui(rr, 1); expr=0; /* rr contains r^l/l! */ /* by induction: err(rr) <= 2*l ulps */ l = 0; ql = q; /* precision used for current giant step */ do { /* all R[i] must have exponent 1-ql */ if (l) for (i=0;i<m;i++) { expR[i] = mpz_normalize2(R[i], R[i], expR[i], 1-ql); } /* the absolute error on R[i]*rr is still 2*i-1 ulps */ expt = mpz_normalize2(t, R[m-1], expR[m-1], 1-ql); /* err(t) <= 2*m-1 ulps */ /* computes t = 1 + r/(l+1) + ... + r^(m-1)*l!/(l+m-1)! using Horner's scheme */ for (i=m-2;i>=0;i--) { mpz_div_ui(t, t, l+i+1); /* err(t) += 1 ulp */ mpz_add(t, t, R[i]); } /* now err(t) <= (3m-2) ulps */ /* now multiplies t by r^l/l! and adds to s */ mpz_mul(t, t, rr); expt += expr; expt = mpz_normalize2(t, t, expt, *exps); /* err(t) <= (3m-1) + err_rr(l) <= (3m-2) + 2*l */ #ifdef DEBUG if (expt != *exps) { fprintf(stderr, "Error: expt != exps %d %d\n", expt, *exps); exit(1); } #endif mpz_add(s, s, t); /* no error here */ /* updates rr, the multiplication of the factors l+i could be done using binary splitting too, but it is not sure it would save much */ mpz_mul(t, rr, R[m]); /* err(t) <= err(rr) + 2m-1 */ expr += expR[m]; mpz_set_ui (tmp, 1); for (i=1, c=1; i<=m; i++) { if (l+i > ~((unsigned long int) 0)/c) { mpz_mul_ui(tmp, tmp, c); c = l+i; } else c *= (unsigned long int) l+i; } if (c != 1) mpz_mul_ui (tmp, tmp, c); /* tmp is exact */ mpz_fdiv_q(t, t, tmp); /* err(t) <= err(rr) + 2m */ expr += mpz_normalize(rr, t, ql); /* err_rr(l+1) <= err_rr(l) + 2m+1 */ ql = q - *exps - mpz_sizeinbase(s, 2) + expr + mpz_sizeinbase(rr, 2); l+=m; } while (expr+mpz_sizeinbase(rr, 2) > -q); TMP_FREE(marker); mpz_clear(tmp); return l; }
// Mine probable prime chain of form: n = h * p# +/- 1 bool MineProbablePrimeChain(Reap_CPU_param* state, Work& tempwork, CSieveOfEratosthenes& psieve, mpz_class& mpzFixedMultiplier, bool& fNewBlock, unsigned int& nTriedMultiplier, unsigned int& nProbableChainLength, unsigned int& nTests, unsigned int& nPrimesHit, unsigned int& nChainsHit, mpz_class& mpzHash, unsigned int nPrimorialMultiplier) { nProbableChainLength = 0; nPrimesHit = 0; nChainsHit = 0; //const unsigned int nBits = block.nBits; const unsigned int nBits = *(uint*)&tempwork.data[72]; bool use_gpu_fermat_test = globalconfs.coin.config.GetValue<bool>("use_gpu_fermat_test"); if (fNewBlock && psieve.inited) { // Must rebuild the sieve psieve.Deinit(); } fNewBlock = false; int64 nStart; // microsecond timer if (!psieve.inited) { // Build sieve nStart = ticker()*1000; psieve.InitAndWeave(state, nSieveSize, nBits, mpzHash, mpzFixedMultiplier); if (globalconfs.coin.config.GetValue<bool>("debug")) printf("MineProbablePrimeChain() : new sieve (%lu/%u) ready in %uus\n", psieve.CandidateList.size(), nSieveSize, (unsigned int) (ticker()*1000 - nStart)); } mpz_class mpzHashMultiplier = mpzHash * mpzFixedMultiplier; mpz_class mpzChainOrigin; // Determine the sequence number of the round primorial unsigned int nPrimorialSeq = 0; while (vPrimes[nPrimorialSeq + 1] <= nPrimorialMultiplier) nPrimorialSeq++; // Allocate GMP variables for primality tests CPrimalityTestParams testParams(nBits, nPrimorialSeq); nStart = ticker()*1000; // References to counters; unsigned int& nChainLengthCunningham1 = testParams.nChainLengthCunningham1; unsigned int& nChainLengthCunningham2 = testParams.nChainLengthCunningham2; unsigned int& nChainLengthBiTwin = testParams.nChainLengthBiTwin; //cout << "PSIEVIOSIE" << psieve.CandidateList.size() << endl; for(uint i=0; i<psieve.CandidateList.size(); ++i) { nTriedMultiplier = psieve.CandidateList[i]&0x3FFFFFFFU; uint sievenumber = psieve.CandidateList[i]>>30; if (sievenumber == 0) sievenumber=3; if (nTriedMultiplier == 0) //will crash otherwise continue; ++nTests; if (tempwork.time != current_work.time) { //cout << "Tempwork.time != curnetopqi" << tempwork.time << " " << current_work.time << endl; break; } mpzChainOrigin = mpzHashMultiplier * (nTriedMultiplier&0x3FFFFFFFU); nChainLengthCunningham1 = 0; nChainLengthCunningham2 = 0; nChainLengthBiTwin = 0; if (ProbablePrimeChainTestFast(mpzChainOrigin, testParams, sievenumber, use_gpu_fermat_test)) { mpz_t mpzPrimeChainMultiplier; mpz_init(mpzPrimeChainMultiplier); mpz_mul_ui(mpzPrimeChainMultiplier,mpzFixedMultiplier.get_mpz_t(),nTriedMultiplier); { //gmp_printf("Found chain! Mult: %Zx\n",mpzPrimeChainMultiplier); vector<uchar> auxdata = XPM_create_auxdata(&mpzPrimeChainMultiplier); CPU_Got_share(state,tempwork,auxdata); } mpz_clear(mpzPrimeChainMultiplier); nProbableChainLength = std::max(std::max(nChainLengthCunningham1, nChainLengthCunningham2), nChainLengthBiTwin); return true; } nProbableChainLength = std::max(std::max(nChainLengthCunningham1, nChainLengthCunningham2), nChainLengthBiTwin); if(TargetGetLength(nProbableChainLength) >= 1) nPrimesHit++; if(TargetGetLength(nProbableChainLength) >= nStatsChainLength) nChainsHit++; } // power tests completed for the sieve //if (fDebug && GetBoolArg("-printmining")) //printf("MineProbablePrimeChain() : %u tests (%u primes and %u %d-chains) in %uus\n", nTests, nPrimesHit, nChainsHit, nStatsChainLength, (unsigned int) (GetTimeMicros() - nStart)); psieve.Deinit(); fNewBlock = true; // notify caller to change nonce return false; // stop as new block arrived }
int main(int argc, char** argv) { int my_rank, p; int i, dest; mpz_t currentPrime; unsigned long int product; sscanf(argv[1], "%lu", &product); int secondFactor = 0; int bcastStatus; int equals; /** GMP library variables **/ mpz_t nextPrimeNumber; mpz_t testFactor; mpz_init(nextPrimeNumber); mpz_init_set_str (nextPrimeNumber, argv[1], 10); mpz_init(testFactor); mpz_init_set_ui(currentPrime, 2); mpz_nextprime(nextPrimeNumber, nextPrimeNumber); mpz_t testProduct; mpz_init(testProduct); /** MPI Initialization **/ MPI_Request finalValue; MPI_File out; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &p); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); MPI_Status status; /** Get Ready to receive a factor if another process finds one */ MPI_Irecv(&secondFactor, 1, MPI_UNSIGNED_LONG, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &finalValue); /** Prepare initial offset for each process **/ for (i=0 ; i < my_rank ; i++) { mpz_nextprime(currentPrime, currentPrime); } /** Start Timing **/ double start = MPI_Wtime(), diff; while (!secondFactor) { /** Check if another process has found the factors **/ MPI_Test (&finalValue, &bcastStatus, &status); if(bcastStatus) { /** Somebody else has found the factors, we are done **/ MPI_Wait(&finalValue, &status); break; } /** Skip P primes before checking again **/ for (i=0 ; i < p ; i++) { mpz_nextprime(currentPrime, currentPrime); } /** Brute force check if the current working prime is a factor of the input number **/ for (mpz_set_ui(testFactor , 2) ; mpz_get_ui(testFactor) <= mpz_get_ui(currentPrime); mpz_nextprime(testFactor, testFactor)) { /** Check if another process has found the factors **/ MPI_Test (&finalValue, &bcastStatus, &status); if(bcastStatus) { MPI_Wait(&finalValue, &status); break; } mpz_mul_ui(testProduct, currentPrime, mpz_get_ui(testFactor)); equals = mpz_cmp_ui(testProduct, product); if (equals == 0){ /** We've found the factor, find the second number, secnd it to the other processes **/ secondFactor = mpz_get_ui(testFactor); printf("done by process %d, factors are %lu and %d \n", my_rank, mpz_get_ui(currentPrime), secondFactor); fflush(stdout); for (dest = 0 ; dest < p ; dest++) { if (dest != my_rank) { MPI_Send(&secondFactor, 1, MPI_UNSIGNED_LONG, dest, 0, MPI_COMM_WORLD); } } } } } diff = MPI_Wtime() - start; /** End Timing **/ /** Prepare file contents **/ char fileName[200], fileContents[200]; sprintf(fileName, "time_%lu", product); sprintf(fileContents, "%d\t%f\n", my_rank, diff); /** Write File **/ MPI_File_open( MPI_COMM_WORLD, fileName, MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &out ); MPI_File_seek(out, my_rank*strlen ( fileContents ) , MPI_SEEK_SET); MPI_File_write_all(out , &fileContents, strlen ( fileContents ), MPI_CHAR, &status ); MPI_File_close(&out); /** Fin **/ MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); return(0); }
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_ptr rands; mpz_t bs; unsigned long bsi, size_range; unsigned long r_rq, r_q, r_r, r; tests_start (); rands = 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_tdiv_qr_ui (quotient, remainder, dividend, divisor); r_q = mpz_tdiv_q_ui (quotient2, dividend, divisor); r_r = mpz_tdiv_r_ui (remainder2, dividend, divisor); r = mpz_tdiv_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_tdiv_qr_ui and mpz_tdiv_q_ui differ", dividend, divisor); if (mpz_cmp (remainder, remainder2) != 0) dump_abort ("remainders from mpz_tdiv_qr_ui and mpz_tdiv_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 same sign as the dividend (quotient rounded towards 0). */ if (mpz_cmp_ui (remainder, 0) != 0) if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (dividend, 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_tdiv_qr_ui is wrong", dividend, divisor); if (mpz_cmp_ui (remainder, r_q) != 0) dump_abort ("remainder returned from mpz_tdiv_q_ui is wrong", dividend, divisor); if (mpz_cmp_ui (remainder, r_r) != 0) dump_abort ("remainder returned from mpz_tdiv_r_ui is wrong", dividend, divisor); if (mpz_cmp_ui (remainder, r) != 0) dump_abort ("remainder returned from mpz_tdiv_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); tests_end (); exit (0); }
void main(int argc, char **argv) { if ( argc != 3 ) { printf("Usage: %s (filename) (number of entries)\n", argv[0]); exit(1); } FILE *fp; char buf[12]; table t; mpz_t u; ulint i, count, invalid, found; unsigned long long phonenum; unsigned long long *numlist; struct timeval starttime, endtime; ulint starttime_us, endtime_us; if ( (fp = fopen(argv[1], "r")) == NULL ) { printf("Could not open file: %s\n", argv[1]); } sscanf(argv[2], "%ld", &count); numlist = (unsigned long long *)calloc( count, sizeof(unsigned long long)); mpz_init(u); mpz_set_ui(u, 1000 * 1000); mpz_mul_ui(u, u, 10000); table_init(&t, count, u); srand(time(NULL)); i = 0; invalid = 0; while ( fgets(buf, 12, fp) != NULL ) { sscanf(buf, "%lld\n", &phonenum); numlist[i] = phonenum; if (rand() <= PROB_INVALID * RAND_MAX) { numlist[i] = numlist[i] / 4; invalid++; } table_insert(&t, phonenum); i++; } fclose(fp); printf("Building table...\n"); table_build(&t); printf("Done inserting %ld numbers (%ld invalids)\n", i, invalid); i = 0; found = 0; invalid = 0; gettimeofday(&starttime, NULL); while ( i < count ) { if ( table_find(&t, numlist[i]) ) { found++; } else { invalid++; } i++; } gettimeofday(&endtime, NULL); starttime_us = starttime.tv_sec*1000000 + starttime.tv_usec; endtime_us = endtime.tv_sec*1000000 + endtime.tv_usec; printf("Found %ld numbers, rejected %ld\n", found, invalid); printf("Total find time: %ld us\n", endtime_us-starttime_us); free(numlist); table_destroy(&t); mpz_clear(u); }
void tiny_poly_init(QS_t * qs_inf, poly_t * poly_inf, mpz_t N) { unsigned long num_primes = qs_inf->num_primes; unsigned long s = (qs_inf->bits-1)/28+1; if (s <= 2) s = 3; prime_t * factor_base = qs_inf->factor_base; unsigned long fact_approx, fact, span; long min; poly_inf->s = s; poly_inf->B_terms = (unsigned long*) flint_stack_alloc(s); poly_inf->A_ind = (unsigned long*) flint_stack_alloc(s); poly_inf->A_modp = (unsigned long*) flint_stack_alloc(s); poly_inf->A_inv2B = (unsigned long**) flint_stack_alloc(s); poly_inf->inv_p2 = (double*) flint_stack_alloc_bytes(s*sizeof(double)); poly_inf->A_inv = (unsigned long*) flint_stack_alloc(num_primes); poly_inf->soln1 = (unsigned long*) flint_stack_alloc(num_primes); poly_inf->soln2 = (unsigned long*) flint_stack_alloc(num_primes); unsigned long ** A_inv2B = poly_inf->A_inv2B; A_inv2B[0] = (unsigned long *) flint_stack_alloc(num_primes*s); mpz_init(poly_inf->C); unsigned long i; for (i = 1; i < s; i++) { A_inv2B[i] = A_inv2B[i-1] + num_primes; } mpz_t temp; mpz_init(temp); mpz_mul_ui(temp, N, 2*qs_inf->k); mpz_sqrt(temp, temp); mpz_div_ui(temp, temp, 300); poly_inf->target_A = mpz_get_ui(temp); mpz_root(temp, temp, s); fact_approx = mpz_get_ui(temp); for (fact = 0; fact_approx >= factor_base[fact].p; fact++); span = num_primes/s/s/2; if (span < 6*s) span = 6*s; min = fact - span/2; if (min < SMALL_PRIMES) min = SMALL_PRIMES; if (min + span >= num_primes - 1) span = num_primes - min - 1; fact = min + span/2; #if POLY_PARAMS printf("num_primes = %ld, min = FB[%ld], span = %ld, number of factors = %ld\n", num_primes, min, span, s); #endif poly_inf->min = min; poly_inf->fact = fact; poly_inf->span = span; mpz_clear(temp); }