Concise main() body using functions

Hi, for my current programming assignment, i have to make the main body of the program below (which calculates the square root of a integer using the babylonian algorithm) by calling functions. Any ideas? I'm not very familiar with using functions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <cmath>
using namespace std;

int main () 
{
bool more = false; 
int count = 0,n; //intialize integer variables
double error, r, guess, new_guess; //initialize calculated variables
char choice; //for quiting/restarting the program
    do
    { 
        cout<<"This program will compute the square root of a positive integer."<<endl;
        while (more==false)
        {
            cout<<"Please enter a number: "<<endl; 
            cin>>n; 
            if (n>0)//check for positive integer input
            {
                more=true;
            }
            else //check for negative value
            {
                cout<<"You entered a negative value. Try again...."<<endl;
            }
        }
        if (cin.fail()) //checks to make sure input 'n' is an integer
        {
            cout<<"You were supposed to enter an integer. The program will now terminate."<<endl;
            return 1;
        }
        if (sqrt(n)==floor(sqrt(n))) //EXTRA CREDIT: checks for square root input! 
        {
            cout<<"You entered a perfect square! You should know the square root."<<endl;
            return 1;
        }
        guess=(double)n/2; //value of initial 'guess' 
        cout<<"Please enter the desired bound on error: "<<endl; //specify the accuracy to which 
        //which this program calculates the square root
        cin>>error;
        new_guess=guess; 
        do //babylononian algorithm starts here
        { 
            count++; //Keeps track of how many iterations were required, with min. 1 iteration
            r=(double)n/new_guess; 
            new_guess=(double)( new_guess+r)/2; 
        }
        while (new_guess>(error+(( new_guess+(double) n/new_guess) / 2.0)));

            cout<<"The square root of "<<n<<" is: "<<new_guess<<". This took "<<count<<" iterations."<<endl;
            cout<<"If you would like to quit the program, press 'q'. If you would like to countinue, press 'c'."<<endl;
            cin>>choice;
            more=false;
    }while (choice != 'q');

return 0; 
}

Last edited on
Functions are just the next step. You've got some basic flow control going, now you need to learn some basic program organization. That's functions.


A function, as in math, does one conceptual thing for you. You've already used a couple of functions that have been prepared for you.

    sqrt(n)

The code to actually calculate the square root of n is not visible to you, but it exists. You don't have to care how it actually works (and it is interesting indeed), but you can still use it because you #included <cmath>, which tells your program all about it.

You can create your own functions to do the same kind of thing.

For example, you can create a function that asks the user for a value. It might look like this:

    double get_positive_number_from_user( string prompt );

When you call the function, it prints the user prompt and waits for the user to enter a number. You can use it in your main function:

1
2
3
4
5
6
int main()
{
    int n = get_positive_number_from_user( "Please enter a number: " );
    // n is now guaranteed to be a positive integer value
    ...
}

The trick to making that function is to move the parts of your code above into the body of that function. Your new function might look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
double get_positive_number_from_user( string prompt )
{
    double n;

    bool more=false;
    while (more==false)
    {
        cout << prompt << endl;
        cin >> n;

        /* (see comment below for how to handle bad input here) */

        if (n>0)
        {
            more=true;
        }
        else
        {
            cout << "You entered a negative value. Try again...." << endl;
        }
    }

    return n;
}

The way you are handling bad input is not quite right. You should check for it immediately after trying to get the input (before you check the input value... since that value might not have been input!).

Here's how to check and clear it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
double get_positive_number_from_user( string prompt )
{
    double n;

    bool more=false;
    while (more==false)
    {
        cout << prompt << endl;
        cin >> n;

        if (!cin)
        {
            cin.clear();
            cin.ignore( 10000, '\n' );
            cout << "That was not a number. Try again...." << endl;
        }
        else

        if (n>0)
        {
            more=true;
        }
        else
        {
            cout << "You entered a negative value. Try again...." << endl;
        }
    }

    return n;
}

Everything inside a function is it's own little ecosystem. Outside the function, you don't have to care about how things work inside, so long as the function does what it is supposed to do.

This makes main a lot simpler to follow, because you are now using more abstractions (functions) to do stuff:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
    do 
    {
        int n = get_positive_number_from_user( "Please enter a number: " );

        double error = get_positive_number_from_user( "Please enter the desired bound on error: " );

        double root = babylonian_square_root( n, error );

        cout << "The square root of " << n << " is " << root << ".\n";

    } while (ask_to_continue());
}

See where functions come in handy? See which ones I invented to complete the assignment? (That right! You get to invent your own functions to do stuff!)

A couple of final thoughts:

If the program is supposed to calculate the square root of a user-entered number, it shouldn't be giving the user guff about any of the numbers he entered. For example, 297183121 is a perfect square, but no one knows what it's root is off the top of his head. (It's 17239.)

Perfect square or not, just calculate the root. If you want, you can also tell the user that he has entered a perfect square (that is, in addition to telling him the square root).

Also, you don't need to tell the user how many iterations it took to find the square root. (Unless that is in the assignment, which makes things uglier. If it is, let me know and I can suggest ways to track it.)

Hope this helps.
Topic archived. No new replies allowed.