Exact Fibonacci numbers — one of them 2090 digits long — with every calculation on the record.
fibonacci.py · output · proof · check · try it in the playground
The Fibonacci numbers start 0, 1, and each next one is the sum of the two before it: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, …
What is the 10th? The 100th? The 10000th? Exactly, to the last digit.
And a classic curiosity: dividing each number by the one before it gets closer and closer to the golden ratio, about 1.618. Can we watch that happen?
Adding one number at a time would take 10000 steps to reach F(10000). Fast doubling uses two formulas that jump from F(K) to F(2K):
So the index is halved at each step: 10 → 5 → 2 → 1 → 0. Even F(10000) needs only about 14 halvings.
implied_by(fib(N, F), (N >= 0) & fib_pair(N, F, _))
fact(fib_pair(0, 0, 1))
implied_by(
fib_pair(N, A, B),
(N > 0)
& is_(Half, N // 2)
& fib_pair(Half, X, Y)
& is_(C, X * (2 * Y - X))
& is_(D, X * X + Y * Y)
& parity_pair(N, C, D, A, B),
)
implied_by(parity_pair(N, C, D, A, B), eq(0, N % 2) & unify(A, C) & unify(B, D))
implied_by(parity_pair(N, C, D, A, B), eq(1, N % 2) & unify(A, D) & is_(B, C + D))
implied_by(
golden_ratio(N, Ratio),
fib(N, A)
& (A > 0)
& is_(Next, N + 1)
& fib(Next, B)
& is_(Ratio, B / A),
)
query(fib(10, F))
# … and the other questions
fib_pair computes two neighbours, F(N) and F(N+1), together. N // 2 is
“N divided by 2, rounded down”; parity_pair picks the formula for even or
odd N.
fib(0, 0)
fib(1, 1)
fib(10, 55)
fib(100, 354224848179261915075)
golden_ratio(1, 1.0)
golden_ratio(10, 1.6181818181818182)
golden_ratio(100, 1.618033988749895)
golden_ratio(1000, 1.618033988749895)
Plus two giants: F(1000) has 209 digits (434665576869…228875) and F(10000)
has 2090 (336447648764…366875). Integers in peye have no size limit, so
these are exact. The ratio B / A is ordinary division, so it gives a
decimal number even when it comes out whole: 1.0.
For F(10) = 55, the proof records each halving:
Every multiplication, subtraction and comparison is a step of its own.
A separate checker read all 314 steps of the proof against the program:
Verdict: checked. Nothing taken on trust.
python -m peye examples/fibonacci.py # the answers
python -m peye --proof examples/fibonacci.py # with their proof
Or open it in the playground.
Add the line query(fib(20, F)) and run again: the answers end with
fib(20, 6765).
A clever algorithm and a huge number need not mean “trust me”. Each shortcut is spelled out as ordinary arithmetic, and a checker redoes that arithmetic itself.