1

I have seen similar questions(but in C) -- Calculating Fibonacci Numbers Recursively in C about my issue.

I am a bit stuck on how to keep on printing fibonacci numbers until it reaches about 40,000, in C# in my console application, How can I achieve this?

E.G, I want the application to do this:

0
1
1
2
3
5
8

and so on.

Thanks. I'd hate to say this, but I had a brainwave, and solved it!

Here is what I did:

static void Main(string[] args)
{
    int num1 = 0;
    int num2 = 1;
    int sum = 1;
    while (num1 <= 15000)
    {
        sum = num1 + num2;
        num1 = num2;
        num2 = sum;
       Console.WriteLine(num2);
    }
    Console.ReadLine();
}
Community
  • 1
  • 1
H Bellamy
  • 22,405
  • 23
  • 76
  • 114
  • 9
    Eventually you'd run out of stack space if you were to do this recursively, which will happen well before forever ends. – Mark Elliot Nov 30 '11 at 21:45
  • 6
    If it's recursively, you'll end up with a stack overflow sooner or later. – Nasreddine Nov 30 '11 at 21:45
  • 3
    What have you done so far? What specifically are you having troubles with? Show us your code. Oftentimes people want others to do their homework for them so you need to show us you are trying before people will help. – Matt Cofer Nov 30 '11 at 21:45
  • Are you asking for help converting C to C# in the above example? – Baub Nov 30 '11 at 21:46
  • You need some sort of exit check in your recursion function to check for your 40k condition. – Michael Dorgan Nov 30 '11 at 21:47
  • You can unwrap any recursive algorithm into an iterative one, using a while loop and a state variable. – Polynomial Nov 30 '11 at 21:48
  • Sorry, I have updated it with a reference to what I have done so far. – H Bellamy Nov 30 '11 at 21:49
  • 1
    @MattCofer I'm not doing homework. – H Bellamy Nov 30 '11 at 21:50
  • 1
    It sure would be nice if C# could do tail recursion... – N_A Nov 30 '11 at 21:51
  • No idea why would you run this forever. I'm no C# expert but I heard C# has some functional programming features. Maybe if you want an infinite sequence you could implement some lazy sequence or something? – Matjaz Muhic Nov 30 '11 at 21:51
  • The algorithm for recursive Fibonacci is in the other question. You're asking us to do your own work for you, if this is indeed not homework, which I find hard to believe. –  Nov 30 '11 at 21:56
  • @Inuyasha I can guarentee 100% that this isn't homework. And I have solved it. – H Bellamy Nov 30 '11 at 21:57
  • 1
    What you edited in is not recursive. – CodesInChaos Nov 30 '11 at 21:59
  • 1
    @mydogisbox: Some versions of the jitter will do tail recursion. However, since fib recurses twice in a typical recursive implementation it is not trivial to turn it into a tail-recursive form. Also note that even if you could transform it into a tail recursive form, the naive recursive fib is still exponential in time. If you want a recursive solution, best to use a memoizer; better still is to use an iterative solution or compute the numbers directly by using the Golden Ratio. – Eric Lippert Nov 30 '11 at 22:47
  • As @EricLippert mentiones, use the closed form solution http://stackoverflow.com/a/8334397/8384 – McKay Nov 30 '11 at 23:17
  • @HBellamy, well, that convinced me. –  Dec 01 '11 at 01:12
  • @EricLippert http://stackoverflow.com/a/8333602/901059 – N_A Dec 01 '11 at 14:27

7 Answers7

6

Just for fun, thought I'd throw in a fun way to do this with LINQ extension methods and a generator (infinite sequence):

// A utility class that holds math utility functions.
public static class MathUtility
{
    // This method returns the fibonacci sequence which is an 
    // infinite sequence of numbers where each result is the
    // sum of the previous two results.
    public static IEnumerable<int> GetFibonacciSequence()
    {
        int first = 0;
        int second = 1;

        // first and second result are always 1.
        yield return first;
        yield return second;

        // this enumerable sequence is bounded by the caller.
        while(true)
        {
            int current = first + second;
            yield return current;

            // wind up for next number if we're requesting one
            first = second;
            second = current;
        }
    }
}

This generates an infinite (theoretically) sequence (it will eventually overflow if you let it go past range of int).

You can then call:

foreach(var num in MathUtility.GetFibonacciSequence().TakeWhile(num => num <= 40000))
{
    Console.WriteLine(num);
}

In this way, you have your presentation (the output) separate from the data generation.

James Michael Hare
  • 37,767
  • 9
  • 73
  • 83
3

How about something that has a loop in it? Like:

    static void main() 
    {
        int num1 = 0;
        int num2 = 1;
        int sum = 1;
        Console.WriteLine(num1);
        while (sum < 40000)
        {
           sum = num1 + num2;
           num1 = num2;
           num2 = sum;    
           Console.WriteLine(num2);
        }
    }   
Austin Salonen
  • 49,173
  • 15
  • 109
  • 139
piebie
  • 2,652
  • 21
  • 30
  • You can also do this with a for loop with multiple variables: for(int first=0,second=1,current=0;first<100;current=first+second,first=second,second=current) { Console.WriteLine(first); } – What Would Be Cool Feb 09 '13 at 22:28
2
static int Fibonacci(int n)
{
    if(n <= 1) return n;
    else return Fibonacci(n - 1) + Fibonacci(n - 2);
}


static void PrintAllFibonacci()
{
    int n = 0;
    while(true)
        Console.WriteLine(Fibonacci(n++));
}

EDIT:

a different approach using a stack

static ulong Fibonacci(int n, IList<ulong> stack)
{
    ulong fibonacci;

    if (n <= 1)
    {
        fibonacci = (ulong)n;
    }
    else
    {
        ulong n1, n2;
        if (n < stack.Count)
            n1 = stack[n - 1];
        else
            n1 = Fibonacci(n - 1, stack);
        if (n - 1 < stack.Count)
            n2 = stack[n - 2];
        else
            n2 = Fibonacci(n - 2, stack);

        fibonacci = n1 + n2;
    }

    if (n >= stack.Count)
        stack.Add(fibonacci);

    return fibonacci;
}


static void PrintAllFibonacci()
{
    var stack = new List<ulong>();
    var n = 0;
    while(n < 50)
        Console.WriteLine(n + ") " + Fibonacci(n++, stack));
}
esskar
  • 10,638
  • 3
  • 36
  • 57
1

You can't do that recursively - remember, that each method call uses you stack. Google about, huh, stack overflow :)

You'll need to find iterating version of the algorithm, it's everywhere on the internet. And, of course, while fib numbers are quite quickly running up, it's impossible to output them forever.

Piotr Zierhoffer
  • 5,005
  • 1
  • 38
  • 59
  • 1
    I doubt you'd hit a stack overflow with a 40k limit on the size of the number. I wouldn't even be surprised if you'd hit the maximal value double can represent before running out of stack. Using BigInteger you probably can get a stack overflow, but it will be far beyond the OP's limit. And some versions of the .net jitter support tail call recursion which(assuming a recursive implementation that allows tail call recursion) makes this O(1) in stack space. – CodesInChaos Nov 30 '11 at 22:21
  • Oh, I didn't know about tail call recursion in .net, interesting! – Piotr Zierhoffer Nov 30 '11 at 22:27
  • Since this form of tail recursion isn't guaranteed to occur, you can't rely on it, and thus it's mostly useless. So for reliable tail calls you need to use the tailcall IL instruction, but the C# compiler doesn't do that. – CodesInChaos Dec 01 '11 at 13:35
1

Use the Closed form solution

    public static long ClosedFormFibonacci(int i)
    {
        const double phi = 1.61803398874989; // or use your own or calculate it
        const double sqrt5 = 2.23606798; // same as above
        return (long)Math.Round(Math.Pow(phi, i) / sqrt5);
    }

It looks like it overflows a long at about the 92nd Fibonacci number

McKay
  • 12,334
  • 7
  • 53
  • 76
0

C# doesn't easily support tail recursion so doing a simple recursion algorithm will cause a stack overflow with large enough numbers. For this problem it would be simplest to use a loop instead of recursion. If you're really stuck on recursion, here is a blog post that investigates both faking recursion and converting C# generated IL code to use tail recursion.

N_A
  • 19,799
  • 4
  • 52
  • 98
0

There are 2 major mistakes in your program:

  1. Multiple use of main()
  2. fibonacci_recursive is not created, though it is declared at the start of program.
Bebu
  • 65
  • 3
  • 14