5

I need to find a (the next) fibonacci number given a integer N. So let's say I have n = 13 and I need to output the next fibonacci number which is 21 but how do I do this? How can I find the previous number that summed up to form it?

I mean I could easily come up with a for/while loop that returns the fibonacci sequence but how can I find the next number by being given the previous one.

<?php

$n = 13;

while($n < 1000) {

    $n = $x + $y; 
    echo($n."<br />"); 
    $x = $y;
    $y = $n;
}
?>
Mike Fonder
  • 61
  • 2
  • 6
  • Why not just create a loop that continues one more iteration than it takes to get the inputted sum? This may not be the most efficient way to do this, but it is A way. – Brandon White Jun 17 '14 at 15:41
  • Could it be about the ratio of the two number that go into the term that you are given? The ration of the numbers tends towards 1.618. Is it then fairly easy to work out what the two integers must be? Divide the given term by 1.618 to get an idea of one of the digits? – Ryan Vincent Jun 17 '14 at 19:16

3 Answers3

4

You can use Binet's Formula:

          n          -n
F(n) = phi   - (-phi)
       ---------------
          sqrt(5)

where phi is the golden ratio (( 1 + sqrt(5) ) / 2) ~= 1.61803...

This lets you determine exactly the n-th term of the sequence.

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • How can I possibly implement that in PHP? – Mike Fonder Jun 17 '14 at 15:45
  • But this cannot help to find Fibonacci number closest to the given number – hindmost Jun 17 '14 at 15:46
  • @hindmost You could use the formula to find `n` for `F(n) = 13` then use it again to calculate n-1. – Jim Jun 17 '14 at 15:47
  • @hindmost: sure you can. start filling in `n` values and use a binary-type search to narrow down possible values. even a simple loop would be doable `$i = 0; while(F($i) <= $search_value) { $i++; }` – Marc B Jun 17 '14 at 15:48
  • @MikeFonder: it's just math. php is perfectly capable of doing exponentiation via `pow()`, and in v5.6+, it even has the `**` operator. – Marc B Jun 17 '14 at 15:49
  • @Marc B But this method doesn't much differ from the OP's iteration loop – hindmost Jun 17 '14 at 15:53
  • yes, but this lets you get arbitrary values. try F(0), then try F(10), F(100) etc.. until you get past whatever the test number is, then back off a bit. For large N (say a few million) this'll be cheaper than having to do a million addition iterations using the "Traditional" method. – Marc B Jun 17 '14 at 15:59
  • and since it IS just a basic math formula, you can always reverse it and solve for `n` given `F(n)`. – Marc B Jun 17 '14 at 16:00
  • I think the solution should be easier. Found this as a C++ homework for preliminary course at a college. – Mike Fonder Jun 17 '14 at 16:05
  • preliminary programming in college usually includes algebra, which is all this is... – Marc B Jun 17 '14 at 16:21
2

Using a loop you could store the values in an array that could stop immediately one key after finding the selected number in the previous keys value.

function getFib($n) {

   $fib = array($n+1);       // array to num + 1
   $fib[0] = 0; $fib[1] = 1; // set initial array keys
   $i;

   for ($i=2;$i<=$n+1;$i++) {
      $fib[$i] = $fib[$i-1]+$fib[$i-2];
        if ($fib[$i] > $n) { // check if key > num 
            return $fib[$i];
            }
        }
    if ($fib[$i-1] < $n) {   // check if key < num
        return $fib[$i-1] + $n;
    }
    if ($fib[$i] = $n-1) {   // check if key = num
        return $fib[$i-1] + $fib[$i-2];
    } 
    if ($fib[$i-1] = 1) {    // check if num = 1
        return $n + $n;
    }
}

$num = 13;
echo "next fibonacci number = " . getFib($num);

Please note that I haven't tested this out and the code could be optimized, so before downvoting consider this serves only as a concept to the question asked.

l'L'l
  • 44,951
  • 10
  • 95
  • 146
  • You're welcome, glad it helped. If you wanted to carry it a step further you could have it identify whether or not the `$num` is a fibonacci number as well. Here's a working example: http://ideone.com/vr5bJH – l'L'l Jun 18 '14 at 00:29
  • Yes, I wrote something similar afterwards. Anyway, I've another quick question. How can I get the first N members of the sequence? So far I've come up to this only: http://pastebin.com/qHvjUzdC But in this way I output only numbers starting from 3 and I also need 0,1,1 and 2 as of the beginning of the fibonacci series. – Mike Fonder Jun 18 '14 at 01:26
1

You can do it in 1 step:

phi = (1+sqrt(5))/2

next = round(current*phi)

(Where round is a function that returns the closest integer; basically equivalent to floor(x+0.5))

For example, if your current number is 13: 13 * phi = 21.034441853748632, which rounds to 21.

12Me21
  • 992
  • 10
  • 22