Вот Вам пушка для воробьев:
Math.Fibonacci = new function(cacheSize = 10){
var _current = 0, _cache = [], C = cacheSize
const A = 5 ** 0.5,
B = (1 + A) / 2,
LNb = Math.log( B ),
Y = x => cache.add( [ x, Math.round( B ** x / A ) ] )[ 1 ],
R = [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ],
X = y => Math.log( A * y ) / LNb,
cache = {
add: ( xy ) => {
if ( _cache.length == C ) _cache = _cache.slice(1,)
_cache.push(xy)
return xy
},
get: n => n in R ? R[n] : ( ( _i = _cache.findIndex(e=>e[0]==n)) != -1 ? _cache[_i][1] : null ),
find: x => ( _i = R.indexOf(x) ) != -1 ? _i : ( ( _i = _cache.findIndex(e=>e[1]==x)) != -1 ? _cache[_i][0] : null )
}
this.get = n => ( _value = cache.get( n ) ) !== null ? _value : Y( n );
this.find = x => {
if ( ( _value = cache.find( x ) ) !== null ) return _value
let a = this.adjacent( x );
return a[0][1] == x ? a[0][0] : ( a[1][1] == x ? a[1][0] : -1 )
}
this.adjacent = y => {
let x = X(y),
x1 = Math.floor(x),
x2 = Math.ceil(x),
y1 = Y(x1),
y2 = Y(x2);
if ( y1 == y ) return [ cache.add( [x1,y1] ), [x1,y1] ]
else if ( y2 == y ) return [ cache.add( [x2,y2] ), [x2,y2] ]
else return [ cache.add( [ x1, y1 ] ), cache.add( [ x2, y2 ] ) ]
}
this.setCacheSize = l => l > 0 ? C = l : false
this.next = _ => Y( ++_current )
this.prev = _ => Y( --_current )
this.current = _ => Y( _current )
}
Вытащите что Вам надо из Math.Fibonacci.adjacent
console.log( Math.Fibonacci.adjacent(20) )
// [ [7, 13], [8,21] ]
Где 7 и 8 порядковые номера чисел Фибоначчи 13 и 21 соответственно
Соответственно, решение:
let x = 20,
[ [_,min], [__,max] ] = Math.Fibonacci.adjacent( x )
x = min === max ? x : max;
console.log(x)
//21