Magical Fibonacci Formulae
orlp.net
orlp.net
I think the post says b=3^n and b=2^{n+1} were "experimentally found" to be enough, which raises the question: can we say what's the smallest base that would work, for a given n?
So to calculate the best base for the n'th Fibonacci number, compute the (n+1)th Fibonacci number and then add one to that, should do the trick. (Whoops, stack is overflowing, whyyyyyy)
I'm assuming that if 2^n doesn't work it's only because you get a wrong result for n=0? Then 1+2^n should beat both of these. And the issue there seems to be unrelated to precision, it is just that the denominator 1 – b^-1 – b^-2 < 0, which requires b > phi at all times, but in that case I am surprised that 3^n works at n=0. But, if you want to stay above phi, maybe b := 1 + 13*n // 8*n wastes a bit less memory.
For anyone who only has floating-point handy, try `1.0/9899` for a faster-to-break-down but still illustrative example.
One non-obvious aspect is that the function relies on using Python's big ints, even for pretty small values of n. You are calculating `2^(n(n+1))` for the numerator, so if n=8 you already get `2^72`, which you can't fit in a 64-bit int. This is even though the answer itself is very small: `F_8=21`.
This makes sense, because you are essentially packing all the previous Fibonnaci numbers into a bit string, so you need room for all of them without overlapping and that bit-string is going to necessarily be long.
function f(n)
b = big(2) << n
return b^(n+1) ÷ (b^2-b-1) % b
end
or for code golf: f(n;b=big(2)<<n)=b^(n+1)÷(b^2-b-1)%b
With "big" f.(1:10) gives the expected answer.I'd venture to say that it is clear that we can't really do better than O(log n) just because the number of digits in Fib(n) is O(log n).
Published continuously since 1963.
Can a number representing pi be done the same way? What about the golden ratio?
I bet a magic number exists for those like 998999. Interestingly, 1,000,000 - 998999 is just 1001. Which if done recursively and added to the prior iteration starts counting. 1.001, 1.002 and so on.
In a way it seems that only 0 and 1 really exist with everything being able to be represented between the two, essentially making infinity = 1
[1](https://orlp.net/blog/magical-fibonacci-formulae/#an-interlu...)
Cool!
> [f(n) for n in range(10)]
> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
Or in Haskell, without the cute generating function tricks:
take 10 $ let f a b = a : f b (a+b) in f 0 1
f = 0:1:zipWith (+) f (tail f) from itertools import pairwise, chain
def f(): yield from chain([0,1], map(sum, pairwise(f())))
There's a Joel Grus post discussing it: https://joelgrus.com/2015/07/07/haskell-style-fibonacci-in-p...The introduction of pairwise in 3.10 made possible to write it more compactly, when compared to the version discussed by Joel.