0

I have to write a program that returns the square root of any number that is inputted. My method runs fine for any number that has a perfect square (like 25 or 100) but if I use any number that doesn't (3 or 10) I get a stack overflow error. I was hoping some one could tell me what I did wrong and how I could fix it.

   public boolean sqrRootRecursive(int number, double approx, double tol)
{

    if( (Math.abs((Math.pow(approx,2) - number))<= tol))
    {
       System.out.println("The root is " +approx);
    }else if (Math.abs((Math.pow(approx,2)-number))>tol)
    {
        sqrRootRecursive(number, ((Math.pow(approx,2)+number)/(2*approx)), tol); 
    }


   return true; 

Thanks for the help!

Joe Lucas
  • 21
  • 2
  • 2
    What are approx and tol? – yitzih Mar 02 '15 at 20:38
  • your second `if` is not needed : if `(Math.abs((Math.pow(approx,2) - number))<= tol))` is false then surely `Math.abs((Math.pow(approx,2)-number))>tol` – Tunaki Mar 02 '15 at 20:38
  • I don't remember how this algorithm works well enough to spot the issue, but I suggest you add a debug line before the recursion step so that you can watch the recursion and try to find your bug. – nvioli Mar 02 '15 at 20:42
  • It is the same problem as http://stackoverflow.com/questions/28781485/newton-raphson-iteration-trapped-in-infinite-loop/28782237#28782237 : it should be `(Math.abs((Math.pow(approx,2) - number))<= tol*number)` – francis Mar 02 '15 at 20:48
  • And if @Soma Turi is in your classroom... Tell him to spot his [question](http://stackoverflow.com/questions/28781485/newton-raphson-iteration-trapped-in-infinite-loop/28782237#28782237) : he thought that changing `float` to `double` solved him problem, but it is not the case... – francis Mar 02 '15 at 21:13

1 Answers1

2

It is the same problem as Newton Raphson iteration trapped in infinite loop and i am giving pretty much the same answer.

It should be (Math.abs((Math.pow(approx,2) - number))<= tol*number)

  • It the number is very large, Math.abs((Math.pow(approx,2) - number)) will hardly become lower than tol due to the precision of floating point computation. It may work for some numbers and fail for others, which corresponds to the symptoms described in the question. The right test is <tol*number.
  • If number is very small, Math.abs((Math.pow(approx,2) - number)) will become lower than tol before getting close to sqrt(number). Once again, using <tol*number will solve this problem.

By using (Math.abs((Math.pow(approx,2) - number))<= tol*number), the right side and the left side of the test have compatible units, since a tolerance is dimensionless.

If it does not solve the stack overflow, increase tol or add a counter and a max number of recursive call.

Community
  • 1
  • 1
francis
  • 9,525
  • 2
  • 25
  • 41