void log(const mpz_t n, mpz_t l, mpz_t b) { mpf_t tmp, tmp2, tmp3; mpf_inits(tmp, tmp2, tmp3, NULL); mpf_set_z(tmp, n); mpf_set_z(tmp3, b); log(tmp, tmp2, tmp3); mpz_set_f(l, tmp2); mpf_clears(tmp, tmp2, tmp3, NULL); }
void readfac (mpf_t *factoriales) { FILE *fichero; char *filename; int i; mpz_t intfac; filename = (char *) malloc(50*sizeof(char)); mpz_init(intfac); mpf_init_set_ui(factoriales[0], 1); for (i=1; i<=NFAC; i++) { sprintf(filename, "factoriales/%4.4d.dat", i); fichero = fopen(filename, "r"); mpz_inp_str(intfac, fichero, 10); /* printf("Ahi va: %d\n", i); * mpz_out_str(stdout, 10, intfac); * printf("\n\n"); */ mpf_init(factoriales[i]); mpf_set_z(factoriales[i], intfac); fclose(fichero); } }
void log2(const mpz_t n, mpz_t l) { mpf_t tmp, tmp2; mpf_inits(tmp, tmp2, NULL); mpf_set_z(tmp, n); log2(tmp, tmp2); mpz_set_f(l, tmp2); mpf_clears(tmp, tmp2, NULL); }
void log10(const mpz_t n, mpz_t l, int prec) { mpf_t tmp, tmp2; mpf_inits(tmp, tmp2, NULL); mpf_set_z(tmp, n); log10(tmp, tmp2, prec); mpz_set_f(l, tmp2); mpf_clears(tmp, tmp2, NULL); }
Float::Float(const Integer& i) { mpf_init(value); mpz_t mpz; i.mpzInit(mpz); mpf_set_z(value, mpz); mpz_clear(mpz); }
void my_divexact(mpz_t r, mpz_t y, mpz_t x) { unsigned long prec = mpz_sizeinbase(y, 2); unsigned long prec2 = mpz_sizeinbase(x, 2); if (prec >= div_threshold) { mpf_set_prec_raw(d1, prec); mpf_set_prec_raw(d2, prec); mpf_set_z(d1, y); mpf_set_z(d2, x); mpf_div_2exp(d1, d1, prec); mpf_div_2exp(d2, d2, prec2); my_div(d2, d1, d2); mpf_mul_2exp(d2, d2, prec-prec2); mpf_set_d(d1, 0.5); mpf_add(d2, d2, d1); mpz_set_f(y, d2); } else { mpz_divexact(y, y, x); //mpz_tdiv_q(y, y, x); } }
/* f_floor (rop, op) -- Set rop = floor (op). */ void f_floor (mpf_t rop, mpf_t op) { mpz_t z; mpz_init (z); /* No mpf_floor(). Convert to mpz and back. */ mpz_set_f (z, op); mpf_set_z (rop, z); mpz_clear (z); }
/* merit (rop, t, v, m) -- calculate merit for spectral test result in dimension T, see Knuth p. 105. BUGS: Only valid for 2 <= T <= 6. */ void merit (mpf_t rop, unsigned int t, mpf_t v, mpz_t m) { int f; mpf_t f_m, f_const, f_pi; mpf_init (f_m); mpf_set_z (f_m, m); mpf_init_set_d (f_const, M_PI); mpf_init_set_d (f_pi, M_PI); switch (t) { case 2: /* PI */ break; case 3: /* PI * 4/3 */ mpf_mul_ui (f_const, f_const, 4); mpf_div_ui (f_const, f_const, 3); break; case 4: /* PI^2 * 1/2 */ mpf_mul (f_const, f_const, f_pi); mpf_div_ui (f_const, f_const, 2); break; case 5: /* PI^2 * 8/15 */ mpf_mul (f_const, f_const, f_pi); mpf_mul_ui (f_const, f_const, 8); mpf_div_ui (f_const, f_const, 15); break; case 6: /* PI^3 * 1/6 */ mpf_mul (f_const, f_const, f_pi); mpf_mul (f_const, f_const, f_pi); mpf_div_ui (f_const, f_const, 6); break; default: fprintf (stderr, "spect (merit): can't calculate merit for dimensions > 6\n"); mpf_set_ui (f_const, 0); break; } /* rop = v^t */ mpf_set (rop, v); for (f = 1; f < t; f++) mpf_mul (rop, rop, v); mpf_mul (rop, rop, f_const); mpf_div (rop, rop, f_m); mpf_clear (f_m); mpf_clear (f_const); mpf_clear (f_pi); }
/* * Function: compute_bbp_first_sum_gmp * -------------------- * Computes the first summand in the BBP formula using GNU GMP. * * d: digit to be calculated * base: the base * c: a fixed positive integer * p: a simple polynomial like x or x^2 * start_at_0: start the summation at k=0, if true, at k=1, otherwise. Most * instances of the BBP formula, such as pi, have you start at 0. * But some, such as log(2), have you start at 1. * * returns: the value of the first sum */ void compute_bbp_first_sum_gmp(mpf_t sum, unsigned long int d, int base, long int c, void (*p)(mpz_t, mpz_t), bool start_at_0) { mpf_set_d(sum, 0.0); signed long int k_start = start_at_0 ? 0 : 1; mpz_t k; mpz_init_set_si(k, k_start); double upper = floor((double) d / (double) c); while (mpz_cmp_d(k, upper) <= 0) { mpz_t poly_result; mpz_init(poly_result); (*p)(poly_result, k); mpz_t num; mpz_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); modular_pow_gmp(num, base, exponent, poly_result); mpf_t num_float; mpf_init(num_float); mpf_set_z(num_float, num); mpz_clear(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_float, denom); mpf_clear(num_float); mpf_clear(denom); mpf_add(sum, sum, quotient); mpf_clear(quotient); mod_one_gmp(sum, sum); mpz_add_ui(k, k, 1); } mpz_clear(k); mod_one_gmp(sum, sum); }
void mpc_mod (mpc_t *rop, mpc_t op1, mpc_t op2) { /* I am 90% sure that this doesn't work. However, it works for * integers, so I'll put off fixing it for a little while. */ mpf_t hold_op1; mpf_t hold_op2; mpf_t hold_res; unsigned int prec; mpf_init (hold_op1); mpf_init (hold_op2); mpf_init (hold_res); mpf_set_z (hold_op1, op1.object); mpf_set_z (hold_op2, op2.object); // Get the largest precision. prec = (op1.precision > op2.precision) ? op1.precision : op2.precision; // Set the scalar values while (op1.precision-- > 0) mpf_div_ui (hold_op1, hold_op1, 10); while (op2.precision-- > 0) mpf_div_ui (hold_op2, hold_op2, 10); // Get the value mpf_div (hold_res, hold_op1, hold_op2); mpf_floor (hold_res, hold_res); mpf_mul (hold_res, hold_res, hold_op2); mpf_sub (hold_res, hold_op1, hold_res); for (rop->precision = prec; prec > 0; prec--) mpf_mul_ui (hold_res, hold_res, 10); mpz_set_f (rop->object, hold_res); }
void mpfc_set_z(mpfc_ptr x,mpz_ptr y) { mpf_set_z(x->Re,y); mpf_set_ui(x->Im,0); }
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); }
extern void _jl_mpf_set_z(mpf_t* rop, mpz_t* op) { mpf_set_z(*rop, *op); }
//Le but de la fonction est de calculer le développement en fractions continue jusqu'à un certain rang de racine carrée de kN et de stocker les couples (A_n-1,Q_n) comme décrit dans la section (à venir) cfrac expand(const mpz_t N, const long long unsigned int rang, const mpz_t k) { cfrac res; //Contient l'ensemble des A_n-1 et l'ensemble Q_n mpz_inits(res.N, res.k, res.g, NULL); //Initialisation des variables mpz_t* A = (mpz_t*)malloc((rang+1)*sizeof(mpz_t)); //Le tableau contenant les A_n-1 mpz_t* Q = (mpz_t*)malloc((rang+2)*sizeof(mpz_t)); //Le tableau contenant les Q_n mpz_t* P = (mpz_t*)malloc((rang+1)*sizeof(mpz_t)); //Éléments reliés au Q_n mpz_t* r = (mpz_t*)malloc((rang+1)*sizeof(mpz_t)); //Interviennent dans le calcul des A_n-1 & Q_n mpz_t* q = (mpz_t*)malloc(rang*sizeof(mpz_t)); //Idem mpz_t g, tempz; //Idem, tempz = variable à tout faire mpf_t sqrtkN, tempf, tempf2; //sqrtkN = sqrt(k*N), tempf = variable à tout faire //Valeurs d'initialisation de la boucle mpz_inits(g, A[0], Q[0], r[0], tempz, NULL); mpf_inits(tempf, sqrtkN, tempf2, NULL); //Initialisation des différentes valeurs "indépendantes" mpz_set(tempz, N); mpz_mul(tempz, tempz, k); mpf_set_z(sqrtkN, tempz); mpf_sqrt(sqrtkN, sqrtkN); mpf_floor(tempf, sqrtkN); mpz_set_f(g, tempf); //g = [sqrt(kN)] mpz_set(Q[0], k); mpz_mul(Q[0], Q[0], N); //Q_-1 = kN = Q[0] mpz_set(r[0], g); //r_-1 = r[0] mpz_set_ui(A[0], 1); //A_-1 = A[0] //Calcul de P_0 & Q_0 mpz_init_set_ui(Q[1], 1); //Q_0 = Q[1] mpz_init_set_ui(P[0], 0); //P_0 = P[0] for(long long int i = 0; i < rang; i++) { switch(i) { case 0: //Calcul de q_0 mpz_init_set(q[0], g); //q_0 = [(sqrt(kN) + P_0)/Q_0] avec P_0 = 0 et Q_0 = 1 //Calcul de A_0 mpz_init_set(A[1],A[0]); mpz_mul(A[1], A[1], q[0]); //A_0 = q_0*A_-1 mpz_mod(A[1], A[1], N); //On réduit mod N //Calcul de r_0 mpz_init_set_ui(r[1], 0); //r_0 = P_0 + g - q_0.Q_0 = 0 + g - g.1 = 0 //Calcul de P_1 mpz_init_set(P[1], g); //P_1 = g - r_0 = g - 0 = g //Calcul de Q_1 = Q[2] mpz_init_set(Q[2], r[1]); mpz_sub(Q[2], Q[2], r[0]); mpz_mul(Q[2], Q[2], q[0]); mpz_add(Q[2], Q[2], Q[0]); break; default: //Calcul q_i mpz_init(q[i]); mpf_set_z(tempf, P[i]); mpf_set_z(tempf2, Q[i+1]); mpf_add(tempf, tempf, sqrtkN); //sqrt(kN) + P_i mpf_div(tempf, tempf, tempf2); mpf_floor(tempf, tempf); //floor((sqrt(kN) + P_i)/Q_i) mpz_set_f(q[i], tempf); //Calcul de r_n = r[n+1] mpz_init(r[i+1]); mpz_submul(r[i+1], q[i], Q[i+1]); mpz_add(r[i+1], r[i+1], P[i]); mpz_add(r[i+1], r[i+1], g); //Calcul de A_n = A[n+1] mpz_init_set(A[i+1],A[i]); mpz_mul(A[i+1], A[i+1], q[i]); //A_i-1*q_i mpz_add(A[i+1], A[i+1], A[i-1]); //A_i-1*q_i + A_i-2 mpz_mod(A[i+1], A[i+1], N); //réduction modulo N //Calcul P_n+1 mpz_init_set(P[i+1], g); mpz_sub(P[i+1], P[i+1], r[i+1]); //P[n+1] = g - r_n = g - r[n+1] //Calcul Q_n+1 = Q[n+2] mpz_init_set(Q[i+2], r[i+1]); mpz_sub(Q[i+2], Q[i+2], r[i]); //(r_n - r_n-1) mpz_mul(Q[i+2], Q[i+2], q[i]); //q_n(r_n - r_n-1) mpz_add(Q[i+2], Q[i+2], Q[i]); //Q_n-1 + q_n(r_n - r_n-1) break; } } //Test de routine pour voir si le développement de la fraction continue s'est bien passé mpz_t tempsqrt; mpz_init(tempsqrt); mpz_set(tempsqrt, k); mpz_mul(tempsqrt, tempsqrt, N); mpz_sqrt(tempsqrt, tempsqrt); mpz_mul_ui(tempsqrt, tempsqrt, 2); for(int i = 1; i < rang; i++) //Éviter de commencer à i = 0 puisque cela représente Q_-1 qui n'intervient uniquement dans l'algo et non dans le développement en fraction continue { if(mpz_cmp(Q[i], tempsqrt) >= 0) //Si Q_n >= 2sqrt(kN) { res.rang = 0; mpz_clears(g, tempz, NULL); mpf_clears(sqrtkN, tempf, tempf2, NULL); return res; } } //Assignation des tableaux dans le résultat res.A = A; res.Q = Q; res.r = r; res.q = q; res.P = P; mpz_set(res.N, N); mpz_set(res.k, k); res.rang = rang; mpz_set(res.g, g); //Libération de mémoire mpz_clears(g, tempz, NULL); mpf_clears(sqrtkN, tempf, tempf2, NULL); return res; }
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; } }
void mpc_div (mpc_t *rop, mpc_t op1, mpc_t op2) { /* This function needs to be fixed. At the current moment I am tired * of having to mess around with the precision values, so I'm just * going to convert the values to 'mpf's and call it quits for the * day. I'll fix it later. * Division by zero is not checked for in this function. */ mpf_t hold_op1; mpf_t hold_op2; mpf_t hold_res; unsigned int prec; mpf_init (hold_op1); mpf_init (hold_op2); mpf_init (hold_res); mpf_set_z (hold_op1, op1.object); mpf_set_z (hold_op2, op2.object); // Get the largest precision prec = (op1.precision > op2.precision) ? op1.precision : op2.precision; if (prec == 0) prec = default_prec; // Set the scalar values while (op1.precision-- > 0) mpf_div_ui (hold_op1, hold_op1, 10); while (op2.precision-- > 0) mpf_div_ui (hold_op2, hold_op2, 10); // Get the value mpf_div (hold_res, hold_op1, hold_op2); for (rop->precision = prec; prec > 0; prec--) mpf_mul_ui (hold_res, hold_res, 10); mpz_set_f (rop->object, hold_res); /* temp.precision = (op1.precision < op2.precision) ? op2.precision : op1.precision; if (!op1.precision && !op2.precision) { temp.precision = default_prec; mpz_set (temp.object, op1.object); power_of_ten (temp.object, default_prec); mpz_tdiv_q (temp_res, temp.object, op2.object); } else if (op1.precision < op2.precision) { temp.precision = op2.precision; mpz_set (temp.object, op1.object); power_of_ten (temp.object, op2.precision - op1.precision); mpz_tdiv_q (temp_res, temp.object, op2.object); } else if (op1.precision > op2.precision) { temp.precision = op1.precision; mpz_set (temp.object, op2.object); power_of_ten (temp.object, op1.precision - op2.precision); mpz_tdiv_q (temp_res, op1.object, temp.object); } else { temp.precision = op1.precision; mpz_set (temp.object, op1.object); mpz_tdiv_q (temp_res, temp.object, op2.object); } rop->precision = temp.precision; mpz_set (rop->object, temp_res); */ }
int main(int argc, char *argv[]) { mpz_t total; mpz_init_set_str(total, "0", 10); mpz_t i; mpz_init_set_str(i, "1", 10); mpz_t upper_bound; mpz_init_set_str(upper_bound, "9999999996", 10); printf("upper_bound: "); mpz_out_str(stdout, 10, upper_bound); printf("\n"); mpz_t prev_pow; mpz_init_set_str(prev_pow, "1", 10); for (; mpz_cmp(i, upper_bound) < 0; mpz_add_ui(i, i, 1)) { // (i+1)^2 mpz_t tmp; mpz_init(tmp); mpz_add_ui(tmp, i, 1); mpz_pow_ui(tmp, tmp, 2); // prev_pow + tmp mpz_t tmp_sum; mpz_init(tmp_sum); mpz_add(tmp_sum, prev_pow, tmp); // sqrt(prev_pow + tmp) mpf_t result; mpf_init(result); mpf_set_z(result, tmp_sum); mpf_sqrt(result, result); mpz_clear(tmp_sum); mpz_set(prev_pow, tmp); mpz_clear(tmp); // (int) result mpz_t result_int; mpz_init(result_int); mpz_set_f(result_int, result); // (float) (int) result mpf_t result_int_float; mpf_init(result_int_float); mpf_set_z(result_int_float, result_int); // result = (float) (int) result ? if (mpf_cmp(result, result_int_float) == 0) { mpz_out_str(stdout, 10, i); printf("\n"); mpz_add(total, total, i); } mpz_clear(result_int); mpf_clear(result_int_float); mpf_clear(result); } printf("Total: "); mpz_out_str(stdout, 10, total); printf("\n"); mpz_clear(total); mpz_clear(i); mpz_clear(upper_bound); mpz_clear(prev_pow); return 0; }
void check_random (long reps) { unsigned long test; gmp_randstate_ptr rands = RANDS; mpf_t a, b, x; mpz_t ds; int hibits, lshift1, lshift2; int xtra; #define HIBITS 10 #define LSHIFT1 10 #define LSHIFT2 10 mpf_set_default_prec ((1 << HIBITS) + (1 << LSHIFT1) + (1 << LSHIFT2)); mpz_init (ds); mpf_inits (a, b, x, NULL); for (test = 0; test < reps; test++) { mpz_urandomb (ds, rands, HIBITS); hibits = mpz_get_ui (ds) + 1; mpz_urandomb (ds, rands, hibits); mpz_setbit (ds, hibits - 1); /* make sure msb is set */ mpf_set_z (a, ds); mpf_set_z (b, ds); mpz_urandomb (ds, rands, LSHIFT1); lshift1 = mpz_get_ui (ds); mpf_mul_2exp (a, a, lshift1 + 1); mpf_mul_2exp (b, b, lshift1 + 1); mpf_add_ui (a, a, 1); /* make a one-bit difference */ mpz_urandomb (ds, rands, LSHIFT2); lshift2 = mpz_get_ui (ds); mpf_mul_2exp (a, a, lshift2); mpf_mul_2exp (b, b, lshift2); mpz_urandomb (ds, rands, lshift2); mpf_set_z (x, ds); mpf_add (a, a, x); mpf_add (b, b, x); insert_random_low_zero_limbs (a, rands); insert_random_low_zero_limbs (b, rands); if (mpf_eq (a, b, lshift1 + hibits) == 0 || mpf_eq (b, a, lshift1 + hibits) == 0) { dump_abort (a, b, lshift1 + hibits, lshift1, lshift2, hibits, 1, test); } for (xtra = 1; xtra < 100; xtra++) if (mpf_eq (a, b, lshift1 + hibits + xtra) != 0 || mpf_eq (b, a, lshift1 + hibits + xtra) != 0) { dump_abort (a, b, lshift1 + hibits + xtra, lshift1, lshift2, hibits, 0, test); } } mpf_clears (a, b, x, NULL); mpz_clear (ds); }
int aks (mpz_t n) { mpz_t r; mpz_t a; mpz_t max_a; mpz_t gcd_rslt; mpz_t totient_r; mpf_t ftotient_r; mpf_t sqrt_rslt; mpf_t sqrt_rslt2; mpf_t temp; mpf_t temp2; sli_t logn; /* For the sake of maple kernel */ int argc = 0; char **argv; char err[2048]; mpz_init (r); mpz_init (a); mpz_init (max_a); mpz_init (gcd_rslt); mpz_init (totient_r); mpf_init (ftotient_r); mpf_init (sqrt_rslt); mpf_init (sqrt_rslt2); mpf_init (temp); mpf_init (temp2); /* 1. If (n = a^k for a in N and b > 1) output COMPOSITE */ if (mpz_perfect_power_p (n) != 0) { printf ("Step 1 detected composite\n"); return FALSE; } /* 2. Find the smallest r such that or(n) > 4(log n)^2 */ find_smallest_r (r, n); gmp_printf ("good r seems to be %Zd\n", r); /* 3. If 1 < gcd(a, n) < n for some a <= r, output COMPOSITE */ /* for (a = 1; a <= r; a++) { * gcd_rslt = gcd(a, n); * if (gcd_rslt > 1 && gcd_rslt < n) { * return FALSE; * } * } */ for (mpz_set_ui (a, 1); mpz_cmp (a, r) < 0 || mpz_cmp (a, r) == 0; mpz_add_ui (a, a, 1)) { mpz_gcd (gcd_rslt, a, n); if (mpz_cmp_ui (gcd_rslt, 1) > 0 && mpz_cmp (gcd_rslt, n) < 0) { printf ("Step 3 detected composite\n"); return FALSE; } } /* 4. If n <= r, output PRIME */ if (mpz_cmp (n, r) < 0 || mpz_cmp (n, r) == 0) { printf ("Step 4 detected prime\n"); return TRUE; } /* 5. For a = 1 to floor(2*sqrt(totient(r))*(log n) * if ( (X+a)^n != X^n + a (mod X^r-1, n) ), output COMPOSITE * * Choices of implementation to evaluate the polynomial equality: * (1) Implement powermodreduce on polynomial ourselves (tough manly way) * (2) Use MAPLE (not so manly, but less painful) */ /* Compute totient(r), since r is prime, this is simply r-1 */ mpz_sub_ui (totient_r, r, 1); /* Compute log n (ceilinged) */ mpz_logbase2cl (&logn, n); /* Compute sqrt(totient(r)) */ mpf_set_z (ftotient_r, totient_r); mpf_sqrt (sqrt_rslt, ftotient_r); /* Compute 2*sqrt(totient(r)) */ mpf_mul_ui (sqrt_rslt2, sqrt_rslt, 2); /* Compute 2*sqrt(totient(r))*(log n) */ mpf_set (temp, sqrt_rslt2); mpf_set_si (temp2, logn); mpf_mul (temp, temp, temp2); /* Finally, compute max_a, after lots of singing and dancing */ mpf_floor (temp, temp); mpz_set_f (max_a, temp); gmp_printf ("max_a = %Zd\n", max_a); /* Now evaluate the polynomial equality with the help of maple kernel */ /* Set up maple kernel incantations */ MKernelVector kv; MCallBackVectorDesc cb = { textCallBack, 0, /* errorCallBack not used */ 0, /* statusCallBack not used */ 0, /* readLineCallBack not used */ 0, /* redirectCallBack not used */ 0, /* streamCallBack not used */ 0, /* queryInterrupt not used */ 0 /* callBackCallBack not used */ }; /* Initialize Maple */ if ((kv = StartMaple (argc, argv, &cb, NULL, NULL, err)) == NULL) { printf ("Could not start Maple, %s\n", err); exit (666); } /* Here comes the complexity and bottleneck */ /* for (a = 1; a <= max_a; a++) { * if (!poly_eq_holds(kv, a, n, r)) { * return FALSE; * } * } */ /* Make max_a only up to 5 */ mpz_set_ui (max_a, 5); for (mpz_set_ui (a, 1); mpz_cmp (a, max_a) < 0 || mpz_cmp (a, max_a) == 0; mpz_add_ui (a, a, 1)) { if (!poly_eq_holds (kv, a, n, r)) { printf ("Step 5 detected composite\n"); return FALSE; } } /* 6. Output PRIME */ printf ("Step 6 detected prime\n"); return TRUE; }
void spectral_test (mpf_t rop[], unsigned int T, mpz_t a, mpz_t m) { /* Knuth "Seminumerical Algorithms, Third Edition", section 3.3.4 (pp. 101-103). */ /* v[t] = min { sqrt (x[1]^2 + ... + x[t]^2) | x[1] + a*x[2] + ... + pow (a, t-1) * x[t] is congruent to 0 (mod m) } */ /* Variables. */ unsigned int ui_t; unsigned int ui_i, ui_j, ui_k, ui_l; mpf_t f_tmp1, f_tmp2; mpz_t tmp1, tmp2, tmp3; mpz_t U[GMP_SPECT_MAXT][GMP_SPECT_MAXT], V[GMP_SPECT_MAXT][GMP_SPECT_MAXT], X[GMP_SPECT_MAXT], Y[GMP_SPECT_MAXT], Z[GMP_SPECT_MAXT]; mpz_t h, hp, r, s, p, pp, q, u, v; /* GMP inits. */ mpf_init (f_tmp1); mpf_init (f_tmp2); for (ui_i = 0; ui_i < GMP_SPECT_MAXT; ui_i++) { for (ui_j = 0; ui_j < GMP_SPECT_MAXT; ui_j++) { mpz_init_set_ui (U[ui_i][ui_j], 0); mpz_init_set_ui (V[ui_i][ui_j], 0); } mpz_init_set_ui (X[ui_i], 0); mpz_init_set_ui (Y[ui_i], 0); mpz_init (Z[ui_i]); } mpz_init (tmp1); mpz_init (tmp2); mpz_init (tmp3); mpz_init (h); mpz_init (hp); mpz_init (r); mpz_init (s); mpz_init (p); mpz_init (pp); mpz_init (q); mpz_init (u); mpz_init (v); /* Implementation inits. */ if (T > GMP_SPECT_MAXT) T = GMP_SPECT_MAXT; /* FIXME: Lazy. */ /* S1 [Initialize.] */ ui_t = 2 - 1; /* NOTE: `t' in description == ui_t + 1 for easy indexing */ mpz_set (h, a); mpz_set (hp, m); mpz_set_ui (p, 1); mpz_set_ui (pp, 0); mpz_set (r, a); mpz_pow_ui (s, a, 2); mpz_add_ui (s, s, 1); /* s = 1 + a^2 */ /* S2 [Euclidean step.] */ while (1) { if (g_debug > DEBUG_1) { mpz_mul (tmp1, h, pp); mpz_mul (tmp2, hp, p); mpz_sub (tmp1, tmp1, tmp2); if (mpz_cmpabs (m, tmp1)) { printf ("***BUG***: h*pp - hp*p = "); mpz_out_str (stdout, 10, tmp1); printf ("\n"); } } if (g_debug > DEBUG_2) { printf ("hp = "); mpz_out_str (stdout, 10, hp); printf ("\nh = "); mpz_out_str (stdout, 10, h); printf ("\n"); fflush (stdout); } if (mpz_sgn (h)) mpz_tdiv_q (q, hp, h); /* q = floor(hp/h) */ else mpz_set_ui (q, 1); if (g_debug > DEBUG_2) { printf ("q = "); mpz_out_str (stdout, 10, q); printf ("\n"); fflush (stdout); } mpz_mul (tmp1, q, h); mpz_sub (u, hp, tmp1); /* u = hp - q*h */ mpz_mul (tmp1, q, p); mpz_sub (v, pp, tmp1); /* v = pp - q*p */ mpz_pow_ui (tmp1, u, 2); mpz_pow_ui (tmp2, v, 2); mpz_add (tmp1, tmp1, tmp2); if (mpz_cmp (tmp1, s) < 0) { mpz_set (s, tmp1); /* s = u^2 + v^2 */ mpz_set (hp, h); /* hp = h */ mpz_set (h, u); /* h = u */ mpz_set (pp, p); /* pp = p */ mpz_set (p, v); /* p = v */ } else break; } /* S3 [Compute v2.] */ mpz_sub (u, u, h); mpz_sub (v, v, p); mpz_pow_ui (tmp1, u, 2); mpz_pow_ui (tmp2, v, 2); mpz_add (tmp1, tmp1, tmp2); if (mpz_cmp (tmp1, s) < 0) { mpz_set (s, tmp1); /* s = u^2 + v^2 */ mpz_set (hp, u); mpz_set (pp, v); } mpf_set_z (f_tmp1, s); mpf_sqrt (rop[ui_t - 1], f_tmp1); /* S4 [Advance t.] */ mpz_neg (U[0][0], h); mpz_set (U[0][1], p); mpz_neg (U[1][0], hp); mpz_set (U[1][1], pp); mpz_set (V[0][0], pp); mpz_set (V[0][1], hp); mpz_neg (V[1][0], p); mpz_neg (V[1][1], h); if (mpz_cmp_ui (pp, 0) > 0) { mpz_neg (V[0][0], V[0][0]); mpz_neg (V[0][1], V[0][1]); mpz_neg (V[1][0], V[1][0]); mpz_neg (V[1][1], V[1][1]); } while (ui_t + 1 != T) /* S4 loop */ { ui_t++; mpz_mul (r, a, r); mpz_mod (r, r, m); /* Add new row and column to U and V. They are initialized with all elements set to zero, so clearing is not necessary. */ mpz_neg (U[ui_t][0], r); /* U: First col in new row. */ mpz_set_ui (U[ui_t][ui_t], 1); /* U: Last col in new row. */ mpz_set (V[ui_t][ui_t], m); /* V: Last col in new row. */ /* "Finally, for 1 <= i < t, set q = round (vi1 * r / m), vit = vi1*r - q*m, and Ut=Ut+q*Ui */ for (ui_i = 0; ui_i < ui_t; ui_i++) { mpz_mul (tmp1, V[ui_i][0], r); /* tmp1=vi1*r */ zdiv_round (q, tmp1, m); /* q=round(vi1*r/m) */ mpz_mul (tmp2, q, m); /* tmp2=q*m */ mpz_sub (V[ui_i][ui_t], tmp1, tmp2); for (ui_j = 0; ui_j <= ui_t; ui_j++) /* U[t] = U[t] + q*U[i] */ { mpz_mul (tmp1, q, U[ui_i][ui_j]); /* tmp=q*uij */ mpz_add (U[ui_t][ui_j], U[ui_t][ui_j], tmp1); /* utj = utj + q*uij */ } } /* s = min (s, zdot (U[t], U[t]) */ vz_dot (tmp1, U[ui_t], U[ui_t], ui_t + 1); if (mpz_cmp (tmp1, s) < 0) mpz_set (s, tmp1); ui_k = ui_t; ui_j = 0; /* WARNING: ui_j no longer a temp. */ /* S5 [Transform.] */ if (g_debug > DEBUG_2) printf ("(t, k, j, q1, q2, ...)\n"); do { if (g_debug > DEBUG_2) printf ("(%u, %u, %u", ui_t + 1, ui_k + 1, ui_j + 1); for (ui_i = 0; ui_i <= ui_t; ui_i++) { if (ui_i != ui_j) { vz_dot (tmp1, V[ui_i], V[ui_j], ui_t + 1); /* tmp1=dot(Vi,Vj). */ mpz_abs (tmp2, tmp1); mpz_mul_ui (tmp2, tmp2, 2); /* tmp2 = 2*abs(dot(Vi,Vj) */ vz_dot (tmp3, V[ui_j], V[ui_j], ui_t + 1); /* tmp3=dot(Vj,Vj). */ if (mpz_cmp (tmp2, tmp3) > 0) { zdiv_round (q, tmp1, tmp3); /* q=round(Vi.Vj/Vj.Vj) */ if (g_debug > DEBUG_2) { printf (", "); mpz_out_str (stdout, 10, q); } for (ui_l = 0; ui_l <= ui_t; ui_l++) { mpz_mul (tmp1, q, V[ui_j][ui_l]); mpz_sub (V[ui_i][ui_l], V[ui_i][ui_l], tmp1); /* Vi=Vi-q*Vj */ mpz_mul (tmp1, q, U[ui_i][ui_l]); mpz_add (U[ui_j][ui_l], U[ui_j][ui_l], tmp1); /* Uj=Uj+q*Ui */ } vz_dot (tmp1, U[ui_j], U[ui_j], ui_t + 1); /* tmp1=dot(Uj,Uj) */ if (mpz_cmp (tmp1, s) < 0) /* s = min(s,dot(Uj,Uj)) */ mpz_set (s, tmp1); ui_k = ui_j; } else if (g_debug > DEBUG_2) printf (", #"); /* 2|Vi.Vj| <= Vj.Vj */ } else if (g_debug > DEBUG_2) printf (", *"); /* i == j */ } if (g_debug > DEBUG_2) printf (")\n"); /* S6 [Advance j.] */ if (ui_j == ui_t) ui_j = 0; else ui_j++; } while (ui_j != ui_k); /* S5 */ /* From Knuth p. 104: "The exhaustive search in steps S8-S10 reduces the value of s only rarely." */ #ifdef DO_SEARCH /* S7 [Prepare for search.] */ /* Find minimum in (x[1], ..., x[t]) satisfying condition x[k]^2 <= f(y[1], ...,y[t]) * dot(V[k],V[k]) */ ui_k = ui_t; if (g_debug > DEBUG_2) { printf ("searching..."); /*for (f = 0; f < ui_t*/ fflush (stdout); } /* Z[i] = floor (sqrt (floor (dot(V[i],V[i]) * s / m^2))); */ mpz_pow_ui (tmp1, m, 2); mpf_set_z (f_tmp1, tmp1); mpf_set_z (f_tmp2, s); mpf_div (f_tmp1, f_tmp2, f_tmp1); /* f_tmp1 = s/m^2 */ for (ui_i = 0; ui_i <= ui_t; ui_i++) { vz_dot (tmp1, V[ui_i], V[ui_i], ui_t + 1); mpf_set_z (f_tmp2, tmp1); mpf_mul (f_tmp2, f_tmp2, f_tmp1); f_floor (f_tmp2, f_tmp2); mpf_sqrt (f_tmp2, f_tmp2); mpz_set_f (Z[ui_i], f_tmp2); } /* S8 [Advance X[k].] */ do { if (g_debug > DEBUG_2) { printf ("X[%u] = ", ui_k); mpz_out_str (stdout, 10, X[ui_k]); printf ("\tZ[%u] = ", ui_k); mpz_out_str (stdout, 10, Z[ui_k]); printf ("\n"); fflush (stdout); } if (mpz_cmp (X[ui_k], Z[ui_k])) { mpz_add_ui (X[ui_k], X[ui_k], 1); for (ui_i = 0; ui_i <= ui_t; ui_i++) mpz_add (Y[ui_i], Y[ui_i], U[ui_k][ui_i]); /* S9 [Advance k.] */ while (++ui_k <= ui_t) { mpz_neg (X[ui_k], Z[ui_k]); mpz_mul_ui (tmp1, Z[ui_k], 2); for (ui_i = 0; ui_i <= ui_t; ui_i++) { mpz_mul (tmp2, tmp1, U[ui_k][ui_i]); mpz_sub (Y[ui_i], Y[ui_i], tmp2); } } vz_dot (tmp1, Y, Y, ui_t + 1); if (mpz_cmp (tmp1, s) < 0) mpz_set (s, tmp1); } } while (--ui_k); #endif /* DO_SEARCH */ mpf_set_z (f_tmp1, s); mpf_sqrt (rop[ui_t - 1], f_tmp1); #ifdef DO_SEARCH if (g_debug > DEBUG_2) printf ("done.\n"); #endif /* DO_SEARCH */ } /* S4 loop */ /* Clear GMP variables. */ mpf_clear (f_tmp1); mpf_clear (f_tmp2); for (ui_i = 0; ui_i < GMP_SPECT_MAXT; ui_i++) { for (ui_j = 0; ui_j < GMP_SPECT_MAXT; ui_j++) { mpz_clear (U[ui_i][ui_j]); mpz_clear (V[ui_i][ui_j]); } mpz_clear (X[ui_i]); mpz_clear (Y[ui_i]); mpz_clear (Z[ui_i]); } mpz_clear (tmp1); mpz_clear (tmp2); mpz_clear (tmp3); mpz_clear (h); mpz_clear (hp); mpz_clear (r); mpz_clear (s); mpz_clear (p); mpz_clear (pp); mpz_clear (q); mpz_clear (u); mpz_clear (v); return; }
void topsin_series (mpf_t a_k, unsigned int k, unsigned int prec) { unsigned int n; mpf_t fourpi, numer, fact, low_bound, term, xterm; mpz_t bino; mpf_set_ui(a_k, 0); /* If k == 0 then we are done */ if (0 == k) return; mpf_init(fourpi); mpf_init(numer); mpf_init(fact); mpf_init(low_bound); mpf_init(term); mpf_init(xterm); mpz_init(bino); fp_two_pi(numer, prec); mpf_neg(numer, numer); // fourpi is actually -4pi^2 mpf_mul(fourpi, numer, numer); mpf_neg(fourpi, fourpi); mpf_set_ui(fact, 1); /* Get the number of binary bits from prec = log_2 10 * prec */ long nbits = (long) floor (3.321 * prec); mpf_div_2exp(low_bound, fact, nbits+32); for (n=0; n<2023123123; n++) { i_binomial(bino, 2*n+k, 2*n); mpf_set_z(term, bino); mpf_mul(xterm, term, numer); mpf_div(term, xterm, fact); mpf_add(a_k, a_k, term); // #define DEBUG 1 #ifdef DEBUG { double h_f, q_f, b_f; h_f = mpf_get_d(h); q_f = mpf_get_d(qmark); b_f = mpf_get_d(bits); printf("duuude place=%d, bitsdone=%ld h=%g q=%g bits=%f s=%d\n", place, bitsdone, h_f, q_f, b_f, mpf_sgn(h)); } #endif // If the term is small enough, we are done. mpf_abs(xterm, term); if (mpf_cmp(xterm, low_bound) < 0) break; // Now iterate mpf_mul(numer, numer, fourpi); mpf_mul_ui(fact, fact, (2*n+3)*2*(n+1)); } if (k%2 == 0) mpf_neg(a_k, a_k); mpf_clear(fourpi); mpf_clear(numer); mpf_clear(fact); mpf_clear(low_bound); mpf_clear(term); mpf_clear(xterm); mpz_clear(bino); }
vanilla::float_object::gmp_mpf_wrapper::gmp_mpf_wrapper(mpz_t op) : _mpf(), _valid(true) { mpf_init(_mpf); mpf_set_z(_mpf, op); }
/* Command line arguments are three char[]s of digits: * integer (binary digits) * exponent (decimal value) * fraction (binary digits) * Outputs are normalized decimal and binary representations * of the input value, one part per line: * decimal integer * decimal fraction * decimal exponent * decimal recurrence digits * decimal recurrence start position * binary recurrence digits * binary recurrence start * binary integer * binary fraction * binary exponent */ int main(int argc, char* argv[]) { if (argc != 4) { puts("Need arguments!"); exit(1); } //const int BINARY_PRECISION = 128; int decimal_exponent; int binary_exponent_v; char* binary_integer_v = malloc(BUF); char* binary_fraction_v = malloc(BUF); char* decimal_fraction = malloc(BUF); char* decimal_integer = malloc(BUF); int decimal_recurrence_start = -1; int binary_recurrence_start = -1; char* decimal_recurrence = malloc(BUF); strcpy(decimal_recurrence, "0"); char* binary_recurrence = malloc(BUF); strcpy(binary_recurrence, "0"); char* temp = malloc(BUF); //int precision_so_far = 0; strcpy(binary_integer_v, argv[1]); binary_exponent_v = atoi(argv[2]); strcpy(binary_fraction_v, argv[3]); //printf("bfv %s\n", binary_fraction_v); mpz_t result; mpz_init(result); //char* binfractemp = binary_fraction_v; // The n versions of the variable are the ones that are normalized and used // for the binary ouput but are not used for generating the decimal values char* binary_integer_n = malloc(BUF); strcpy(binary_integer_n, binary_integer_v); char* binary_fraction_n = malloc(BUF); strcpy(binary_fraction_n, binary_fraction_v); int binary_exponent_n = binary_exponent_v; while(atoi(binary_integer_n) > 1) { temp[0] = binary_integer_n[strlen(binary_integer_n)-1]; temp[1] = '\0'; // strcpy(temp,&(binary_integer_n[strlen(binary_integer_n)-1])); strcpy(binary_fraction_n, strcat(temp, binary_fraction_n)); //strcpy(binary_integer_n, substr(binary_integer_n,0, strlen(binary_integer_n) - 1)); binary_integer_n[strlen(binary_integer_n)-1] = '\0'; binary_exponent_n++; } while (strcmp(binary_integer_n,"0") == 0) { binary_integer_n[0] = binary_fraction_n[0]; binary_integer_n[1] = '\0'; // strcpy(binary_integer_n, binary_fraction_n); // strcpy(binary_fraction_n, substr(binary_fraction_n,1,strlen(binary_fraction_n)-1)); substr1(binary_fraction_n); binary_exponent_n--; } if (binary_fraction_n[0] == '\0') { strcpy(binary_fraction_n, "0"); } //printf("bi %s\n",binary_integer_v); //these are copies of the originals char* binary_integer = malloc(BUF); strcpy(binary_integer, binary_integer_v); char* binary_fraction = malloc(BUF); strcpy(binary_fraction, binary_fraction_v); int binary_exponent = binary_exponent_v; //printf("bi %s\n",binary_integer); while (binary_exponent > 0) { int a = strlen(binary_integer); binary_integer[a] = binary_fraction[0]; binary_integer[a+1] = '\0'; //strcpy(binary_fraction, substr(binary_fraction,1,strlen(binary_fraction-1))); substr1(binary_fraction); if (binary_fraction[0] == '\0') { strcpy(binary_fraction, "0"); } binary_exponent--; } ////printf("space needed: %d\n", (int) binary_fraction - (int) binary_fraction_backing); //printf("bi %s\n",binary_integer); while (binary_exponent < 0) { //strcpy(temp, &(binary_integer[strlen(binary_integer) - 1])); temp[0] = binary_integer[strlen(binary_integer) - 1]; temp[1] = '\0'; strcpy(binary_fraction, strcat(temp, binary_fraction)); //strcpy(binary_integer, substr(binary_integer,0, strlen(binary_integer) - 1)); binary_integer[strlen(binary_integer)-1] = '\0'; if (binary_integer[0] == '\0') { strcpy(binary_integer, "0"); } binary_exponent++; } // Decimal integer part strcpy(decimal_integer, "0"); mpz_t power_of_two; mpz_init(power_of_two); mpz_set_ui(power_of_two, 1); mpz_t di; mpz_init(di); mpz_set_ui(di, 0); //printf("bin int len: %s\n", binary_integer); //int aa = 0, b = 0; for (int i = strlen(binary_integer) - 1; i > -1; i--) { // if it's a 1 you add the decimal integer to the power of two (power of // two starts at 1) if (binary_integer[i] == '1') { mpz_add(di, di, power_of_two); //printf("di %s\n", mpz_get_str(NULL,10,power_of_two)); //aa++; } mpz_add(power_of_two, power_of_two, power_of_two); //double the power_of_two //printf("power_of_two b=%d %s\n", b, mpz_get_str(NULL,10,power_of_two)); //b++; } //printf("aa = %d\nb = %d\n",aa,b); // Decimal fraction part // reset the power_of_two back to 1 mpz_set_ui(power_of_two, 1); mpz_t df; mpz_init(df); mpz_set_ui(df, 0); strcpy(decimal_fraction, "0"); //printf("binary_fraction pre-add: %s\n", binary_fraction); int j = 0, k = 0; for (int i = strlen(binary_fraction) - 1; i > -1; i--) { // if it is 1 add the decimal fraction to the power of two if (binary_fraction[i] == '1') { j++; mpz_add(df, df, power_of_two); } mpz_add(power_of_two, power_of_two, power_of_two); //double the power_of_two k++; } //printf("j = %d\nk = %d\n",j,k); //printf("df %s\n", mpz_get_str(NULL, 10, df)); //printf("powtwo %s\n", mpz_get_str(NULL, 10, power_of_two)); mpf_set_default_prec(1000); mpf_t decf; mpf_init(decf); mpf_set_z(decf, df); //int n = 10; mpf_t powtwo; mpf_init(powtwo); mpf_set_z(powtwo, power_of_two); mpf_div(decf, decf, powtwo); // Normalize decimal_exponent = 0; char* ditemp = malloc(BUF); char* dftemp = malloc(BUF); mpz_get_str(ditemp, 10, di); //printf("ditemp %s\n", ditemp); strcpy(decimal_integer, ditemp); mp_exp_t a; mpf_get_str(dftemp, &a, 10, 10000, decf); strcpy(decimal_fraction, dftemp); /* while( a <0) { strcpy(decimal_fraction, strcat("0", decimal_fraction)); a++; } */ prepend(decimal_fraction, repeat_char('0', abs(a))); while (strlen(decimal_integer)>1) { temp[0] = decimal_integer[strlen(decimal_integer)-1]; temp[1] = '\0'; //strcpy(temp, &(decimal_integer[strlen(decimal_integer)-1])); strcpy(decimal_fraction, strcat(temp, decimal_fraction)); //strcpy(decimal_integer, substr(decimal_integer,0, strlen(decimal_integer) - 1)); decimal_integer[strlen(decimal_integer)-1] = '\0'; decimal_exponent++; } while (strcmp(decimal_integer, "0") == 0) { decimal_integer[0] = decimal_fraction[0]; decimal_integer[1] = '\0'; //strcpy(decimal_integer, decimal_fraction); //strcpy(decimal_fraction, substr(decimal_fraction,1,strlen(decimal_fraction)-1)); substr1(decimal_fraction); decimal_exponent--; } if (decimal_integer[0] == '\0') { strcpy(decimal_integer, "0"); } if (decimal_fraction[0] == '\0') { strcpy(decimal_fraction, "0"); } char* tempDI = malloc(BUF); strcpy( tempDI, decimal_integer); while (tempDI[0] == '0') { //strcpy(tempDI, substr(tempDI,1,strlen(tempDI)-1)); substr1(tempDI); } if (tempDI[0] == '\0') strcpy(tempDI, "0"); strcpy(decimal_integer, tempDI); printf("%s\n", decimal_integer); printf("%s\n", decimal_fraction); printf("%d\n", decimal_exponent); printf("%s\n", decimal_recurrence); printf("%d\n", decimal_recurrence_start); printf("%s\n", binary_recurrence); printf("%d\n", binary_recurrence_start); // These bottom three are the normalized binary values that also have to be // returned to the Javascript printf("%s\n", binary_integer_n); printf("%s\n", binary_fraction_n); printf("%d\n", binary_exponent_n); mpf_clear(decf); mpf_clear(powtwo); mpz_clear(result); mpz_clear(di); mpz_clear(df); free(binary_integer_n); free(binary_fraction_n); free(binary_integer_v); free(binary_fraction_v); free(binary_integer); free(binary_fraction); free(binary_recurrence); free(decimal_recurrence); free(decimal_integer); free(decimal_fraction); free(tempDI); free(ditemp); free(dftemp); free(temp); return 0; }
void check_one (mpz_srcptr z) { static const int shift[] = { 0, 1, BITS_PER_MP_LIMB, 2*BITS_PER_MP_LIMB, 5*BITS_PER_MP_LIMB }; int sh, shneg, neg; mpf_t f; mpz_t got, want; mpf_init2 (f, mpz_sizeinbase(z,2)); mpz_init (got); mpz_init (want); for (sh = 0; sh < numberof(shift); sh++) { for (shneg = 0; shneg <= 1; shneg++) { for (neg = 0; neg <= 1; neg++) { mpf_set_z (f, z); mpz_set (want, z); if (neg) { mpf_neg (f, f); mpz_neg (want, want); } if (shneg) { mpz_tdiv_q_2exp (want, want, shift[sh]); mpf_div_2exp (f, f, shift[sh]); } else { mpz_mul_2exp (want, want, shift[sh]); mpf_mul_2exp (f, f, shift[sh]); } mpz_set_f (got, f); MPZ_CHECK_FORMAT (got); if (mpz_cmp (got, want) != 0) { printf ("wrong result\n"); printf (" shift %d\n", shneg ? -shift[sh] : shift[sh]); printf (" neg %d\n", neg); mpf_trace (" f", f); mpz_trace (" got", got); mpz_trace (" want", want); abort (); } } } } mpf_clear (f); mpz_clear (got); mpz_clear (want); }
//------------------------------------------------------------------------------ // Name: //------------------------------------------------------------------------------ knumber_float::knumber_float(const knumber_integer *value) { mpf_init(mpf_); mpf_set_z(mpf_, value->mpz_); }
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); }
void w3j(mpf_t w, long j1, long j2, long j3, long m1, long m2, long m3) { mpq_t delta_sq,r; mpz_t i; mpf_t h; mpq_init(delta_sq); mpq_init(r); mpz_init(i); mpf_init(h); mpq_set_si(r,0,1); if(m1+m2+m3!=0) return; if((iabs(m1)>j1) || (iabs(m2)>j2) || (iabs(m3)>j3)) return; if((j3<iabs(j1-j2)) || ((j1+j2)<j3)) return; w3j_Delta_sq(delta_sq, j1, j2, j3); w3j_intterm(i, j1, j2, j3, m1, m2, m3); if(iabs(j1-j2-m3)%2 == 1) mpz_neg(i,i); w3j_sqrt_sq(r, j1, j2, j3, m1, m2, m3); mpq_mul(r,r,delta_sq); mpf_set_q(w,r); mpf_sqrt(w,w); mpf_set_z(h,i); mpf_mul(w,w,h); mpf_clear(h); mpz_clear(i); mpq_clear(r); mpq_clear(delta_sq); }