How to avoid dividing by zero?

Hey guys so I'm starting to teach myself c++ using "Beginning C++ Through Game Programming, Third Edition" since my computer science program only starts up in the winter and I'd like to have some knowledge beforehand. I started a few days ago and I made it to the end of chapter 2 where they ask you to create a program in which you can pick a random number and have the computer guess it for you. I figured it out but my program makes it so that on occasion when the computer is narrowing down the possible numbers it will divide by zero in one of my equations. So here's the program:

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
#include <iostream>
#include <conio.h>
#include <string>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
	srand(static_cast<unsigned int>(time(0)));
	
	int guessHigh = 100;
	int guessLow = 1;
	int playerNumber;
	string answer;

	cout << "Pick any number from 1 to 100\n";
	cout << "Type 'lower' if your number is lower or 'higher' if it's higher."; 
	cout <<"\nWhen the computer has successfully guessed your number type 'yes'.";
	cout << "\nPress any key to continue\n";
	_getch();
	
	do
	{
		int guess = rand() % (guessHigh - guessLow) + guessLow;
		cout << "\nIs your number: " << guess << "?\n";
		cin >> answer;

		if (answer == "higher")
		{
			guessLow = guess + 1;
		}
		else if (answer == "lower")
		{
			guessHigh = guess - 1;
		}

		else if (answer == "yes")
		{
			cout << "\nI did it!";
		}
		
		else
		{
			cout << "\nStop cheating";
		}
		
	}

	while (answer != "yes");

	_getch();

	return 0;

}


I didn't make any notes because the program is just for learning purposes so I hope that everything is clear enough for you guys to understand (the program is pretty simple so I don't think it should be a problem).

The part that creates the divide by zero error is

int guess = rand() % (guessHigh - guessLow) + guessLow;

This is due to the fact that if your number is let's say 56 and it picks 55 and 57 then the equation will look like :

int guess = rand() % ( 56 - 56) + 56;

This could obviously be remedied by removing the +1 and -1 on lines 32 and 36 however this makes it so that the computer can guess the same number more than once.

I have very limited knowledge of c++ right now so I may not understand all of your explanations but I look forward to learning. Thanks.

Also, if you guys have any suggestions for me or see any bad habits in my work so far please let me know so that I can make the necessary changes.
Last edited on
How to avoid dividing by zero?
Check that the divisor isn't zero.
Yep, that's it.
If guessHigh == guessLow then there is only one answer left to guess and it must be the right answer. I would add a condition before hand (at the top, inside of the do-while loop) that says
1
2
if( guessHigh == guessLow )
	cout << "Hey, you can't change your number on me!\n";
Last edited on
Instead of trying to generate random numbers, calculate the new guess as rougly halfway between the new max and min guesses--that way, you won't ever divide by zero.

The first guess should always be 50... that eliminates roughly half of all possible answers.

If that is too high:
1) make the new max one less than the computer's guess (in this case, new max = 49).
2) add the min and max, then divide by 2 to get the new guess. In this case, 25 would be the new guess ((49+1)/2).

If that is too low:
1) make the new min one more than the last guess (would be 51 in this example).
2) do the following math to get the new guess: (max+min+1)/2. In this case, the computer would guess 76--(51+100+1)/2=76. **Note: the one is added because of rounding issues with integers.

Rinse and repeat the calulations until you get the correct answer... should NEVER take more than 7 guesses. :) If you would like, I can post code....

edit: grammar.
Last edited on
Cuddlebuddie928 wrote:
Instead of trying to generate random numbers, calculate the new guess as rougly halfway between the new max and min guesses...
Yea, but then the program doesn't act like a person. I believe the randomness is a (crude) simulation of human behavior. I mean, how many of your friends would implement that O(n) = log2(n) time algorithm to simplify a game like this?
@helios
...thanks...I knew someone would say it.

@Mathhead200
I tried to do something like that a little while ago, guess i must've messed it up (still learning). Maybe I'll make it display the proper value if they equal each other and display the "victory message".

@Cuddlebuddie928
Yeah I thought about doing it like that before but as Mathhead200 pointed out the randomness was something that I wanted to have in the program. It makes it a bit less mathematical/systematic and a bit more "chance based", as if you played it with a human opponent. Thanks for the suggestion though and posting code won't be necessary but I appreciate it.

Thanks guys for your answers
Last edited on
PFratt wrote:
I tried to do something like that a little while ago, guess i must've messed it up (still learning). Maybe I'll make it display the proper value if they equal each other and display the "victory message".
Even if it isn't quite working, post it away, explain the problem(s), and someone (at least me) will take a look.
I'll try to get it to work tomorrow but depending on my schedule it might have to wait a little while. I'll definitely post in here if I need help though, thanks.

edit: Ok so I got it to work thanks a lot Mathhead

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
do
	{
		
		if (guessLow == guessHigh)
		{
			cout << "\nIs your number: " << guessLow << "?\n";
			cin >> answer;
			
			if (answer == "yes") 
			{
				cout << "\nI did it!";
			}
			else
			{
				cout << "\nStop cheating\n";
			}
		}

		else
		{
			int guess = rand() % (guessHigh - guessLow) + guessLow;
			cout << "\nIs your number: " << guess << "?\n";
			cin >> answer;

			if (answer == "higher")
			{
				guessLow = guess + 1;
			}
			else if (answer == "lower")
			{
				guessHigh = guess - 1;
			}

			else if (answer == "yes")
			{
				cout << "\nI did it!";
			}
		
			else
			{
				cout << "\nStop cheating\n";
			}
		}
		
	}

	while (answer != "yes");


There's probably a better way to have written that but since this is just a learning exercise I won't stress about it.
Last edited on
Just for kicks:
Based on PFratt's guessing program,
Random Guess 102
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
60
#include <iostream>
#include <sstream>
#include <string>
#include <cstdlib>
#include <ctime>

using namespace std;

int main(int argc, char *argv[]) {
	int min = 1, max = 100;
	{
		stringstream translator;
		if( argc > 2 ) {
			translator << argv[1] << ' ' << argv[2];
			translator >> min >> max;
		} else if( argc > 1 ) {
			translator << argv[1];
			translator >> max;
		}
		if( max < min ) {
			cerr << max << " < " << min << endl;
			return 1;
		}
	}
	
	string response;
	cout << "Think of a number between " << min << " and " << max << " (inclusively)...\n"
	     << "(Press enter when you've got it.)" << flush;
	getline(cin, response);
	
	cout << "Okay, ";
	srand(time(NULL));
	for( int tries = 1; min <= max; tries++ ) {
		//note the divisor (max - min + 1) > 0, given min <= max
		int guess = rand() % (max - min + 1) + min;
		cout << "is your number " << guess << "?\n";
		do {
			cout << " (yes|higher|lower) > " << flush;
			getline(cin, response);
			if( response == "yes" ) {
				cout << "Got it. And it only took me " << tries
				     << (tries == 1 ? " try" : " tries") << " too." << endl;
				min = max + 1; //break out of the outer for-loop
			} else if( response == "higher" )
				min = guess + 1;
			else if( response == "lower" )
				max = guess - 1;
			else {
				cerr << "Invalid response\n";
				continue;
			}
			break;
		} while(true);
		response[0] -= 0x20; //capitalize 
		cout << response << ", got it. So then ";
	}
	
	cout << "that was fun, let's play again some time." << endl;
	return 0;
}
Topic archived. No new replies allowed.