mpf_class printGrowthConstant(Motzkin& motzkinInfo, int precision = 15, int maximumIteration = -1) { cout << setprecision(precision); int i = 1; IterationVector old_vector(motzkinInfo, precision); while (1) { i++; IterationVector new_vector = old_vector.iterate(); mpf_class temp(new_vector.cell_value(1) / old_vector.cell_value(1), precision); mpf_class min = temp; mpf_class max = temp; for (mpz_class j=2; j< new_vector.get_size(); j++) { temp = new_vector.cell_value(j) / old_vector.cell_value(j); if (min > temp) { min = temp; } if (max < temp) { max = temp; } } // cout << "n="<<i<<endl<<"min = "<< min << endl << "max = " << max <<endl; if (mpf_eq(min.get_mpf_t(), max.get_mpf_t(), temp.get_prec()) || (maximumIteration > 0 && i > maximumIteration)) return min; old_vector = new_vector; } }
/* * Evaluate the series 1/0! + 1/1! + 1/2! + 1/3! + 1/4! ... * On input, 'bits' is the desired precision in bits. * On output, e' contains the calculated value. */ static void calculateE( unsigned bits, mpf_t e) { mpf_t lastE; mpf_t invFact; /* 1/2!, 1/3!, 1/4!, etc. */ unsigned term; /* 2, 3, 4... */ /* initial conditions, including the first two terms */ mpf_init_set_ui(lastE, 0); mpf_set_ui(e, 2); mpf_init_set_ui(invFact, 1); /* 1/1! */ term = 2; for(;;) { /* invFact /= (term) */ mpf_div_ui(invFact, invFact, term); /* e += 1 / (term!) */ mpf_add(e, e, invFact); /* if e == lastE, within the requested precision, we're done */ if(mpf_eq(e, lastE, bits)) { break; } mpf_set(lastE, e); term++; } /* free memory associated with mpf_t's we allocated */ mpf_clear(lastE); mpf_clear(invFact); }
// // 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_class & pi ) { mpf_class lastPi( 0.0 ); mpf_class scratch; // variables per the formal Gauss - Legendre formulae mpf_class a; mpf_class b; mpf_class t; mpf_class x; mpf_class y; unsigned p = 1; // initial conditions a = 1; // b := 1 / sqrt( 2 ) mpf_sqrt_ui( b.get_mpf_t( ), 2 ); b = 1.0 / b; t = 0.25; for( ;; ) { x = ( a + b )/2; // y := sqrt( ab ) y = a * b; mpf_sqrt( y.get_mpf_t( ), y.get_mpf_t( ) ); // t := t - p * ( a - x )**2 scratch = a - x; scratch *= scratch; scratch *= p; t -= scratch; a = x; b = y; p <<= 1; // pi := ( ( a + b )**2 ) / 4t pi = a + b; pi *= pi; pi /= ( 4 * t ); // if pi == lastPi, within the requested precision, we're done if ( mpf_eq( pi.get_mpf_t( ), lastPi.get_mpf_t( ), bits ) ) { break; } lastPi = pi; } }
/* * Evaluate the series 1/0! + 1/1! + 1/2! + 1/3! + 1/4! ... * On input, 'bits' is the desired precision in bits. * On output, e' contains the calculated value. */ static void calculateE( unsigned bits, mpf_class &e) { /* initial conditions, including the first two terms */ mpf_class lastE(0.0); mpf_class invFact(1.0); /* 1/2!, 1/3!, 1/4!, etc. */ unsigned term = 2; /* 2, 3, 4... */ e = 2; for(;;) { invFact /= term; e += invFact; /* if e == lastE, within the requested precision, we're done */ if(mpf_eq(e.get_mpf_t(), lastE.get_mpf_t(), bits)) { return; } lastE = e; term++; } /* NOT REACHED */ }
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); }
void check_data (void) { static const struct { struct { int exp, size; mp_limb_t d[10]; } x, y; mp_bitcnt_t bits; int want; } data[] = { { { 0, 0, { 0 } }, { 0, 0, { 0 } }, 0, 1 }, { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 0, 1 }, { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 17, 1 }, { { 0, 1, { 7 } }, { 0, 1, { 7 } }, 4711, 1 }, { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 0, 1 }, { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 2, 1 }, { { 0, 1, { 7 } }, { 0, 1, { 6 } }, 3, 0 }, { { 0, 0, { 0 } }, { 0, 1, { 1 } }, 0, 0 }, { { 0, 1, { 1 } }, { 0,-1 ,{ 1 } }, 0, 0 }, { { 1, 1, { 1 } }, { 0, 1, { 1 } }, 0, 0 }, { { 0, 1, { 8 } }, { 0, 1, { 4 } }, 0, 0 }, { { 0, 2, { 0, 3 } }, { 0, 1, { 3 } }, 1000, 1 }, }; mpf_t x, y; int got, got_swapped; int i; mp_trace_base = 16; for (i = 0; i < numberof (data); i++) { PTR(x) = (mp_ptr) data[i].x.d; SIZ(x) = data[i].x.size; EXP(x) = data[i].x.exp; PREC(x) = numberof (data[i].x.d); MPF_CHECK_FORMAT (x); PTR(y) = (mp_ptr) data[i].y.d; SIZ(y) = data[i].y.size; EXP(y) = data[i].y.exp; PREC(y) = numberof (data[i].y.d); MPF_CHECK_FORMAT (y); got = mpf_eq (x, y, data[i].bits); got_swapped = mpf_eq (y, x, data[i].bits); if (got != got_swapped || got != data[i].want) { printf ("check_data() wrong result at data[%d]\n", i); mpf_trace ("x ", x); mpf_trace ("y ", y); printf ("got %d\n", got); printf ("got_swapped %d\n", got_swapped); printf ("want %d\n", data[i].want); abort (); } } }
// // 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); }