void fmpz_fib_ui(fmpz_t f, ulong n) { if (n < NUM_SMALL_FIB) fmpz_set_ui(f, small_fib[n]); else mpz_fib_ui(_fmpz_promote(f), n); }
RCP<const Integer> fibonacci(unsigned long n) { mpz_class f; mpz_fib_ui(f.get_mpz_t(), n); return integer(f); }
int main() { mpz_t f; mpz_init(f); mpz_fib_ui(f, 1073741825); print_state(&f, 1073741825); return 0; }
static int mixed (void) { int n1; int n2; int i = 121; #ifndef NPRINTF_L long double d = 1. / 31.; #endif mpf_t mpf; mpq_t mpq; mpz_t mpz; mpfr_t x; mpfr_rnd_t rnd; mpf_init (mpf); mpf_set_ui (mpf, 40); mpf_div_ui (mpf, mpf, 31); /* mpf = 40.0 / 31.0 */ mpq_init (mpq); mpq_set_ui (mpq, 123456, 4567890); mpz_init (mpz); mpz_fib_ui (mpz, 64); mpfr_init (x); mpfr_set_str (x, "-12345678.875", 10, MPFR_RNDN); rnd = MPFR_RNDD; check_vsprintf ("121%", "%i%%", i); check_vsprintf ("121% -1.2345678875E+07", "%i%% %RNE", i, x); check_vsprintf ("121, -12345679", "%i, %.0Rf", i, x); check_vsprintf ("10610209857723, -1.2345678875e+07", "%Zi, %R*e", mpz, rnd, x); check_vsprintf ("-12345678.9, 121", "%.1Rf, %i", x, i); check_vsprintf ("-12345678, 1e240/45b352", "%.0R*f, %Qx", MPFR_RNDZ, x, mpq); n1 = check_vsprintf ("121, -12345678.875000000000, 1.290323", "%i, %.*Rf, %Ff%n", i, 12, x, mpf, &n2); if (n1 != n2) { printf ("error in number of characters written by mpfr_vsprintf\n"); printf ("expected: %d\n", n2); printf (" got: %d\n", n1); exit (1); } #ifndef NPRINTF_L check_vsprintf ("00000010610209857723, -1.2345678875e+07, 0.032258", "%.*Zi, %R*e, %Lf", 20, mpz, rnd, x, d); #endif mpf_clear (mpf); mpq_clear (mpq); mpz_clear (mpz); mpfr_clear (x); return 0; }
// Courtesy of http://oeis.org/A007805 int main() { mpz_class sum = 0; for (int n = 1; n <= 12; ++n) { mpz_class l; mpz_fib_ui(l.get_mpz_t(), 6 * n + 3); sum += l / 2; } std::cout << sum << "\n"; return 0; }
static PyObject * GMPy_MPZ_Function_Fib(PyObject *self, PyObject *other) { MPZ_Object *result = NULL; unsigned long n; n = c_ulong_From_Integer(other); if (n == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_fib_ui(result->z, n); } return (PyObject*)result; }
int main(int argc, char* argv[]) { mpz_t n; char* s; unsigned long int i; mpz_init(n); i = 0; while(1) { mpz_fib_ui(n, ++i); s = mpz_get_str(NULL, 10, n); if (strlen(s) >= 1000) { break; } free(s); } mpz_clear(n); printf("%lu\n", i); return 0; }
/* Evaluate the expression E and put the result in R. */ void mpz_eval_expr (mpz_ptr r, expr_t e) { mpz_t lhs, rhs; switch (e->op) { case LIT: mpz_set (r, e->operands.val); return; case PLUS: mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); mpz_add (r, lhs, rhs); mpz_clear (lhs); mpz_clear (rhs); return; case MINUS: mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); mpz_sub (r, lhs, rhs); mpz_clear (lhs); mpz_clear (rhs); return; case MULT: mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); mpz_mul (r, lhs, rhs); mpz_clear (lhs); mpz_clear (rhs); return; case DIV: mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); mpz_fdiv_q (r, lhs, rhs); mpz_clear (lhs); mpz_clear (rhs); return; case MOD: mpz_init (rhs); mpz_eval_expr (rhs, e->operands.ops.rhs); mpz_abs (rhs, rhs); mpz_eval_mod_expr (r, e->operands.ops.lhs, rhs); mpz_clear (rhs); return; case REM: /* Check if lhs operand is POW expression and optimize for that case. */ if (e->operands.ops.lhs->op == POW) { mpz_t powlhs, powrhs; mpz_init (powlhs); mpz_init (powrhs); mpz_init (rhs); mpz_eval_expr (powlhs, e->operands.ops.lhs->operands.ops.lhs); mpz_eval_expr (powrhs, e->operands.ops.lhs->operands.ops.rhs); mpz_eval_expr (rhs, e->operands.ops.rhs); mpz_powm (r, powlhs, powrhs, rhs); if (mpz_cmp_si (rhs, 0L) < 0) mpz_neg (r, r); mpz_clear (powlhs); mpz_clear (powrhs); mpz_clear (rhs); return; } mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); mpz_fdiv_r (r, lhs, rhs); mpz_clear (lhs); mpz_clear (rhs); return; #if __GNU_MP_VERSION >= 2 case INVMOD: mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); mpz_invert (r, lhs, rhs); mpz_clear (lhs); mpz_clear (rhs); return; #endif case POW: mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); if (mpz_cmpabs_ui (lhs, 1) <= 0) { /* For 0^rhs and 1^rhs, we just need to verify that rhs is well-defined. For (-1)^rhs we need to determine (rhs mod 2). For simplicity, compute (rhs mod 2) for all three cases. */ expr_t two, et; two = malloc (sizeof (struct expr)); two -> op = LIT; mpz_init_set_ui (two->operands.val, 2L); makeexp (&et, MOD, e->operands.ops.rhs, two); e->operands.ops.rhs = et; } mpz_eval_expr (rhs, e->operands.ops.rhs); if (mpz_cmp_si (rhs, 0L) == 0) /* x^0 is 1 */ mpz_set_ui (r, 1L); else if (mpz_cmp_si (lhs, 0L) == 0) /* 0^y (where y != 0) is 0 */ mpz_set_ui (r, 0L); else if (mpz_cmp_ui (lhs, 1L) == 0) /* 1^y is 1 */ mpz_set_ui (r, 1L); else if (mpz_cmp_si (lhs, -1L) == 0) /* (-1)^y just depends on whether y is even or odd */ mpz_set_si (r, (mpz_get_ui (rhs) & 1) ? -1L : 1L); else if (mpz_cmp_si (rhs, 0L) < 0) /* x^(-n) is 0 */ mpz_set_ui (r, 0L); else { unsigned long int cnt; unsigned long int y; /* error if exponent does not fit into an unsigned long int. */ if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0) goto pow_err; y = mpz_get_ui (rhs); /* x^y == (x/(2^c))^y * 2^(c*y) */ #if __GNU_MP_VERSION >= 2 cnt = mpz_scan1 (lhs, 0); #else cnt = 0; #endif if (cnt != 0) { if (y * cnt / cnt != y) goto pow_err; mpz_tdiv_q_2exp (lhs, lhs, cnt); mpz_pow_ui (r, lhs, y); mpz_mul_2exp (r, r, y * cnt); } else mpz_pow_ui (r, lhs, y); } mpz_clear (lhs); mpz_clear (rhs); return; pow_err: error = "result of `pow' operator too large"; mpz_clear (lhs); mpz_clear (rhs); longjmp (errjmpbuf, 1); case GCD: mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); mpz_gcd (r, lhs, rhs); mpz_clear (lhs); mpz_clear (rhs); return; #if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1 case LCM: mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); mpz_lcm (r, lhs, rhs); mpz_clear (lhs); mpz_clear (rhs); return; #endif case AND: mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); mpz_and (r, lhs, rhs); mpz_clear (lhs); mpz_clear (rhs); return; case IOR: mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); mpz_ior (r, lhs, rhs); mpz_clear (lhs); mpz_clear (rhs); return; #if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1 case XOR: mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); mpz_xor (r, lhs, rhs); mpz_clear (lhs); mpz_clear (rhs); return; #endif case NEG: mpz_eval_expr (r, e->operands.ops.lhs); mpz_neg (r, r); return; case NOT: mpz_eval_expr (r, e->operands.ops.lhs); mpz_com (r, r); return; case SQRT: mpz_init (lhs); mpz_eval_expr (lhs, e->operands.ops.lhs); if (mpz_sgn (lhs) < 0) { error = "cannot take square root of negative numbers"; mpz_clear (lhs); longjmp (errjmpbuf, 1); } mpz_sqrt (r, lhs); return; #if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1 case ROOT: mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); if (mpz_sgn (rhs) <= 0) { error = "cannot take non-positive root orders"; mpz_clear (lhs); mpz_clear (rhs); longjmp (errjmpbuf, 1); } if (mpz_sgn (lhs) < 0 && (mpz_get_ui (rhs) & 1) == 0) { error = "cannot take even root orders of negative numbers"; mpz_clear (lhs); mpz_clear (rhs); longjmp (errjmpbuf, 1); } { unsigned long int nth = mpz_get_ui (rhs); if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0) { /* If we are asked to take an awfully large root order, cheat and ask for the largest order we can pass to mpz_root. This saves some error prone special cases. */ nth = ~(unsigned long int) 0; } mpz_root (r, lhs, nth); } mpz_clear (lhs); mpz_clear (rhs); return; #endif case FAC: mpz_eval_expr (r, e->operands.ops.lhs); if (mpz_size (r) > 1) { error = "result of `!' operator too large"; longjmp (errjmpbuf, 1); } mpz_fac_ui (r, mpz_get_ui (r)); return; #if __GNU_MP_VERSION >= 2 case POPCNT: mpz_eval_expr (r, e->operands.ops.lhs); { long int cnt; cnt = mpz_popcount (r); mpz_set_si (r, cnt); } return; case HAMDIST: { long int cnt; mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); cnt = mpz_hamdist (lhs, rhs); mpz_clear (lhs); mpz_clear (rhs); mpz_set_si (r, cnt); } return; #endif case LOG2: mpz_eval_expr (r, e->operands.ops.lhs); { unsigned long int cnt; if (mpz_sgn (r) <= 0) { error = "logarithm of non-positive number"; longjmp (errjmpbuf, 1); } cnt = mpz_sizeinbase (r, 2); mpz_set_ui (r, cnt - 1); } return; case LOG: { unsigned long int cnt; mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); if (mpz_sgn (lhs) <= 0) { error = "logarithm of non-positive number"; mpz_clear (lhs); mpz_clear (rhs); longjmp (errjmpbuf, 1); } if (mpz_cmp_ui (rhs, 256) >= 0) { error = "logarithm base too large"; mpz_clear (lhs); mpz_clear (rhs); longjmp (errjmpbuf, 1); } cnt = mpz_sizeinbase (lhs, mpz_get_ui (rhs)); mpz_set_ui (r, cnt - 1); mpz_clear (lhs); mpz_clear (rhs); } return; case FERMAT: { unsigned long int t; mpz_init (lhs); mpz_eval_expr (lhs, e->operands.ops.lhs); t = (unsigned long int) 1 << mpz_get_ui (lhs); if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0 || t == 0) { error = "too large Mersenne number index"; mpz_clear (lhs); longjmp (errjmpbuf, 1); } mpz_set_ui (r, 1); mpz_mul_2exp (r, r, t); mpz_add_ui (r, r, 1); mpz_clear (lhs); } return; case MERSENNE: mpz_init (lhs); mpz_eval_expr (lhs, e->operands.ops.lhs); if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0) { error = "too large Mersenne number index"; mpz_clear (lhs); longjmp (errjmpbuf, 1); } mpz_set_ui (r, 1); mpz_mul_2exp (r, r, mpz_get_ui (lhs)); mpz_sub_ui (r, r, 1); mpz_clear (lhs); return; case FIBONACCI: { mpz_t t; unsigned long int n, i; mpz_init (lhs); mpz_eval_expr (lhs, e->operands.ops.lhs); if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0) { error = "Fibonacci index out of range"; mpz_clear (lhs); longjmp (errjmpbuf, 1); } n = mpz_get_ui (lhs); mpz_clear (lhs); #if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1 mpz_fib_ui (r, n); #else mpz_init_set_ui (t, 1); mpz_set_ui (r, 1); if (n <= 2) mpz_set_ui (r, 1); else { for (i = 3; i <= n; i++) { mpz_add (t, t, r); mpz_swap (t, r); } } mpz_clear (t); #endif } return; case RANDOM: { unsigned long int n; mpz_init (lhs); mpz_eval_expr (lhs, e->operands.ops.lhs); if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0) { error = "random number size out of range"; mpz_clear (lhs); longjmp (errjmpbuf, 1); } n = mpz_get_ui (lhs); mpz_clear (lhs); mpz_urandomb (r, rstate, n); } return; case NEXTPRIME: { mpz_eval_expr (r, e->operands.ops.lhs); mpz_nextprime (r, r); } return; case BINOM: mpz_init (lhs); mpz_init (rhs); mpz_eval_expr (lhs, e->operands.ops.lhs); mpz_eval_expr (rhs, e->operands.ops.rhs); { unsigned long int k; if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0) { error = "k too large in (n over k) expression"; mpz_clear (lhs); mpz_clear (rhs); longjmp (errjmpbuf, 1); } k = mpz_get_ui (rhs); mpz_bin_ui (r, lhs, k); } mpz_clear (lhs); mpz_clear (rhs); return; case TIMING: { int t0; t0 = cputime (); mpz_eval_expr (r, e->operands.ops.lhs); printf ("time: %d\n", cputime () - t0); } return; default: abort (); } }
int main (int argc, char *argv[]) { unsigned long n; unsigned long limit = 100 * BITS_PER_MP_LIMB; mpz_t want_fn, want_fn1, got_fn, got_fn1; tests_start (); mp_trace_base = -16; if (argc > 1 && argv[1][0] == 'x') limit = ULONG_MAX; else if (argc > 1) limit = atoi (argv[1]); check_fib_table (); /* start at n==0 */ mpz_init_set_ui (want_fn1, 1); /* F[-1] */ mpz_init_set_ui (want_fn, 0); /* F[0] */ mpz_init (got_fn); mpz_init (got_fn1); for (n = 0; n < limit; n++) { /* check our float formula seems right */ if (MPZ_FIB_SIZE_FLOAT (n) < SIZ(want_fn)) { printf ("MPZ_FIB_SIZE_FLOAT wrong at n=%lu\n", n); printf (" MPZ_FIB_SIZE_FLOAT %ld\n", MPZ_FIB_SIZE_FLOAT (n)); printf (" SIZ(want_fn) %d\n", SIZ(want_fn)); abort (); } /* check MPN_FIB2_SIZE seems right, compared to actual size and compared to our float formula */ if (MPN_FIB2_SIZE (n) < MPZ_FIB_SIZE_FLOAT (n)) { printf ("MPN_FIB2_SIZE wrong at n=%lu\n", n); printf (" MPN_FIB2_SIZE %ld\n", MPN_FIB2_SIZE (n)); printf (" MPZ_FIB_SIZE_FLOAT %ld\n", MPZ_FIB_SIZE_FLOAT (n)); abort (); } if (MPN_FIB2_SIZE (n) < SIZ(want_fn)) { printf ("MPN_FIB2_SIZE wrong at n=%lu\n", n); printf (" MPN_FIB2_SIZE %ld\n", MPN_FIB2_SIZE (n)); printf (" SIZ(want_fn) %d\n", SIZ(want_fn)); abort (); } mpz_fib2_ui (got_fn, got_fn1, n); MPZ_CHECK_FORMAT (got_fn); MPZ_CHECK_FORMAT (got_fn1); if (mpz_cmp (got_fn, want_fn) != 0 || mpz_cmp (got_fn1, want_fn1) != 0) { printf ("mpz_fib2_ui(%lu) wrong\n", n); mpz_trace ("want fn ", want_fn); mpz_trace ("got fn ", got_fn); mpz_trace ("want fn1", want_fn1); mpz_trace ("got fn1", got_fn1); abort (); } mpz_fib_ui (got_fn, n); MPZ_CHECK_FORMAT (got_fn); if (mpz_cmp (got_fn, want_fn) != 0) { printf ("mpz_fib_ui(%lu) wrong\n", n); mpz_trace ("want fn", want_fn); mpz_trace ("got fn", got_fn); abort (); } mpz_add (want_fn1, want_fn1, want_fn); /* F[n+1] = F[n] + F[n-1] */ mpz_swap (want_fn1, want_fn); } mpz_clear (want_fn); mpz_clear (want_fn1); mpz_clear (got_fn); mpz_clear (got_fn1); tests_end (); exit (0); }