static void precision_init(int prec) { int i; mpf_t f0; mpf_set_default_prec(prec); mpf_init2(epsilon, 2); mpf_init2(negepsilon, 2); mpf_init(recipeulere); mpf_init(pi); mpf_init(eulere); mpf_set_ui(epsilon, 1); mpf_div_2exp(epsilon, epsilon, prec); mpf_neg(negepsilon, epsilon); mpf_init(f0); mpf_set_ui(eulere, 1); mpf_set_ui(f0, 1); for (i=1;; i++) { mpf_div_ui(f0, f0, i); if (mpf_cmp(f0, epsilon) < 0) { break; } mpf_add(eulere, eulere, f0); } mpf_clear(f0); mpf_ui_div(recipeulere, 1, eulere); compute_pi(prec); }
void extrapolate(index_t num_samples, mpf_t *samples, mpf_t ans) { // The Richardson extrapolation recursive formula is // // A_n+1(x) = (2^n A_n(2x) - A_n(x)) / (2^n - 1) mpf_t mult; // mult = 2^n mpf_init_set_d(mult, 1); mpf_t denom; // denom = 1 / (mult - 1) mp_bitcnt_t precision = mpf_get_prec(ans); mpf_init2(denom, precision); mpf_t *end = samples + num_samples; for (mpf_t *lim = samples; lim < end; lim++) { // lim - samples = n mpf_mul_ui(mult, mult, 2); mpf_set(denom, mult); mpf_sub_ui(denom, denom, 1); mpf_ui_div(denom, 1, denom); // evaluate all extrapolations for (mpf_t *ptr = end; --ptr > lim; ) { // A_n+1(x) = (mult A_n(2x) - A_n(x)) * denom mpf_mul(*ptr, *ptr, mult); mpf_sub(*ptr, *ptr, *(ptr - 1)); mpf_mul(*ptr, *ptr, denom); } } mpf_set(ans, *(end - 1)); // move to ans // Clean mpf_clear(mult); mpf_clear(denom); }
Float Float::pow(const long exponent) const { Float result(*this); if (exponent < 0) mpf_ui_div(result.value, 1, result.value); mpf_pow_ui(result.value, result.value, std::abs(exponent)); return result; }
// r = y/x WARNING: r cannot be the same as y. void my_div(mpf_t r, mpf_t y, mpf_t x) { unsigned long prec, bits, prec0; prec0 = mpf_get_prec(r); if (prec0<=DOUBLE_PREC) { mpf_set_d(r, mpf_get_d(y)/mpf_get_d(x)); return; } bits = 0; for (prec=prec0; prec>DOUBLE_PREC;) { int bit = prec&1; prec = (prec+bit)/2; bits = bits*2+bit; } mpf_set_prec_raw(t1, DOUBLE_PREC); mpf_ui_div(t1, 1, x); while (prec<prec0) { prec *=2; if (prec<prec0) { /* t1 = t1+t1*(1-x*t1); */ mpf_set_prec_raw(t2, prec); mpf_mul(t2, x, t1); // full x half -> full mpf_ui_sub(t2, 1, t2); mpf_set_prec_raw(t2, prec/2); mpf_mul(t2, t2, t1); // half x half -> half mpf_set_prec_raw(t1, prec); mpf_add(t1, t1, t2); } else { prec = prec0; /* t2=y*t1, t1 = t2+t1*(y-x*t2); */ mpf_set_prec_raw(t2, prec/2); mpf_mul(t2, t1, y); // half x half -> half mpf_mul(r, x, t2); // full x half -> full mpf_sub(r, y, r); mpf_mul(t1, t1, r); // half x half -> half mpf_add(r, t1, t2); break; } prec -= (bits&1); bits /=2; } }
// The Brent-Salamin algorithm int main(int argc, char* argv[]) { if (argc < 2) return -1; int n = (int)strtol(argv[1], NULL, 10); mpf_set_default_prec(1000); mpf_t a, b, t, c, sum; // a=1 mpf_init_set_ui(a, 1); mpf_init_set_ui(sum, 0); mpf_init(b); mpf_init(t); mpf_init(c); mpf_init(sum); // b=1/sqrt(2) mpf_sqrt_ui(b, 2); mpf_ui_div(b, 1, b); // n次迭代的误差小于\frac{2^{n+9}}{20^{2n+1}} for (int i = 1; i <= n; ++i) { // t=(a+b)/2 mpf_add(t, a, b); mpf_div_ui(t, t, 2); // b=sqrt(a*b); mpf_mul(b, a, b); mpf_sqrt(b, b); // a=t mpf_swap(t, a); mpf_mul(t, a, a); mpf_mul(c, b, b); mpf_sub(c, t, c); mpf_mul_2exp(c, c, i + 1); mpf_add(sum, sum, c); } mpf_mul(t, a, a); mpf_mul_ui(t, t, 4); mpf_ui_sub(sum, 1, sum); mpf_div(t, t, sum); mpf_out_str(stdout, 10, 0, t); printf("\n"); mpf_clear(a); mpf_clear(b); mpf_clear(t); mpf_clear(c); mpf_clear(sum); return 0; }
int main(void) { int i ; char buf[4096] ; mpf_t x, y , result ; mpf_set_default_prec(LIMIT); mpf_init ( x ); mpf_init ( y ); mpf_init (result) ; mpf_set_str(result, "1" , 10 ); for ( i = 1 ; i < LIMIT ; i++ ) { sprintf ( buf , "%d" , (2*i + 1) ) ; mpf_set_str(x, buf , 10 ); mpf_ui_div (y, 1, x) ; if ( i % 2 ) { mpf_sub ( x , result , y ) ; mpf_set (result , x) ; } else { mpf_add ( x , result , y ) ; mpf_set (result , x) ; } } mpf_mul_ui (x, result, 4 ) ; printf("\n pi = " ) ; mpf_out_str (stdout , 10, 0, x) ; printf ("\n") ; mpf_clear (x); mpf_clear (y); mpf_clear (result); return EXIT_SUCCESS; }
int main(void) { clock_t begin, end; mpf_set_default_prec(BITS_PER_DIGIT*DIGITS); //mpf_set_default_prec(4096); begin = clock(); mpf_init(x); mpf_init(y); mpf_init(p); mpf_init(aux1); mpf_init(aux2); mpf_init(sqrtx); mpf_init(invsqrtx); /* x = sqrt(2)*/ mpf_set_ui(x, 2); mpf_sqrt(x, x); /* y = sqrt(sqrt(2)) = sqrt(x)*/ mpf_sqrt(y, x); /* p = 2 + sqrt(2) = 2 + x*/ mpf_add_ui(p, x, 2); for (i=0; i<24; i++) { mpf_sqrt(sqrtx, x); mpf_ui_div(invsqrtx, 1, sqrtx); pthread_create(&t1, NULL, thread1, NULL); pthread_create(&t2, NULL, thread2, NULL); pthread_join(t1, NULL); pthread_join(t2, NULL); mpf_div(p, aux1, aux2); //Para ver os valores de pi a cada iteracao //mpf_out_str(stdout, 10, DIGITS, p); } mpf_out_str(stdout, 10, DIGITS, p); mpf_clear(x); mpf_clear(y); mpf_clear(p); mpf_clear(aux1); mpf_clear(aux2); mpf_clear(sqrtx); mpf_clear(invsqrtx); end = clock(); printf("Took %lfs\n", (double)(end-begin)/CLOCKS_PER_SEC); pthread_exit(0); }
void determine_pivot_tolerances(mpf_t pivot_tol, mpf_t pivot_drop_tol, int prec) /***************************************************************\ * USAGE: compute tolerances based on prec * \***************************************************************/ { int num_digits = (int) floor(prec * log10(2.0) - 2.5); // setup pivot_tol mpf_set_prec(pivot_tol, prec); mpf_set_ui(pivot_tol, 10); mpf_pow_ui(pivot_tol, pivot_tol, num_digits); mpf_ui_div(pivot_tol, 1, pivot_tol); // setup pivot_drop_tol mpf_set_prec(pivot_drop_tol, prec); mpf_set_ui(pivot_drop_tol, 10); mpf_pow_ui(pivot_drop_tol, pivot_drop_tol, num_digits - 3); return; }
/** * void initAttributes() * * Descricao: * Inicializa as variaveis globas e atribui os valores iniciais necessarios para a execucao do algoritmo * Gauss-Legendre. * * Parametros de entrada: * - * * Parametros de retorno: * - */ void initAttributes(){ /* Atribui como precisao default 10 milhoes de casas decimais. A funcao mpf_set_default_prec() tem como parametro de entrada * a precisao desejada em bits, ou seja, e necessario utilizar a conversao (log de 2 na base 10)*10 milhoes para obter o valor correto. */ mpf_set_default_prec((log(10)/log(2))*10000000); int i; mpf_t sqrt2; // Variavel auxiliar para o calculo de b0 mpf_t b0; // Variavel auxiliar para o calculo de b0 n_count = 0; /* Arrays de variaveis utilizadas pelo algoritmo. Como o algoritmo converge para o valor correto do "pi" com 45 milhoes de casas decimais * em apenas 25 iteracoes, serao utilizado arrays com 25 posicoes */ a_n = (mpf_t*) malloc(25*sizeof(mpf_t)); b_n = (mpf_t*) malloc(25*sizeof(mpf_t)); t_n = (mpf_t*) malloc(25*sizeof(mpf_t)); p_n = (mpf_t*) malloc(25*sizeof(mpf_t)); pi = (mpf_t*) malloc(25*sizeof(mpf_t)); for(i=0; i<25; i++){ mpf_init(a_n[i]); mpf_init(b_n[i]); mpf_init(p_n[i]); mpf_init(t_n[i]); mpf_init(pi[i]); } /* Atribuicao dos valores iniciais */ mpf_init(sqrt2); mpf_init(b0); mpf_sqrt_ui(sqrt2, 2); mpf_ui_div(b0, 1, sqrt2); mpf_set_d(a_n[n_count], 1.0); mpf_set(b_n[n_count], b0); mpf_set_d(t_n[n_count], 0.25); mpf_set_d(p_n[n_count], 1.0); }
/** * Algoritmo de Borwein * * vars.a1 se aproxima do valor de 1/PI. * Cada iteração quadruplica o número de dígitos corretos. * */ void gmp_borwein_par() { /*threads*/ pthread_t init[9], calc[4]; /*variáveis para calculos*/ thr_gmpf_t vars; mpf_set_default_prec(33219280);//(33219280); /*define a precisao do float em bits*/ vars.k = 0; /*Seta o valor inicial do iterador*/ calc[1] = 0; calc[3] = 0; /*Inicializa as variáveis em 0*/ pthread_create(&init[0],NULL,(void *)&mpf_init,(void *)&vars.a0); pthread_create(&init[1],NULL,(void *)&mpf_init,(void *)&vars.a1); pthread_create(&init[2],NULL,(void *)&mpf_init,(void *)&vars.y0); pthread_create(&init[3],NULL,(void *)&mpf_init,(void *)&vars.y1); pthread_create(&init[4],NULL,(void *)&mpf_init,(void *)&vars.aux_y1); pthread_create(&init[5],NULL,(void *)&mpf_init,(void *)&vars.aux_y2); pthread_create(&init[6],NULL,(void *)&mpf_init,(void *)&vars.aux_a1); pthread_create(&init[7],NULL,(void *)&mpf_init,(void *)&vars.aux_a2); pthread_create(&init[8],NULL,(void *)&mpf_init,(void *)&vars.y_valoratual); /*A função espera as variáveis serem atualizadas*/ pthread_join(init[0],NULL); pthread_join(init[1],NULL); pthread_join(init[2],NULL); pthread_join(init[3],NULL); pthread_join(init[4],NULL); pthread_join(init[5],NULL); pthread_join(init[6],NULL); pthread_join(init[7],NULL); pthread_join(init[8],NULL); /*TODO: verificar se é possível fazer os cálculos abaixo assim que a variável for inicializada acima*/ /*seta os valores inicias das váriaveis de precisão variável*/ /*d = sqrt(2)*/ mpf_set_ui(vars.aux_y1,2); mpf_sqrt(vars.aux_y1,vars.aux_y1); /*a0 = 6-4*d*/ mpf_mul_ui(vars.a0,vars.aux_y1,4); mpf_ui_sub(vars.a0,6,vars.a0); mpf_set(vars.a1,vars.a0); //a1=a0 /*y0 = d-1*/ mpf_sub_ui(vars.y0,vars.aux_y1,1); /*vars.y0 = sqrt(2)-1*/ while(vars.k<12) { /*Certifica que o valor de y está atualizado antes de calcular o próximo valor de y*/ if(calc[3] != 0) pthread_join(calc[3],NULL); pthread_create(&calc[0], NULL, (void *) &calc_y, (void *)&vars); //calcula valor de y-> nao depende de a nem de k, só do y anterior /*Certifica que a já foi calculado antes de fazer a0=a1*/ if(calc[1] != 0) pthread_join(calc[1],NULL); pthread_create(&calc[2], NULL, (void *) &mpf_seta_thread, (void *)&vars); //troca o valor de a pthread_join(calc[0],NULL); mpf_set(vars.y_valoratual,vars.y1); //seta o valor de y que será usado para calcular a /*Troca o valor de y0=y1*/ pthread_create(&calc[3], NULL, (void *) &mpf_sety_thread, (void *)&vars); pthread_join(calc[2],NULL); /*Calcula o novo valor de a*/ pthread_create(&calc[1], NULL, (void *) &calc_a, (void *)&vars); } mpf_ui_div(vars.a1,1,vars.a1); /*PI=1/vars.a1*/ gmp_printf("%.*Ff\n",10000000,vars.a1); /*Limpa as variáveis da memória*/ mpf_clear(vars.a0),mpf_clear(vars.a1),mpf_clear(vars.y0),mpf_clear(vars.y1); mpf_clear(vars.aux_y1),mpf_clear(vars.aux_y2),mpf_clear(vars.aux_a1),mpf_clear(vars.aux_a2); mpf_clear(vars.y_valoratual); }
/* * Function: compute_bbp_second_sum_gmp * -------------------- * Computes the second summand in the BBP formula. * * d: digit to be calculated * base: the base * c: a fixed positive integer * p: a simple polynomial like x or x^2 * * returns: the value of the second sum */ void compute_bbp_second_sum_gmp(mpf_t sum, int d, int base, int c, void (*p)(mpz_t, mpz_t)) { mpf_set_d(sum, 0.0); mpz_t k; mpz_init_set_si(k, floor((double) d / (double) c) + 1); mpf_t prev_sum; mpf_init(prev_sum); mpf_set(prev_sum, sum); mpf_t base_gmp; mpf_init(base_gmp); mpf_set_si(base_gmp, base); double d_diff = 0.0; do { mpf_set(prev_sum, sum); mpz_t poly_result; mpz_init(poly_result); (*p)(poly_result, k); mpf_t num; mpf_init(num); mpz_t exponent; mpz_init_set(exponent, k); mpz_mul_si(exponent, exponent, c); mpz_mul_si(exponent, exponent, -1); mpz_add_ui(exponent, exponent, d); signed long int exp = mpz_get_si(exponent); unsigned long int neg_exp = -1 * exp; mpf_pow_ui(num, base_gmp, neg_exp); mpf_ui_div(num, 1, num); mpz_clear(exponent); mpf_t denom; mpf_init_set_d(denom, mpz_get_d(poly_result)); mpz_clear(poly_result); mpf_t quotient; mpf_init(quotient); mpf_div(quotient, num, denom); mpf_clear(num); mpf_clear(denom); mpf_add(sum, sum, quotient); mpf_clear(quotient); mpz_add_ui(k, k, 1); mpf_t diff; mpf_init(diff); mpf_sub(diff, prev_sum, sum); d_diff = mpf_get_d(diff); d_diff = fabs(d_diff); mpf_clear(diff); } while (d_diff > 0.00000001); mpz_clear(k); mpf_clear(base_gmp); mpf_clear(prev_sum); }
int main (int argc, char **argv) { mp_size_t size; mp_exp_t exp; int reps = 10000; int i; mpf_t u, v, w, x; mp_size_t bprec = SIZE * GMP_LIMB_BITS; mpf_t rerr, limit_rerr; unsigned long ulimb, vlimb; int single_flag; tests_start (); if (argc > 1) { reps = strtol (argv[1], 0, 0); if (argc > 2) bprec = strtol (argv[2], 0, 0); } mpf_set_default_prec (bprec); mpf_init (rerr); mpf_init (limit_rerr); mpf_init (u); mpf_init (v); mpf_init (w); mpf_init (x); for (i = 0; i < reps; i++) { mp_size_t res_prec; res_prec = urandom () % bprec + 1; mpf_set_prec (w, res_prec); mpf_set_prec (x, res_prec); mpf_set_ui (limit_rerr, 1); mpf_div_2exp (limit_rerr, limit_rerr, res_prec - 1); single_flag = 0; if ((urandom () & 1) != 0) { size = urandom () % (2 * SIZE) - SIZE; exp = urandom () % SIZE; mpf_random2 (u, size, exp); } else { ulimb = urandom (); mpf_set_ui (u, ulimb); single_flag = 1; } if ((urandom () & 1) != 0) { size = urandom () % (2 * SIZE) - SIZE; exp = urandom () % SIZE; mpf_random2 (v, size, exp); } else { vlimb = urandom (); mpf_set_ui (v, vlimb); single_flag = 2; } if (mpf_sgn (v) == 0) continue; mpf_div (w, u, v); mpf_mul (x, w, v); mpf_reldiff (rerr, u, x); if (mpf_cmp (rerr, limit_rerr) > 0) { printf ("ERROR in mpf_mul or mpf_div after %d tests\n", i); printf (" u = "); mpf_dump (u); printf (" v = "); mpf_dump (v); printf (" x = "); mpf_dump (x); printf (" w = "); mpf_dump (w); abort (); } if (single_flag == 2) { mpf_div_ui (x, u, vlimb); mpf_reldiff (rerr, w, x); if (mpf_cmp (rerr, limit_rerr) > 0) { printf ("ERROR in mpf_div or mpf_div_ui after %d tests\n", i); printf (" u = "); mpf_dump (u); printf (" v = "); mpf_dump (v); printf (" x = "); mpf_dump (x); printf (" w = "); mpf_dump (w); abort (); } } if (single_flag == 1) { mpf_ui_div (x, ulimb, v); mpf_reldiff (rerr, w, x); if (mpf_cmp (rerr, limit_rerr) > 0) { printf ("ERROR in mpf_div or mpf_ui_div after %d tests\n", i); printf (" u = "); mpf_dump (u); printf (" v = "); mpf_dump (v); printf (" x = "); mpf_dump (x); printf (" w = "); mpf_dump (w); abort (); } } } mpf_clear (rerr); mpf_clear (limit_rerr); mpf_clear (u); mpf_clear (v); mpf_clear (w); mpf_clear (x); tests_end (); exit (0); }
int scanhash_m7m_hash(int thr_id, uint32_t *pdata, const uint32_t *ptarget, uint64_t max_nonce, unsigned long *hashes_done) { uint32_t data[32] __attribute__((aligned(128))); uint32_t *data_p64 = data + (M7_MIDSTATE_LEN / sizeof(data[0])); uint32_t hash[8] __attribute__((aligned(32))); uint8_t bhash[7][64] __attribute__((aligned(32))); uint32_t n = pdata[19] - 1; const uint32_t first_nonce = pdata[19]; char data_str[161], hash_str[65], target_str[65]; uint8_t *bdata = 0; mpz_t bns[8]; int rc = 0; int bytes, nnNonce2; mpz_t product; mpz_init(product); for(int i=0; i < 8; i++){ mpz_init(bns[i]); } memcpy(data, pdata, 80); sph_sha256_context ctx_final_sha256; sph_sha256_context ctx_sha256; sph_sha512_context ctx_sha512; sph_keccak512_context ctx_keccak; sph_whirlpool_context ctx_whirlpool; sph_haval256_5_context ctx_haval; sph_tiger_context ctx_tiger; sph_ripemd160_context ctx_ripemd; sph_sha256_init(&ctx_sha256); sph_sha256 (&ctx_sha256, data, M7_MIDSTATE_LEN); sph_sha512_init(&ctx_sha512); sph_sha512 (&ctx_sha512, data, M7_MIDSTATE_LEN); sph_keccak512_init(&ctx_keccak); sph_keccak512 (&ctx_keccak, data, M7_MIDSTATE_LEN); sph_whirlpool_init(&ctx_whirlpool); sph_whirlpool (&ctx_whirlpool, data, M7_MIDSTATE_LEN); sph_haval256_5_init(&ctx_haval); sph_haval256_5 (&ctx_haval, data, M7_MIDSTATE_LEN); sph_tiger_init(&ctx_tiger); sph_tiger (&ctx_tiger, data, M7_MIDSTATE_LEN); sph_ripemd160_init(&ctx_ripemd); sph_ripemd160 (&ctx_ripemd, data, M7_MIDSTATE_LEN); sph_sha256_context ctx2_sha256; sph_sha512_context ctx2_sha512; sph_keccak512_context ctx2_keccak; sph_whirlpool_context ctx2_whirlpool; sph_haval256_5_context ctx2_haval; sph_tiger_context ctx2_tiger; sph_ripemd160_context ctx2_ripemd; do { data[19] = ++n; nnNonce2 = (int)(data[19]/2); memset(bhash, 0, 7 * 64); ctx2_sha256 = ctx_sha256; sph_sha256 (&ctx2_sha256, data_p64, 80 - M7_MIDSTATE_LEN); sph_sha256_close(&ctx2_sha256, (void*)(bhash[0])); ctx2_sha512 = ctx_sha512; sph_sha512 (&ctx2_sha512, data_p64, 80 - M7_MIDSTATE_LEN); sph_sha512_close(&ctx2_sha512, (void*)(bhash[1])); ctx2_keccak = ctx_keccak; sph_keccak512 (&ctx2_keccak, data_p64, 80 - M7_MIDSTATE_LEN); sph_keccak512_close(&ctx2_keccak, (void*)(bhash[2])); ctx2_whirlpool = ctx_whirlpool; sph_whirlpool (&ctx2_whirlpool, data_p64, 80 - M7_MIDSTATE_LEN); sph_whirlpool_close(&ctx2_whirlpool, (void*)(bhash[3])); ctx2_haval = ctx_haval; sph_haval256_5 (&ctx2_haval, data_p64, 80 - M7_MIDSTATE_LEN); sph_haval256_5_close(&ctx2_haval, (void*)(bhash[4])); ctx2_tiger = ctx_tiger; sph_tiger (&ctx2_tiger, data_p64, 80 - M7_MIDSTATE_LEN); sph_tiger_close(&ctx2_tiger, (void*)(bhash[5])); ctx2_ripemd = ctx_ripemd; sph_ripemd160 (&ctx2_ripemd, data_p64, 80 - M7_MIDSTATE_LEN); sph_ripemd160_close(&ctx2_ripemd, (void*)(bhash[6])); for(int i=0; i < 7; i++){ set_one_if_zero(bhash[i]); mpz_set_uint512(bns[i],bhash[i]); } mpz_set_ui(bns[7],0); for(int i=0; i < 7; i++){ mpz_add(bns[7], bns[7], bns[i]); } mpz_set_ui(product,1); for(int i=0; i < 8; i++){ mpz_mul(product,product,bns[i]); } mpz_pow_ui(product, product, 2); bytes = mpz_sizeinbase(product, 256); bdata = (uint8_t *)realloc(bdata, bytes); mpz_export((void *)bdata, NULL, -1, 1, 0, 0, product); sph_sha256_init(&ctx_final_sha256); sph_sha256 (&ctx_final_sha256, bdata, bytes); sph_sha256_close(&ctx_final_sha256, (void*)(hash)); int digits=(int)((sqrt((double)(nnNonce2))*(1.+EPS))/9000+75); int iterations=20; mpf_set_default_prec((long int)(digits*BITS_PER_DIGIT+16)); mpz_t magipi; mpz_t magisw; mpf_t magifpi; mpf_t mpa1, mpb1, mpt1, mpp1; mpf_t mpa2, mpb2, mpt2, mpp2; mpf_t mpsft; mpz_init(magipi); mpz_init(magisw); mpf_init(magifpi); mpf_init(mpsft); mpf_init(mpa1); mpf_init(mpb1); mpf_init(mpt1); mpf_init(mpp1); mpf_init(mpa2); mpf_init(mpb2); mpf_init(mpt2); mpf_init(mpp2); uint32_t usw_; usw_ = sw_(nnNonce2, SW_DIVS); if (usw_ < 1) usw_ = 1; mpz_set_ui(magisw, usw_); uint32_t mpzscale=mpz_size(magisw); for(int i=0; i < NM7M; i++){ if (mpzscale > 1000) { mpzscale = 1000; } else if (mpzscale < 1) { mpzscale = 1; } mpf_set_ui(mpa1, 1); mpf_set_ui(mpb1, 2); mpf_set_d(mpt1, 0.25*mpzscale); mpf_set_ui(mpp1, 1); mpf_sqrt(mpb1, mpb1); mpf_ui_div(mpb1, 1, mpb1); mpf_set_ui(mpsft, 10); for(int j=0; j <= iterations; j++){ mpf_add(mpa2, mpa1, mpb1); mpf_div_ui(mpa2, mpa2, 2); mpf_mul(mpb2, mpa1, mpb1); mpf_abs(mpb2, mpb2); mpf_sqrt(mpb2, mpb2); mpf_sub(mpt2, mpa1, mpa2); mpf_abs(mpt2, mpt2); mpf_sqrt(mpt2, mpt2); mpf_mul(mpt2, mpt2, mpp1); mpf_sub(mpt2, mpt1, mpt2); mpf_mul_ui(mpp2, mpp1, 2); mpf_swap(mpa1, mpa2); mpf_swap(mpb1, mpb2); mpf_swap(mpt1, mpt2); mpf_swap(mpp1, mpp2); } mpf_add(magifpi, mpa1, mpb1); mpf_pow_ui(magifpi, magifpi, 2); mpf_div_ui(magifpi, magifpi, 4); mpf_abs(mpt1, mpt1); mpf_div(magifpi, magifpi, mpt1); mpf_pow_ui(mpsft, mpsft, digits/2); mpf_mul(magifpi, magifpi, mpsft); mpz_set_f(magipi, magifpi); mpz_add(product,product,magipi); mpz_add(product,product,magisw); mpz_set_uint256(bns[0], (void*)(hash)); mpz_add(bns[7], bns[7], bns[0]); mpz_mul(product,product,bns[7]); mpz_cdiv_q (product, product, bns[0]); if (mpz_sgn(product) <= 0) mpz_set_ui(product,1); bytes = mpz_sizeinbase(product, 256); mpzscale=bytes; bdata = (uint8_t *)realloc(bdata, bytes); mpz_export(bdata, NULL, -1, 1, 0, 0, product); sph_sha256_init(&ctx_final_sha256); sph_sha256 (&ctx_final_sha256, bdata, bytes); sph_sha256_close(&ctx_final_sha256, (void*)(hash)); } mpz_clear(magipi); mpz_clear(magisw); mpf_clear(magifpi); mpf_clear(mpsft); mpf_clear(mpa1); mpf_clear(mpb1); mpf_clear(mpt1); mpf_clear(mpp1); mpf_clear(mpa2); mpf_clear(mpb2); mpf_clear(mpt2); mpf_clear(mpp2); rc = fulltest_m7hash(hash, ptarget); if (rc) { if (opt_debug) { bin2hex(hash_str, (unsigned char *)hash, 32); bin2hex(target_str, (unsigned char *)ptarget, 32); bin2hex(data_str, (unsigned char *)data, 80); applog(LOG_DEBUG, "DEBUG: [%d thread] Found share!\ndata %s\nhash %s\ntarget %s", thr_id, data_str, hash_str, target_str); } pdata[19] = data[19]; goto out; } } while (n < max_nonce && !work_restart[thr_id].restart); pdata[19] = n; out: for(int i=0; i < 8; i++){ mpz_clear(bns[i]); } mpz_clear(product); free(bdata); *hashes_done = n - first_nonce + 1; return rc; }
bool bbp_pi(bool const & abortTask, std::string const & digitIndex, uint32_t const digitStep, std::string & piSequence) { unsigned long const mantissa_bits = 132; unsigned long const count_offset = 7; // settings above gives 32 hexadecimal digits unsigned long count = static_cast<unsigned long>( floor(log10(pow(2.0, static_cast<double>(mantissa_bits))))); count -= count_offset; // starting digit mpz_t digit; mpz_init(digit); if (mpz_set_str(digit, digitIndex.c_str(), 10) < 0) return false; mpz_sub_ui(digit, digit, 1); // subtract the 3 digit mpz_add_ui(digit, digit, digitStep); mpz_t tmpI[TEMPORARY_INTEGERS]; for (size_t i = 0; i < (sizeof(tmpI) / sizeof(mpz_t)); ++i) mpz_init(tmpI[i]); mpf_t tmpF[TEMPORARY_FLOATS]; for (size_t i = 0; i < (sizeof(tmpF) / sizeof(mpf_t)); ++i) mpf_init2(tmpF[i], mantissa_bits); // determine epsilon based on the number of digits required mpf_t epsilon; mpf_init2(epsilon, mantissa_bits); mpf_set_ui(epsilon, 10); mpf_pow_ui(epsilon, epsilon, count + count_offset); mpf_ui_div(epsilon, 1, epsilon); // integer constant mpz_t sixteen; mpz_init(sixteen); mpz_set_ui(sixteen, 16); // determine the series mpf_t s1, s2, s3, s4; mpf_init2(s1, mantissa_bits); mpf_init2(s2, mantissa_bits); mpf_init2(s3, mantissa_bits); mpf_init2(s4, mantissa_bits); series(abortTask, s1, 1, tmpI, tmpF, sixteen, digit, epsilon); if (abortTask) return false; series(abortTask, s2, 4, tmpI, tmpF, sixteen, digit, epsilon); if (abortTask) return false; series(abortTask, s3, 5, tmpI, tmpF, sixteen, digit, epsilon); if (abortTask) return false; series(abortTask, s4, 6, tmpI, tmpF, sixteen, digit, epsilon); if (abortTask) return false; // pid = 4. * s1 - 2. * s2 - s3 - s4; mpf_mul_ui(s1, s1, 4); mpf_mul_ui(s2, s2, 2); mpf_t result; mpf_init2(result, mantissa_bits); mpf_sub(result, s1, s2); mpf_sub(result, result, s3); mpf_sub(result, result, s4); // pid = pid - (int) pid + 1.; mpf_t & tmp1 = tmpF[0]; mpf_floor(tmp1, result); mpf_sub(result, result, tmp1); mpf_add_ui(result, result, 1); mpf_abs(result, result); // output the result char resultStr[256]; mp_exp_t exponent; mpf_get_str(resultStr, &exponent, 16, 254, result); resultStr[count + 1] = '\0'; // cut off any erroneous bits piSequence.assign(&resultStr[1]); // cleanup for (size_t i = 0; i < (sizeof(tmpI) / sizeof(mpz_t)); ++i) mpz_clear(tmpI[i]); for (size_t i = 0; i < (sizeof(tmpF) / sizeof(mpf_t)); ++i) mpf_clear(tmpF[i]); mpz_clear(digit); mpf_clear(epsilon); mpz_clear(sixteen); mpf_clear(s1); mpf_clear(s2); mpf_clear(s3); mpf_clear(s4); mpf_clear(result); return true; }
void series(bool const & abortTask, mpf_t & rop, unsigned long m, mpz_t * const & tmpI, mpf_t * const & tmpF, mpz_t const & sixteen, mpz_t const & digit, mpf_t const & epsilon) { // temporary local variables mpf_t & tmp1 = tmpF[0]; mpf_t & t = tmpF[1]; mpz_t & tmp2 = tmpI[0]; mpz_t & k = tmpI[1]; mpz_t & p = tmpI[2]; mpz_t & ak = tmpI[3]; mpf_set_ui(rop, 0); mpz_set_ui(k, 0); while (mpz_cmp(k, digit) < 0) // k < digit { // p = id - k; mpz_sub(p, digit, k); // ak = 8 * k + m; mpz_set(ak, k); mpz_mul_ui(ak, ak, 8); mpz_add_ui(ak, ak, m); // t = expm (p, ak); mpz_powm(tmp2, sixteen, p, ak); mpf_set_z(t, tmp2); // s = s + t / ak; mpf_set_z(tmp1, ak); mpf_div(tmp1, t, tmp1); mpf_add(rop, rop, tmp1); // s = s - (int) s; mpf_floor(tmp1, rop); mpf_sub(rop, rop, tmp1); // k++ mpz_add_ui(k, k, 1); if (abortTask) return; } // ak = 8 * k + m; mpz_set(ak, k); mpz_mul_ui(ak, ak, 8); mpz_add_ui(ak, ak, m); // t = pow (16., (double) (id - k)) / ak; mpf_set_z(tmp1, ak); mpf_ui_div(t, 1, tmp1); while (mpf_cmp(t, epsilon) >= 0) // t >= epsilon { // s = s + t; mpf_add(rop, rop, t); // s = s - (int) s; mpf_floor(tmp1, rop); mpf_sub(rop, rop, tmp1); // k++ mpz_add_ui(k, k, 1); // p = id - k; mpz_sub(p, digit, k); // ak = 8 * k + m; mpz_set(ak, k); mpz_mul_ui(ak, ak, 8); mpz_add_ui(ak, ak, m); // t = pow (16., (double) (id - k)) / ak; mpz_pow_ui(tmp2, sixteen, mpz_get_ui(p)); mpz_mul(tmp2, tmp2, ak); mpf_set_z(t, tmp2); mpf_ui_div(t, 1, t); if (abortTask) return; } }
int chudnovsky(int digits, int threads) { int res = 0; unsigned long int i, iter, precision, rest, per_cpu, k; mpf_t ltf, sum, result; pthread_t *pthreads; struct thread_args targs; mp_exp_t exponent; char *pi; /* If threads is not specified, check how many CPUs are avail */ if (threads == 0) { threads = get_cpu_count(); } pthreads = malloc(threads * sizeof(pthread_t)); if (pthreads == NULL) { res = -ENOMEM; goto chudnovsky_exit; } /* Calculate and set precision */ precision = (digits * BPD) + 1; mpf_set_default_prec(precision); /* Calculate number of iterations */ iter = digits/DPI + 1; /* Init all objects */ mpf_inits(ltf, sum, result, targs.sum, NULL); mpf_set_ui(sum, 0); mpf_set_ui(targs.sum, 0); /* Set pthread specific stuff */ targs.k = 0; targs.iter = iter; pthread_mutex_init(&targs.start_mutex, NULL); pthread_mutex_init(&targs.sum_mutex, NULL); /* Prepare the constant from the left side of the equation */ mpf_sqrt_ui(ltf, LTFCON1); mpf_mul_ui(ltf, ltf, LTFCON2); printf("Starting summing, using:\n" "%d digits - %lu iterations - %d threads\n", digits, iter, threads); for (i = 0; i < threads; i++) { pthread_create(&pthreads[i], NULL, &chudnovsky_chunk, (void *) &targs); } /* Wait for threads to finish and take their sums */ for (i = 0; i < threads; i++) { pthread_join(pthreads[i], NULL); } printf("Starting final steps\n"); /* Invert sum */ mpf_ui_div(sum, 1, targs.sum); mpf_mul(result, sum, ltf); /* Get one more char then needed and then trunc to avoid rounding */ pi = mpf_get_str(NULL, &exponent, 10, digits + 2, result); pi[digits+1] = '\0'; if (strlen(pi) < LAST_DIGITS_PRINT + 1) { printf("Calculated PI:\n"); printf("\t%.*s.%s\n", (int)exponent, pi, pi + exponent); } else { printf("Last digits of Pi are:\n"); printf("\t%s\n", pi+(digits-(LAST_DIGITS_PRINT-1))); } free(pi); mpf_clears(ltf, sum, result, NULL); pthread_mutex_destroy(&targs.start_mutex); pthread_mutex_destroy(&targs.sum_mutex); /* TODO: add verification here! */ chudnovsky_free_pthreads: free(pthreads); chudnovsky_exit: return res; }
int main () { int i = 0; /*Contador de iterações*/ int k = 8; /*Fator de multiplicação*/ mpf_t pi_pas, pi_novo; mpf_t a_pas, a_novo; mpf_t y_pas, y_novo; mpf_t temp1, temp2; mpf_t e; FILE *fileTime; /*Ponteiro do arquivo de saída*/ clock_t start, end; double cpu_time_used; mpf_set_default_prec(BITS_PER_DIGIT * 11000000); /*Precisão default*/ /*Inicialização das variáveis*/ mpf_init(pi_pas); mpf_init(pi_novo); mpf_init(a_pas); mpf_init(y_pas); mpf_init(temp1); mpf_init(temp2); mpf_init_set_d(a_novo, 32.0); mpf_sqrt(a_novo, a_novo); mpf_ui_sub(a_novo, 6, a_novo); mpf_init_set_d(y_novo, 2.0); mpf_sqrt(y_novo, y_novo); mpf_sub_ui(y_novo, y_novo, 1); mpf_init_set_str(e, "1e-10000000", 10); mpf_ui_div(pi_novo, 1, a_novo); start = clock(); /*Calcula as iterações*/ do { mpf_swap(pi_pas, pi_novo); mpf_swap(a_pas, a_novo); mpf_swap(y_pas, y_novo); mpf_pow_ui(y_pas, y_pas, 4); mpf_ui_sub(y_pas, 1, y_pas); mpf_sqrt(y_pas, y_pas); mpf_sqrt(y_pas, y_pas); mpf_add_ui(temp1, y_pas, 1); mpf_ui_sub(y_novo, 1, y_pas); mpf_div(y_novo, y_novo, temp1); mpf_add_ui(temp1, y_novo, 1); mpf_pow_ui(temp2, y_novo, 2); mpf_add(temp2, temp2, temp1); mpf_mul(temp2, temp2, y_novo); mpf_mul_ui(temp2, temp2, k); k *= 4; mpf_pow_ui(temp1, temp1, 4); mpf_mul(temp1, temp1, a_pas); mpf_sub(a_novo, temp1, temp2); mpf_ui_div(pi_novo, 1, a_novo); mpf_sub(pi_pas, pi_novo, pi_pas); mpf_abs(pi_pas, pi_pas); gmp_printf("\nIteracao %d | pi = %.25Ff", i, pi_novo); i++; } while ( mpf_cmp(e, pi_pas) < 0 ); end = clock(); cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; fileTime = fopen("execution_time.txt", "w"); fprintf(fileTime, "Execution time: %f\n", cpu_time_used); fclose(fileTime); /*Libera espaço de memória*/ mpf_clear(pi_pas); mpf_clear(pi_novo); mpf_clear(a_pas); mpf_clear(a_novo); mpf_clear(y_pas); mpf_clear(y_novo); mpf_clear(temp1); mpf_clear(temp2); mpf_clear(e); return 0; }
/** * Algoritmo de Borwein * * a1 se aproxima do valor de 1/PI. * Cada iteração quadruplica o número de dígitos corretos. * */ void gmp_borwein() { /*variáveis para calculo com respectivos valores iniciais*/ mpf_t a0, a1, y0, y1, aux1, aux2; /*contador de iterações*/ long unsigned int k=0; //mpf_set_default_prec(33220); /*define a precisao do float em bits*/ mpf_set_default_prec(33219280);//(33219280); /*define a precisao do float em bits*/ mpf_init(a0),mpf_init(a1),mpf_init(y0),mpf_init(y1),mpf_init(aux1),mpf_init(aux2); /*Inicializa as variáveis em 0*/ /*seta os valores inicias das váriaveis de precisão variável*/ /*a0 = 6-4*sqrt(2)*/ mpf_set_ui(aux1,2); mpf_sqrt(aux1,aux1); /*sqrt(2)*/ mpf_mul_ui(a0,aux1,4); mpf_ui_sub(a0,6,a0); //mpf_set_d(a0, 6-4*sqrt(2)); mpf_sub_ui(y0,aux1,1); /*y0 = sqrt(2)-1*/ while(k<12) { /*y1 = (1-sqrt(sqrt((1-pow(y0,4))))) / (1+sqrt(sqrt(1-pow(y0,4))));*/ mpf_pow_ui(y1,y0,4); /*y1 = pow(y0,4)*/ mpf_ui_sub(y1,1,y1); /*y1 = 1 - y1*/ mpf_sqrt(y1,y1); mpf_sqrt(y1,y1); mpf_ui_sub(aux1,1,y1); mpf_add_ui(aux2,y1,1); mpf_div(y1,aux1,aux2); /*a1 = a0*pow(1 + y1,4) - pow(2,2*k+3)*y1*(1+y1+pow(y1,2));*/ mpf_add_ui(a1,y1,1); /*a1 = y1+1*/ mpf_pow_ui(a1,a1,4); /*a1 = a1^4*/ mpf_mul(a1,a0,a1); /*a1 = a0*a1*/ mpf_pow_ui(aux2,y1,2); /*aux2 = pow(y1,2)*/ mpf_add(aux2,aux2,y1); /*aux2 += y1*/ mpf_add_ui(aux2,aux2,1); /*aux2++*/ mpf_mul(aux2,aux2,y1); /*aux2 *= y1*/ mpf_set_ui(aux1,2); /* aux1=2 */ mpf_pow_ui(aux1,aux1,2*k+3); /* aux1 = pow(aux1,2*k+3)*/ mpf_mul(aux1,aux1,aux2); /*aux1 = aux1*aux2*/ mpf_sub(a1,a1,aux1); /*troca os valores das variáveis de maneira eficiente*/ mpf_swap(a0,a1); mpf_swap(y0,y1); k++; /*gmp_printf("k=%ld, y1=%.*Ff, 1/PI=%.*Ff\n", k, 20, y1, 20, a1); gmp_printf("a0=%.*Ff, y0=%.*Ff\n", 20, a0, 20, y0);*/ } mpf_ui_div(a1,1,a1); /*PI=1/a1*/ gmp_printf("%.*Ff\n",10000000,a1); mpf_clear(a0),mpf_clear(a1),mpf_clear(y0),mpf_clear(y1),mpf_clear(aux1),mpf_clear(aux2); /*Limpa as variáveis da memória*/ }
//#define SW_MAX 1000 void m7magi_hash(const char* input, char* output) { unsigned int nnNonce; uint32_t pdata[32]; memcpy(pdata, input, 80); // memcpy(&nnNonce, input+76, 4); int i, j, bytes, nnNonce2; nnNonce2 = (int)(pdata[19]/2); size_t sz = 80; uint8_t bhash[7][64]; uint32_t hash[8]; memset(bhash, 0, 7 * 64); sph_sha256_context ctx_final_sha256; sph_sha256_context ctx_sha256; sph_sha512_context ctx_sha512; sph_keccak512_context ctx_keccak; sph_whirlpool_context ctx_whirlpool; sph_haval256_5_context ctx_haval; sph_tiger_context ctx_tiger; sph_ripemd160_context ctx_ripemd; sph_sha256_init(&ctx_sha256); // ZSHA256; sph_sha256 (&ctx_sha256, input, sz); sph_sha256_close(&ctx_sha256, (void*)(bhash[0])); sph_sha512_init(&ctx_sha512); // ZSHA512; sph_sha512 (&ctx_sha512, input, sz); sph_sha512_close(&ctx_sha512, (void*)(bhash[1])); sph_keccak512_init(&ctx_keccak); // ZKECCAK; sph_keccak512 (&ctx_keccak, input, sz); sph_keccak512_close(&ctx_keccak, (void*)(bhash[2])); sph_whirlpool_init(&ctx_whirlpool); // ZWHIRLPOOL; sph_whirlpool (&ctx_whirlpool, input, sz); sph_whirlpool_close(&ctx_whirlpool, (void*)(bhash[3])); sph_haval256_5_init(&ctx_haval); // ZHAVAL; sph_haval256_5 (&ctx_haval, input, sz); sph_haval256_5_close(&ctx_haval, (void*)(bhash[4])); sph_tiger_init(&ctx_tiger); // ZTIGER; sph_tiger (&ctx_tiger, input, sz); sph_tiger_close(&ctx_tiger, (void*)(bhash[5])); sph_ripemd160_init(&ctx_ripemd); // ZRIPEMD; sph_ripemd160 (&ctx_ripemd, input, sz); sph_ripemd160_close(&ctx_ripemd, (void*)(bhash[6])); // printf("%s\n", hash[6].GetHex().c_str()); mpz_t bns[8]; for(i=0; i < 8; i++){ mpz_init(bns[i]); } //Take care of zeros and load gmp for(i=0; i < 7; i++){ set_one_if_zero(bhash[i]); mpz_set_uint512(bns[i],bhash[i]); } mpz_set_ui(bns[7],0); for(i=0; i < 7; i++) mpz_add(bns[7], bns[7], bns[i]); mpz_t product; mpz_init(product); mpz_set_ui(product,1); // mpz_pow_ui(bns[7], bns[7], 2); for(i=0; i < 8; i++){ mpz_mul(product,product,bns[i]); } mpz_pow_ui(product, product, 2); bytes = mpz_sizeinbase(product, 256); // printf("M7M data space: %iB\n", bytes); char *data = (char*)malloc(bytes); mpz_export(data, NULL, -1, 1, 0, 0, product); sph_sha256_init(&ctx_final_sha256); // ZSHA256; sph_sha256 (&ctx_final_sha256, data, bytes); sph_sha256_close(&ctx_final_sha256, (void*)(hash)); free(data); int digits=(int)((sqrt((double)(nnNonce2))*(1.+EPS))/9000+75); // int iterations=(int)((sqrt((double)(nnNonce2))+EPS)/500+350); // <= 500 // int digits=100; int iterations=20; // <= 500 mpf_set_default_prec((long int)(digits*BITS_PER_DIGIT+16)); mpz_t magipi; mpz_t magisw; mpf_t magifpi; mpf_t mpa1, mpb1, mpt1, mpp1; mpf_t mpa2, mpb2, mpt2, mpp2; mpf_t mpsft; mpz_init(magipi); mpz_init(magisw); mpf_init(magifpi); mpf_init(mpsft); mpf_init(mpa1); mpf_init(mpb1); mpf_init(mpt1); mpf_init(mpp1); mpf_init(mpa2); mpf_init(mpb2); mpf_init(mpt2); mpf_init(mpp2); uint32_t usw_; usw_ = sw_(nnNonce2, SW_DIVS); if (usw_ < 1) usw_ = 1; // if(fDebugMagi) printf("usw_: %d\n", usw_); mpz_set_ui(magisw, usw_); uint32_t mpzscale=mpz_size(magisw); for(i=0; i < NM7M; i++) { if (mpzscale > 1000) { mpzscale = 1000; } else if (mpzscale < 1) { mpzscale = 1; } // if(fDebugMagi) printf("mpzscale: %d\n", mpzscale); mpf_set_ui(mpa1, 1); mpf_set_ui(mpb1, 2); mpf_set_d(mpt1, 0.25*mpzscale); mpf_set_ui(mpp1, 1); mpf_sqrt(mpb1, mpb1); mpf_ui_div(mpb1, 1, mpb1); mpf_set_ui(mpsft, 10); for(j=0; j <= iterations; j++) { mpf_add(mpa2, mpa1, mpb1); mpf_div_ui(mpa2, mpa2, 2); mpf_mul(mpb2, mpa1, mpb1); mpf_abs(mpb2, mpb2); mpf_sqrt(mpb2, mpb2); mpf_sub(mpt2, mpa1, mpa2); mpf_abs(mpt2, mpt2); mpf_sqrt(mpt2, mpt2); mpf_mul(mpt2, mpt2, mpp1); mpf_sub(mpt2, mpt1, mpt2); mpf_mul_ui(mpp2, mpp1, 2); mpf_swap(mpa1, mpa2); mpf_swap(mpb1, mpb2); mpf_swap(mpt1, mpt2); mpf_swap(mpp1, mpp2); } mpf_add(magifpi, mpa1, mpb1); mpf_pow_ui(magifpi, magifpi, 2); mpf_div_ui(magifpi, magifpi, 4); mpf_abs(mpt1, mpt1); mpf_div(magifpi, magifpi, mpt1); // mpf_out_str(stdout, 10, digits+2, magifpi); mpf_pow_ui(mpsft, mpsft, digits/2); mpf_mul(magifpi, magifpi, mpsft); mpz_set_f(magipi, magifpi); //mpz_set_ui(magipi,1); mpz_add(product,product,magipi); mpz_add(product,product,magisw); mpz_set_uint256(bns[0], (void*)(hash)); mpz_add(bns[7], bns[7], bns[0]); mpz_mul(product,product,bns[7]); mpz_cdiv_q (product, product, bns[0]); if (mpz_sgn(product) <= 0) mpz_set_ui(product,1); bytes = mpz_sizeinbase(product, 256); mpzscale=bytes; // printf("M7M data space: %iB\n", bytes); char *bdata = (char*)malloc(bytes); mpz_export(bdata, NULL, -1, 1, 0, 0, product); sph_sha256_init(&ctx_final_sha256); // ZSHA256; sph_sha256 (&ctx_final_sha256, bdata, bytes); sph_sha256_close(&ctx_final_sha256, (void*)(hash)); free(bdata); } //Free the memory for(i=0; i < 8; i++){ mpz_clear(bns[i]); } // mpz_clear(dSpectralWeight); mpz_clear(product); mpz_clear(magipi); mpz_clear(magisw); mpf_clear(magifpi); mpf_clear(mpsft); mpf_clear(mpa1); mpf_clear(mpb1); mpf_clear(mpt1); mpf_clear(mpp1); mpf_clear(mpa2); mpf_clear(mpb2); mpf_clear(mpt2); mpf_clear(mpp2); memcpy(output, hash, 32); }
int main() { pthread_t thread_a, thread_b; /* My threads*/ int i; FILE *filePi, *fileTime; clock_t start, end; double cpu_time_used; mpf_set_default_prec(BITS_PER_DIGIT * 11000000); /* Borwein Variable Initialization */ for(i=0; i<2; i++) for(j=0; j<2; j++) mpf_init(params[i][j]); mpf_init(real_pi); mpf_init(y0Aux); mpf_init(y0Aux2); mpf_init(a0Aux); mpf_init(a0Aux2); mpf_init(pi[0]); mpf_init(pi[1]); mpf_init_set_str(error, "1e-10000000", 10); /* Initial value setting */ mpf_sqrt_ui(params[A][0], 2.0); /* a0 = sqrt(2)*/ mpf_mul_ui(params[A][0], params[A][0], 4.0); /* a0 = 4 * sqrt(2) */ mpf_ui_sub(params[A][0], 6.0, params[A][0]); /* a0 = 6 - 4 * sqrt(2) */ mpf_sqrt_ui(params[Y][0], 2.0); /* y0 = sqrt(2) */ mpf_sub_ui(params[Y][0], params[Y][0], 1.0); /* y0 = sqrt(2) - 1 */ mpf_set_ui(pi[0], 0); mpf_set_ui(pi[1], 0); i = 1; j = 1; iteracoes = 0; x = 0; /* Load the reals digits of pi */ filePi = fopen("pi.txt", "r"); gmp_fscanf(filePi, "%Ff", real_pi); fclose(filePi); start = clock(); while(1){ /* y = ( 1 - (1 - y0 ^ 4) ^ 0.25 ) / ( 1 + ( 1 - y0 ^ 4) ^ 0.25 ) */ mpf_pow_ui(y0Aux, params[Y][0], 4); mpf_ui_sub(y0Aux, 1.0, y0Aux); mpf_sqrt(y0Aux, y0Aux); mpf_sqrt(y0Aux, y0Aux); mpf_add_ui(y0Aux2, y0Aux, 1.0); mpf_ui_sub(y0Aux, 1.0, y0Aux); mpf_div(params[Y][1], y0Aux, y0Aux2); /* a = a0 * ( 1 + params[Y][1] ) ^ 4 - 2 ^ ( 2 * i + 3 ) * params[Y][1] * ( 1 + params[Y][1] + params[Y][1] ^ 2 ) */ /* Threads creation */ pthread_create(&thread_a, NULL, calc_a, NULL); pthread_create(&thread_b, NULL, calc_b, NULL); pthread_join(thread_a, NULL); pthread_join(thread_b, NULL); /* 2 ^ ( 2 * i + 3 ) * params[Y][1] * ( 1 + params[Y][1] + params[Y][1] ^ 2 ) */ mpf_mul(a0Aux, a0Aux, a0Aux2); /*a0 * ( 1 + params[Y][1] ) ^ 4*/ mpf_add_ui(a0Aux2, params[Y][1], 1); mpf_pow_ui(a0Aux2, a0Aux2, 4); mpf_mul(a0Aux2, params[A][0], a0Aux2); /* form the entire expression */ mpf_sub(params[A][1], a0Aux2, a0Aux); mpf_set(params[A][0], params[A][1]); mpf_set(params[Y][0], params[Y][1]); mpf_ui_div(pi[j], 1, params[A][0]); gmp_printf("\nIteracao %d | pi = %.25Ff", iteracoes, pi[j]); /* Calculate the error */ mpf_sub(pi[(j+1)%2], real_pi, pi[j]); mpf_abs(pi[(j+1) % 2], pi[(j+1) % 2]); if(mpf_cmp(pi[(j+1)%2], error) < 0){ printf("\n%d iteracoes para alcancar 10 milhoes de digitos de corretos.", iteracoes); break; } j = (j+1) % 2; iteracoes++; i++; } end = clock(); cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; fileTime = fopen("execution_time.txt", "w"); fprintf(fileTime, "Execution time: %f\n", cpu_time_used); fclose(fileTime); /* Clean up*/ for(i=0; i<2; i++) for(j=0; j<2; j++) mpf_clear(params[i][j]); mpf_clear(pi[0]); mpf_clear(pi[1]); mpf_clear(real_pi); mpf_clear(error); return 0; }
// // The core Gauss-Legendre routine. // On input, 'bits' is the desired precision in bits. // On output, 'pi' contains the calculated value. // static void calculatePi( unsigned bits, mpf_t pi) { mpf_t lastPi; mpf_t scratch; // variables per the formal Gauss-Legendre formulae mpf_t a; mpf_t b; mpf_t t; mpf_t x; mpf_t y; unsigned p = 1; mpf_init_set_ui(lastPi, 0); mpf_init(x); mpf_init(y); mpf_init(scratch); // initial conditions mpf_init_set_ui(a, 1); // a := 1 mpf_init(b); // b := 1 / sqrt(2) mpf_sqrt_ui(b, 2); mpf_ui_div(b, 1, b); mpf_init_set_ui(t, 4); // t := 1/4 mpf_ui_div(t, 1, t); for(;;) { // x := (a+b)/2 mpf_add(x, a, b); mpf_div_ui(x, x, 2); // y := sqrt(a*b) mpf_mul(y, a, b); mpf_sqrt(y, y); // t := t - p * (a-x)**2 mpf_sub(scratch, a, x); mpf_pow_ui(scratch, scratch, 2); mpf_mul_ui(scratch, scratch, p); mpf_sub(t, t, scratch); // a := x // b := y // p := 2p mpf_set(a, x); mpf_set(b, y); p <<= 1; // pi := ((a + b)**2) / 4t mpf_add(pi, a, b); mpf_pow_ui(pi, pi, 2); mpf_mul_ui(scratch, t, 4); mpf_div(pi, pi, scratch); // if pi == lastPi, within the requested precision, we're done if(mpf_eq(pi, lastPi, bits)) { break; } mpf_set(lastPi, pi); } // free memory associated with mpf_t's we allocated mpf_clear(a); mpf_clear(b); mpf_clear(t); mpf_clear(x); mpf_clear(y); mpf_clear(lastPi); mpf_clear(scratch); }
int fractal_gmp_calculate_line(image_info* img, int line) { int ret = 1; int ix = 0; int mx = 0; int chk_px = ((rthdata*)img->rth_ptr)->check_stop_px; int img_width = img->real_width; int* raw_data = &img->raw_data[line * img_width]; depth_t depth = img->depth; mpf_t x, y; mpf_t x2, y2; mpf_t c_re, c_im; /* working variables: */ mpf_t wre, wim; mpf_t wre2, wim2; mpf_t frs_bail; mpf_t width, img_rw, img_xmin; mpf_t t1; mpf_init2(x, img->precision); mpf_init2(y, img->precision); mpf_init2(x2, img->precision); mpf_init2(y2, img->precision); mpf_init2(c_re, img->precision); mpf_init2(c_im, img->precision); mpf_init2(wre, img->precision); mpf_init2(wim, img->precision); mpf_init2(wre2, img->precision); mpf_init2(wim2, img->precision); mpf_init2(frs_bail,img->precision); mpf_init2(width, img->precision); mpf_init2(img_rw, img->precision); mpf_init2(img_xmin,img->precision); mpf_init2(t1, img->precision); mpf_set_si(frs_bail, 4); mpf_set_si(img_rw, img_width); mpf_set( img_xmin, img->gxmin); mpf_set( width, img->gwidth); /* y = img->ymax - ((img->xmax - img->xmin) / (long double)img->real_width) * (long double)img->lines_done; */ mpf_div( t1, width, img_rw); mpf_mul_ui( t1, t1, line); mpf_sub( y, img->gymax, t1); mpf_mul( y2, y, y); while (ix < img_width) { mx += chk_px; if (mx > img_width) mx = img_width; for (; ix < mx; ++ix, ++raw_data) { /* x = ((long double)ix / (long double)img->real_width) * (img->xmax - img->xmin) + img->xmin; */ mpf_ui_div(t1, ix, img_rw); mpf_mul(x, t1, width); mpf_add(x, x, img_xmin); mpf_mul( x2, x, x); mpf_set( wre, x); mpf_set( wim, y); mpf_set( wre2, x2); mpf_set( wim2, y2); switch (img->family) { case FAMILY_MANDEL: mpf_set(c_re, x); mpf_set(c_im, y); break; case FAMILY_JULIA: mpfr_to_gmp(img->u.julia.c_re, c_re); mpfr_to_gmp(img->u.julia.c_im, c_im); break; } switch(img->fractal) { case BURNING_SHIP: *raw_data = frac_burning_ship_gmp( depth, frs_bail, wim, wre, c_im, c_re, wim2, wre2, t1); break; case GENERALIZED_CELTIC: *raw_data = frac_generalized_celtic_gmp( depth, frs_bail, wim, wre, c_im, c_re, wim2, wre2, t1); break; case VARIANT: *raw_data = frac_variant_gmp( depth, frs_bail, wim, wre, c_im, c_re, wim2, wre2, t1); break; case MANDELBROT: default: *raw_data = frac_mandel_gmp(depth, frs_bail, wim, wre, c_im, c_re, wim2, wre2, t1); } } if (rth_render_should_stop((rthdata*)img->rth_ptr)) { ret = 0; break; } } mpf_clear(x); mpf_clear(y); mpf_clear(x2); mpf_clear(y2); mpf_clear(c_re); mpf_clear(c_im); mpf_clear(wre); mpf_clear(wim); mpf_clear(wre2); mpf_clear(wim2); mpf_clear(frs_bail); mpf_clear(width); mpf_clear(img_rw); mpf_clear(t1); return ret; }