Search code examples
c++mathinclusion

Programming a manual square root function?


For my class I'm programming a square root function using inclusion. No, I may not use any other method...

This is my code so far, with the program nearly working. It works for perfect square roots and some other values (like 11 or 5) but it gets into an infinite loop for others (8, 2).

The reason why this happens is that the upper and lower bounds (b and a) do not change. Ideally, the bounds would be current x and previous x, creating new x. What happens is that new x is currently formed by current x and either a or b, being a constant.

I've tried for so long but I have not yet found a way to 'remember' or find the 'previous x', as every time the while loop repeats, only the current x is available for use. Anyone know how such a problem could be solved?

void inclusion ()
{
    double v ;
    cout << "*** Now solving using Inclusion ***" << endl << "To calculate the square root, enter a positive number: " ;
    cin >> v ;

    while (v<0)
    {
        cout << "Square roots of negative numbers cannot be calculated, please enter a positive number: " ;
        cin >> v ;
    }

    cout << endl ;

    int n = 0;
    while (v >= n*n)
        n++ ;

    double b = n ;
    double a = n-1 ;

    int t = 0 ;
    double x = (a+b)/2 ;

        while ((x * x - v >= 0.1) || (x * x - v <= -0.1))
        {
            t++ ;

            if (x * x < v)
                {
                cout << "Lower Bound: " << x << '\t' << '\t' ;
                cout << "Upper Bound: " << b << '\t' << '\t' ;
                x = (b + x)/2 ;
                cout << "Approximation " << t << ": " << x  << endl ;
                }

            else
                {
                cout << "Lower Bound: " << a << '\t' << '\t' ;
                cout << "Upper Bound: " << x << '\t' << '\t' ;
                x = (a + x)/2 ;
                cout << "Approximation " << t << ": " << x  << endl ;
                }
        }

    cout << endl << "The answer is " << x << ". Iterated " << t << " times." << endl << endl ;
}

Solution

  • I have not yet found a way to 'remember' or find the 'previous x'

    Have a variable previous_x that you previous_x = x at the end of the loop

    But that's not your problem. You are changing x, but not a or b, so you get into an infinitely repeating pattern. You should instead adjust whichever bound brings you tighter in.

    void inclusion ()
    {
        double v ;
        cout << "*** Now solving using Inclusion ***" << endl << "To calculate the square root, enter a positive number: " ;
        cin >> v ;
    
        while (v<0)
        {
            cout << "Square roots of negative numbers cannot be calculated, please enter a positive number: " ;
            cin >> v ;
        }
    
        cout << endl ;
    
        int n = 0;
        while (v >= n*n)
            n++ ;
    
        double b = n ;
        double a = n-1 ;
    
        int t = 0 ;
    
        double x;
        for (x = (a+b)/2; abs(x * x - v) >= 0.1; x = (a+b)/2, ++t)
        {
            if (x * x < v)
            {
                cout << "Lower Bound: " << x << '\t' << '\t' ;
                cout << "Upper Bound: " << b << '\t' << '\t' ;
                a = (b + x)/2 ;
                cout << "Approximation " << t << ": " << x  << endl ;
            }   
            else
            {
                cout << "Lower Bound: " << a << '\t' << '\t' ;
                cout << "Upper Bound: " << x << '\t' << '\t' ;
                b = (a + x)/2 ;
                cout << "Approximation " << t << ": " << x  << endl ;
            }
        }
    
        cout << endl << "The answer is " << x << ". Iterated " << t << " times." << endl << endl ;
    }