Prime number check with very strange result

This program I wrote to determine if a number is prime has some very interesting behavior. I have checked dozens and dozens of numbers, all giving the correct output except for the number 999. The program calls this "prime". 997 outputs prime, 1000 outputs composite, and the program works up to but not including one billion.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <cmath>
using namespace std;

int dummy = 0;
int testnumber = 0;
int main ()
{
	cout << "Enter a positive integer: ";
    cin >> testnumber;

  
   for( int i = 2; i < (testnumber); i++ )
   {
       if (testnumber%i==0) 
		   cout << "Composite";

	   else cout << "Prime";
	   break;
	   }
   
   cin >> dummy;
}


The use of the dummy is the only way I know how to let the output be displayed before the program ends itself too fast. I am extremely curious to why this strange behavior is taking place. Thanks in advance,

Hendrix9

Edit: I know I only have to check up to the square root of the number, but I couldn't get sqrt and % to work together, they seemed to want different types. That's why cmath is still in there. If anyone could help with that problem too, that would be awesome.
Last edited on
It's not interesting, just incorrect. It's checking for oddness, not primality. See if you can figure out why.
Your internet harshness does not bother me at all. My guess is the if/else statement in the loop. I wanted to write this on my own rather than cheat and look at someone's code. I cannot figure out why its checking for evenness rather than primeness. If you have constructive advice, great. If you need to vent your anger, go somewhere else.

Hendrix9
It's not anger, he's just trying to push you in the right direction (programmers here don't sugar coat, if you say something wrong you'll hear about it). Try stepping through your code line by line (EVERY line). Write down the values of each variable as they change. If that doesn't help, write down (in english) what you think each line does then post it here. This is an important skill to learn as is closer to the point of this kind of exercise than simply learning the syntax.
Last edited on
Thanks for the reply. If I misinterpreted the first reply I apologize. Where I come from that sort of reply is considered rude.

I think I am in over my head with this program. I have only been coding for a week.

If it is only testing for evenness, perhaps the counter isn't increasing like I expect? I thought I was dividing by larger and larger numbers, and if there is no remainder at a counter number I can conclude the number is composite. If the loop counter makes it all the way to the test number with remainders, it must be prime. Thanks again for the replies,

Hendrix9

Edit: Typo
Last edited on
To see your specific problem, I would suggest formatting the code more "correctly". Line up all indentations uniformly.

Ex, instead of something like
1
2
3
4
if (thing) something();

if (thing)
something_else();

do
1
2
3
4
if (thing)
{
    something();
}
Last edited on
Sorry, it's just my nature to be blunt. I can sometimes come across as rude even to people who have known me for years, but really, I mean no disrespect.

Many newbies tend to underestimate the importance of proper formatting.
No problem at all.

I came up with a working program, but I feel like it could be written a lot better:

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
#include <iostream>
#include <cmath>
using namespace std;

int dummy = 0;
int testnumber = 0;
int x = 0;
int main ()
{
	cout << "Enter a positive integer: ";
    cin >> testnumber;

  
   for( int i = 2; i < (testnumber); i++ )
   {
       if (testnumber%i==0) {
		   cout << "Composite";
		   x = 1;
		   break;
	   }
	   if (testnumber==i)
	       break;
	   
   }
    
   if (x !=1) {
   cout << "Prime";
   
}
   cin >> dummy;
}


I know my indentations suck, and I am going to work on that. Other than that, any suggestions for improvement? Thanks in advance,

Hendrix9

Edit: Didn't use code format.
Last edited on
Line 21 can never evaluate to true.

I'm not a fan of early exits from for loops using break. Consider the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

int main()
{
    int number;
    std::cout << "Enter a postiive integer\n> ";
    std::cin >> number;

    int divisor = 2;
    while (divisor < number && number % divisor != 0)
        ++divisor;

    if (divisor == number)
        std::cout << number << " is prime.\n";
    else
        std::cout << number << " is not prime.\n";
}

The number of iterations can be reduced by testing divisors up to and including the square root of the number:
1
2
3
    int limit = sqrt(double(number));

    for (int i = 2;  i <= limit; i++ )
Thanks for the replies. I do see why line 21 is pointless, since the loop uses less than and not less than/equal to. A handful of questions:

1.) I was trying to use the square root as a limit, but the modulo and square root functions needed different data types. I just learned about casting data types. Is that what you are doing there?

2.) Also, when a number larger than 1 billion is entered the program shuts down. Is this due to the nature of the integer data type?

3.) Is it possible to ask the user if they want to try another number while maintaining the for loop or must I switch to the suggested while loop to achieve this?

Thanks again,

Hendrix9
1.) I was trying to use the square root as a limit, but the modulo and square root functions needed different data types. I just learned about casting data types. Is that what you are doing there?

Prior to C++11, the overloads for sqrt all took floating point types (float, double, long double) as parameters and a cast was necessary to select one of those overloads, however an overload for intregral types was introduced in C++11 and a cast should not be necessary for a compliant library implementation when C++11 is being used.

2.) Also, when a number larger than 1 billion is entered the program shuts down. Is this due to the nature of the integer data type?

Yes. You could effectively double the range just by changing to the type to unsigned int, since there is no reason to be using half the range for negative values.

3.) Is it possible to ask the user if they want to try another number while maintaining the for loop or must I switch to the suggested while loop to achieve this?

It is possible using either a for or while loop. All that is required is enclosing the code in another loop which manages the gathering of input.
Last edited on
Topic archived. No new replies allowed.