static int fib(int n) { return n > 1 ? fib(n - 1) + fib(n - 2) : n; } Func<int, int> fib = Y<int,int>(f => n => n > 1 ? f(n - 1) + f(n - 2) : n); Y defined, for example, like this: static Func<A, R> Y<A, R>(Func<Func<A, R>, Func<A, R>> f) { Func<A, R> g = null; g = f(a=>g(a)); return g; } x*x is considered faster than Math.Pow(x,2) ? Because for the integer degree, you can not only do without the Taylor series, but also optimize the calculation for large degrees by creating temporary variables. For example, x 4 can be considered as int y = x * x; return y * y; int y = x * x; return y * y; - and the greater the degree, the greater the savings.
short . public static long IntPower(int x, short power) { if (power == 0) return 1; if (power == 1) return x; int n = 15; while ((power <<= 1) >= 0) n--; long tmp = x; while (--n > 0) tmp = tmp * tmp * (((power <<= 1) < 0) ? x : 1); return tmp; } struct mtx2x2 { public int _11, _12, _21, _22; public static mtx2x2 operator*(mtx2x2 lhs, mtx2x2 rhs) { return new mtx2x2 { _11 = lhs._11*rhs._11 + lhs._12*rhs._21, _12 = lhs._11*rhs._12 + lhs._12*rhs._22, _21 = lhs._21*rhs._11 + lhs._22*rhs._21, _22 = lhs._21*rhs._12 + lhs._22*rhs._22 }; } } private static readonly mtx2x2 fibMtx = new mtx2x2 {_11 = 1, _12 = 1, _21 = 1}; private static readonly mtx2x2 identity = new mtx2x2 {_11 = 1, _22 = 1}; IntPower() method for 2 × 2 matrices: public static mtx2x2 IntPower(mtx2x2 x, short power) { if (power == 0) return identity; if (power == 1) return x; int n = 15; while ((power <<= 1) >= 0) n--; mtx2x2 tmp = x; while (--n > 0) tmp = (tmp * tmp) * (((power <<= 1) < 0) ? x : identity); return tmp; } static int fibm(short n) { return IntPower(fibMtx, (short)(n-1))._11; } fib(40) considered 4 seconds, and fibm(40) is displayed immediately. ■Source: https://habr.com/ru/post/83303/
All Articles