0

I'm trying to calculate the square root of the number 12345. I'm new to programming, and need help with the bottom so I don't receive the exeption "Stack overflow".

public static decimal Sqrt(int number, decimal root)
{
    return Sqrt(number, root - ((root * root) - number) / (2 * root));
}

static void Main(string[] args)
{

    decimal root = Sqrt(12345, 10M);

    Console.WriteLine(root);

}
1
  • 4
    A recursive function like Sqrt needs halting criteria. When the halting criteria are true, it should just return what it has instead of continuing with the recursion. I believe for this algorithm you halt when the newly computed value is within some tolerance of the last computed value. You will have to decide what the tolerance is and add a check to the Sqrt function. Commented Jun 12, 2020 at 19:09

1 Answer 1

2

Wikipedia:

The most-common cause of stack overflow is excessively deep or infinite recursion, in which a function calls itself so many times that the space needed to store the variables and information associated with each call is more than can fit on the stack.

An example of infinite recursion in C.

int foo()
{

    return foo();

}

The function foo, when it is invoked, continues to invoke itself, allocating additional space on the stack each time, until the stack overflows resulting in a segmentation fault. However, some compilers implement tail-call optimization, allowing infinite recursion of a specific sort—tail recursion—to occur without stack overflow. This works because tail-recursion calls do not take up additional stack space.

You missed a check. Your code is infinite recursion, since there is no way to escape from recursion.

The line

return Sqrt(number, root - ((root * root) - number) / (2 * root));

will result in another call for Sqrt method, and it will result in another call for Sqrt method, which will result in .... SO when it stops and return proper result?!

Anyway, if you add a single if statement it will work correctly.

public static decimal Sqrt(int number, decimal root)
{
    if (Math.Abs(root * root - number) <= 0.00000000001M)
        return root;

    return Sqrt(number, root - ((root * root) - number) / (2 * root));
}

// Usage:
static void Main(string[] args)
{
    Console.WriteLine(Sqrt(4, someDecimal));
}

If you use

if (root * root == number)

instead of

if (Math.Abs(root * root - number) <= 0.00000000001M)

, your code will only support perfect squares.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.