最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - recursive functions - why not an infinite loop? - Stack Overflow

programmeradmin8浏览0评论

So this is apparently a valid bit of code, but I can't figure out how the second call to power can ever be pleted if the exponent argument is anything besides 0.

function power(base, exponent) {
  if (exponent == 0)
    return 1;
  else
    return base * power(base, exponent - 1);
}

From: .jpg

So this is apparently a valid bit of code, but I can't figure out how the second call to power can ever be pleted if the exponent argument is anything besides 0.

function power(base, exponent) {
  if (exponent == 0)
    return 1;
  else
    return base * power(base, exponent - 1);
}

From: https://i.sstatic/Jin6c.jpg

Share Improve this question edited Nov 15, 2013 at 2:35 Jonathan Lonowski 124k35 gold badges202 silver badges202 bronze badges asked Nov 15, 2013 at 2:11 max pleanermax pleaner 26.8k9 gold badges71 silver badges128 bronze badges 3
  • 4 Please include valid code in the question itself, and for the love of all that you hold holy, don't use a screenshot of your code. – Matt Ball Commented Nov 15, 2013 at 2:14
  • 1 Note to editors: An edit of the question is not the right way to suggest a revised snippet. Post it as part of an answer. – Jonathan Lonowski Commented Nov 15, 2013 at 2:36
  • 1 Well, it is an infinite loop (or better: a stack overflow) when you call it with anything else but a positive integer for the exponent. – Bergi Commented Nov 15, 2013 at 4:02
Add a ment  | 

4 Answers 4

Reset to default 8

Because the second call will keep calling with smaller numbers in exponent, until it reaches 0, and then return 1, and roll back aggregating the result ...

I think you'll have to do some reading on recursion :)

Here's a simple case of how it'll look:

power(2,2) 
 power(2,1) 
    power(2,0) 
       return 1 
    return 2*1 = 2 
 return 2*2 = 4 

Taken and modified from this page.

Try this page for an animated view of the recursion (didn't work for me, it's an old page, needs java, and I don't have it installed on my machine ...)


Edit:
It was bothering me I couldn't find any simple example of this, so here's a quick console program that might help you visualize how this is working :

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SO_Console
{
    class Program
    {
        static void Main(string[] args)
        {
            int base_value = 0;
            int exponent = 0;
            string[] parts = new string[2];
            int result = 0;
            Console.Out.WriteLine("Please enter the Power to calculate in this format: x^y "
            + Environment.NewLine + "(where x is the base (int) and y is the exponent (int)."
            + Environment.NewLine);

            var temp = Console.ReadLine();
            if (!string.IsNullOrWhiteSpace(temp))
            {

                parts = temp.Split('^');
                if (parts.Length != 2)
                InvalidInput();
            }
            else
            InvalidInput();


            if (Int32.TryParse(parts[0], out base_value) && Int32.TryParse(parts[1], out exponent))
            result = Power(base_value, exponent, "");
            else
            InvalidInput();

            Console.Out.WriteLine(Environment.NewLine + "Final result = {0}", result);


            Console.Out.WriteLine(Environment.NewLine + "Hit any key to quit.");
            Console.Read();

        }

        /// <summary>
        /// Recursive call to calculate Power x^y
        /// </summary>
        /// <param name="base_value">The base</param>
        /// <param name="exponent">The exponent</param>
        /// <param name="padding">Padding, for output.</param>
        /// <returns></returns>
        private static int Power(int base_value, int exponent, string padding)
        {
            Console.Out.WriteLine(string.Format("{2}Power called with: {0}^{1}", base_value, exponent, padding));
            Thread.Sleep(750);

            if (exponent == 0)
            {
                Console.Out.WriteLine("{0}{1}Base case reached, returning 1.{0}", Environment.NewLine ,padding);
                return 1;
            }
            else
            {
                var return_value = base_value * Power(base_value, exponent - 1, padding + "  ");
                Console.Out.WriteLine("{0}Going back in the recursion, returning {1}.", padding, return_value);
                Thread.Sleep(750);
                return return_value;
            }
        }

        /// <summary>
        /// Inform user about bad input and quit.
        /// </summary>
        private static void InvalidInput()
        {
            Console.Out.WriteLine("Invalid input.");
            return;
        }
    }
}

You can just paste and run it, and your results will look something along:

Edit 2:
I've written an article about this, explaining in details what happens why where. You're wele to have a look at it here : simple power recursion, console application.

Recursion only terminates when you have edge case. In the case of exponentiation the edge case is:

n0 = 1

It reads as "any number raised to the power of 0 is 1".

The general case of exponentiation is:

nx = n × nx - 1

In a mathematical language like Haskell exponentiation would be defined as follows:

n ^ 0 = 1
n ^ x = n * n ^ (x - 1)

Interestingly if you give this function a negative integer then the edge condition will never execute and it would run into an infinite loop eventually terminating in a stack overflow.

However since we only use this function with whole numbers (0 and positive integers) you will never run into an infinite loop.

Nevertheless if you use a big enough exponent you will still run into a stack overflow because puters only have so much space to store intermediate results.

In most JavaScript browsers you can calculate 2 ^ 2 ^ 14. However if you try to calculate 2 ^ 2 ^ 15 then you get a stack overflow: http://jsfiddle/9chrJ/

Observe that xn = x × xn-1 and x0 = 1. This is why the code is correct.

Just try an example. Here's 2 to the power of 3

power(2,3) = 2 * (power(2,2) = 2 * (power(2,1) = 2 * (power(2,0) = 1)))

So:

power(2,3) = 2 * (2 * (2 * 1)))
发布评论

评论列表(0)

  1. 暂无评论