c# 4.0 - Calculating fibonacci -
i sent nice non-recursive function computing fibonacci sequence.
so coded bit of c# , able verify numbers 1474 correct.
the problem comes in when attempting calculate 1475 , above. c# math skills aren't task of figuring out different way. so, have better way of expressing particular math function in c#? other traditional way of doing recursive function?
incidentally, started use biginteger return type. problem comes in when trying raise (1+math.sqrt(5) /2) 1475th power. don't see data type need (nor mechanism matter) come other infinity.
here's starting point.
private double fibsequence(int32 input) { double part1 = (1 / math.sqrt(5)); double part2 = math.pow(((1 + math.sqrt(5)) / 2), input); double part3 = math.pow(((1 - math.sqrt(5)) / 2), input); return (part1 * part2) - (part1 * part3); }
and, no, it's not homework. "simple" problem slow day.
i don't think c# has data type enough floating precision , range handle naïvely.
if want go down path, can notice conjugate less one, same rounding nearest integer, can simplify solution finding . use binomial expansion have calculate , appropriate a , b (which rational , can computed biginteger). if still go double this, still won't further 1475, should able figure out how part exact integer math ☺
there's neat method computing fibonacci numbers, using matrix exponentiation:
this can done in o(log n) if you're clever.
i ended implementing these in haskell. fib1
matrix exponentiation , fib2
exact integer translation of closed-form formula, described above. respective runtimes this, measured criterion when compiled ghc 7.0.3:
import control.arrow import data.list import data.ratio newtype matrix2 = matrix2 (a, a, a, a) deriving (show, eq) instance (num a) => num (matrix2 a) matrix2 (a, b, c, d) * matrix2 (e, f, g, h) = matrix2 (a*e+b*g, a*f+b*h, c*e+d*g, c*f+d*h) frominteger x = let y = frominteger x in matrix2 (y, 0, 0, y) fib1 n = let matrix2 (_, x, _, _) = matrix2 (1, 1, 1, 0) ^ n in x binom n = scanl (\a (b, c)-> a*b `div` c) 1 $ takewhile ((/=) 0 . fst) $ iterate (pred *** succ) (n, 1) evens (x:_:xs) = x : evens xs evens xs = xs odds (_:x:xs) = x : odds xs odds _ = [] iterate' f x = x : (iterate' f $! f x) powers b = iterate' (b *) 1 esqrt e n = x (_, x):_ = dropwhile ((<=) e . abs . uncurry (-)) $ zip trials (tail trials) trials = iterate (\x -> (x + n / x) / 2) n fib' n = (a, b) d = 2 ^ n = sum (zipwith (*) (odds $ binom n) (powers 5)) % d b = sum (zipwith (*) (evens $ binom n) (powers 5)) % d fib2 n = numerator r `div` denominator r (a, b) = fib' n l = lcm (denominator a) (denominator a) r = + esqrt (1 % max 3 l) (b * b / 5) + 1 % 2
Comments
Post a Comment