1

Below is a simple program which computes sqrt of a number using Bisection. While executing this with a call like sqrtr(4,1,4) in goes into an endless recursion . I am unable to figure out why this is happening. Below is the function :

double sqrtr(double N , double Low ,double High  )
{

     double value = 0.00;

     double mid = (Low + High + 1)/2;

    if(Low == High)
     {
        value =  High;

     }

     else if (N < mid * mid )
     {
        value = sqrtr(N,Low,mid-1) ;


     }
     else if(N >= mid * mid)
     {
         value = sqrtr(N,mid,High) ;

     }

     return value;

}
3
  • 4
    I smell a rounding inconsistency boundary condition. Commented May 20, 2010 at 22:39
  • 1
    docs.sun.com/source/806-3568/ncg_goldberg.html Commented May 20, 2010 at 22:48
  • @Platinum Azure : surprisingly enough, I don't. Credits to jpalecek, who noted that the +1 part was stolen from an integer algorithm. That gives you completely the wrong boundaries, so it no longer matters how you round them. Commented May 21, 2010 at 13:11

4 Answers 4

5

You may have to put a range on your low == high comparison, i.e. high - low < .000001 for six decimal places of precision.

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

1 Comment

Uh, how about N = 143214.4213e22? Now how do you like the test, high-low < 0.000001? See my answer.
4

Apart from having a bad termination condition, how did you get this:

 else if (N < mid * mid )
 {
    value = sqrtr(N,Low,mid-1) ;

How is the mid-1 justified? Didn't you cut-and-paste some code for integer binary search?

2 Comments

Was thinking the same thing myself. That -1 has to go!
Yup. Try sqrtr(0.0001, 0.0, 0.1) for an instant proof.
0

It's rarely a good idea to rely on floating point values equaling one another. It's very easy for them to be off by a slight amount since, unlike integers, they can't represent all values in the range of values that they represent.

So, you'll likely need to do a comparison to a given precision rather than exact equality.

As pointed out in one of the comments above, you should look at the paper "What Every Computer Scientist Should Know About Floating-Point Arithmetic". It's a classic, excellent paper on the nature of floating point numbers.

Comments

0

There are several problems. As noted by jpalecek, it looks as though you've cut-and-pasted a (not very good) binary search routine for an indexed array without understanding how it works. Also, the termination criterion is overly strict.

I suppose this is a learning exercise, because bisection and recursion is a very poor way to solve for sqrt().

The code below works, but it is horribly slow and inaccurate.

#include <iostream>
using namespace std;

double sqrtr(double N , double Low ,double High  )
{
    // Precondition: Low and High, Low <= High, must be non-negative, and must
    // bracket sqrt(N).

     const double sqrt_mef = 1e-8; // Approximate square root of machine efficiency

     double mid = (Low + High)/2; // No +1

    if((High-Low)/(1+mid) < sqrt_mef)
     {
        return mid;
     }

     else if (N < mid * mid )
     {
        return sqrtr(N,Low,mid) ;  // No -1
     }
     else
     {
         return sqrtr(N,mid,High) ;
     }

}

int main()
{   
    double sqrt_2 = sqrtr(2.0, 0, 2.0);
    cout << sqrt_2*sqrt_2  << endl;
    getchar();
}

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.