Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here's a straightforward translation of the formula to Haskell: </p> <pre><code>fib n = round $ (phi^n - (1 - phi)^n) / sqrt 5 where phi = (1 + sqrt 5) / 2 </code></pre> <p>This gives correct values only up to <code>n = 75</code>, because it uses <code>Double</code> precision floating-point arithmetic.</p> <p>However, we can avoid floating-point arithmetic by working with numbers of the form <code>a + b * sqrt 5</code>! Let's make a data type for them:</p> <pre><code>data Ext = Ext !Integer !Integer deriving (Eq, Show) instance Num Ext where fromInteger a = Ext a 0 negate (Ext a b) = Ext (-a) (-b) (Ext a b) + (Ext c d) = Ext (a+c) (b+d) (Ext a b) * (Ext c d) = Ext (a*c + 5*b*d) (a*d + b*c) -- easy to work out on paper -- remaining instance methods are not needed </code></pre> <p>We get exponentiation for free since it is implemented in terms of the <code>Num</code> methods. Now, we have to rearrange the formula slightly to use this.</p> <pre><code>fib n = divide $ twoPhi^n - (2-twoPhi)^n where twoPhi = Ext 1 1 divide (Ext 0 b) = b `div` 2^n -- effectively divides by 2^n * sqrt 5 </code></pre> <p>This gives an exact answer.</p> <hr> <p>Daniel Fischer points out that we can use the formula <code>phi^n = fib(n-1) + fib(n)*phi</code> and work with numbers of the form <code>a + b * phi</code> (i.e. ℤ[φ]). This avoids the clumsy division step, and uses only one exponentiation. This gives a much nicer implementation:</p> <pre><code>data ZPhi = ZPhi !Integer !Integer deriving (Eq, Show) instance Num ZPhi where fromInteger n = ZPhi n 0 negate (ZPhi a b) = ZPhi (-a) (-b) (ZPhi a b) + (ZPhi c d) = ZPhi (a+c) (b+d) (ZPhi a b) * (ZPhi c d) = ZPhi (a*c+b*d) (a*d+b*c+b*d) fib n = let ZPhi _ x = phi^n in x where phi = ZPhi 0 1 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload