static PyObject * GMPy_MPZ_Function_Fib2(PyObject *self, PyObject *other) { PyObject *result = NULL; MPZ_Object *fib1 = NULL, *fib2 = NULL; unsigned long n; n = c_ulong_From_Integer(other); if (n == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } if (!(result = PyTuple_New(2)) || !(fib1 = GMPy_MPZ_New(NULL)) || !(fib2 = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ Py_XDECREF(result); Py_XDECREF((PyObject*)fib1); Py_XDECREF((PyObject*)fib2); result = NULL; /* LCOV_EXCL_STOP */ } mpz_fib2_ui(fib1->z, fib2->z, n); PyTuple_SET_ITEM(result, 0, (PyObject*)fib1); PyTuple_SET_ITEM(result, 1, (PyObject*)fib2); return (PyObject*)result; }
void fibonacci2(const Ptr<RCP<const Integer>> &g, const Ptr<RCP<const Integer>> &s, unsigned long n) { mpz_t g_t; mpz_t s_t; mpz_init(g_t); mpz_init(s_t); mpz_fib2_ui(g_t, s_t, n); *g = integer(mpz_class(g_t)); *s = integer(mpz_class(s_t)); mpz_clear(g_t); mpz_clear(s_t); }
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); }
int main(void) { const unsigned long offset = 50000, limit = 1000000; mpz_t fib0, fib; mpz_init(fib); mpz_init(fib0); mpz_fib2_ui(fib, fib0, offset - 1); /* F(n), for n = 1000000, has 208988 digits */ char* numstr = calloc(210000 * sizeof(char), sizeof(char)); char* numstr_end = numstr; for (unsigned long i = offset; i <= limit; ++i) { if (i % 5000 == 0) { printf("Crossed... %lu\n", i); } mpz_add(fib0, fib0, fib); mpz_swap(fib0, fib); mpz_get_str(numstr, 10, fib); unsigned int pandigital = 0; for (int x = 0; x <= 8; ++x) { if (*(numstr + x) - '0') { pandigital |= 1 << (*(numstr + x) - '1'); } } if (pandigital != 0x1FF) { continue; } printf("First 9 pandigital :: %lu\n", i); while (*numstr_end) ++numstr_end; pandigital = 0; for (int x = 1; x <= 9; ++x) { if (*(numstr_end - x) - '0') { pandigital |= 1 << (*(numstr_end - x) - '1'); } } if (pandigital != 0x1FF) { continue; } printf("i => %lu\n", i); break; } free(numstr); mpz_clear(fib0); mpz_clear(fib); return 0; }