x86-64 assembly, 13 12 bytes
6a 01 58 99 92 01 c2 39 fa 75 f9 c3
In assembly:
previous:
push 1
pop rax
cdq # zeroes rdx
previous_loop:
xchg eax,edx
add edx,eax
cmp edx,edi
jne previous_loop
ret
Try it online!
Uses the usual calling convention of taking the first argument in rdi
and returning in rax
. It's also valid x86-32, just with edi
and eax
instead.
It's pretty simple- it just explicitly computes Fibonacci numbers and returns if the new number is equal to the input. At the end of a loop, rdx
contains the next Fibonacci number and rax
contains the previous. If rdx
is equal to the input rdi
, then the loop terminates (and thus rax
, the previous number, is returned). Otherwise the two are swapped, and the loop begins again.
This uses 32-bit registers to save a few bytes, so it only works up to the 47th Fibonacci number, 2971215073
. It can be expanded to work with 64-bit numbers by changing all the registers to 64-bit, at the cost of 2 bytes:
6a 01 58 99 48 0f c1 c2 48 39 fa 75 f7 c3
The added bytes are the REX.W (0x48
) prefix that swaps the operand size to 64-bit. xchg rax,rdx; add rdx,rax
is also replaced with xadd rdx,rax
, which is shorter because it uses one fewer REX.W prefix.
-1 byte thanks to @PeterCordes.