简体   繁体   中英

C programming - Checking prime number

I am trying to check whether a given number is prime but I've run into an issue. This is the code:

#include <stdio.h>
#include <math.h>
#include <stdbool.h>

bool isPrime(int input)
{
    for (int i = sqrt(input); i >= 2; i--)
    {
        if (input % i == 0)
        {
            return false;
        }
    return true; 
    }
    
}

int main()
{
    int input;
    scanf("%d", &input);
    
    if (isPrime(input))
    {
        printf("Is prime number");
    } else
    {
        printf("Is not prime number");
    }
    
    return 0;
}

In the code block of my isPrime function, if I put return true; in the for loop like above, this will be wrong in some cases (for example, when input is 10, it will declare that 10 is a prime number). But if I put return true; outside the for loop, it works fine. So what is the difference?

The function returns true if the first divisor in the for loop does not divide the target number.

because this return statement

    return true; 

is inside the for loop.

bool isPrime(int input)
{
    for (int i = sqrt(input); i >= 2; i--)
    {
        if (input % i == 0)
        {
            return false;
        }
    return true; 
    }
    
} 

Moreover the function has undefined behavior if it is called for example for prime numbers 2 or 3 or if a non-positive number is passed to the function.

Placing the return statement

return true; 

outside the loop does not make your function correct.

Pay attention to that there is no sense to check even numbers except the number 2 whether they are prime or not prime.

The function can be written the following way

bool isPrime( unsigned long long n )
{
    bool prime = n % 2 == 0 ? n == 2 : n != 1;

    for ( unsigned long long int i = 3; prime && i <= n / i; i += 2 )
    {
        prime = n % i != 0;
    }

    return prime;  
} 

The function can be called like

unsigned int input;
scanf("%u", &input);

if (isPrime(input))
{
    printf("Is prime number");
} else
{
    printf("Is not prime number");
}

Let's walk through your loop:

for (int i = sqrt(input); i >= 2; i--)
{

If the input is 10 , then i starts out as 3 (remember that when assigning a floating-point value to an int , the fractional portion is discarded). 3 is greater than or equal to 2 , so the loop body executes.

    if (input % i == 0)
    {

The remainder of 10 divided by 3 is not zero, so we do not enter the body of the if statement.

        return false;
    }
return true; 
}

And then we immediately return true .

Because of this, no matter what input you provide, your loop will only iterate 1 time. If input is evenly divisible by the integer value of its square root (such as 9 , 16 , or 25 ), then the body of the if statement is executed and it returns false , otherwise it unconditionally returns true .

For your function to work properly, you must move the return true; statement outside the body of the loop - you should only return true when you've exhausted all values of i between sqrt(input) and 2 .

When you put return true; inside of the loop, that statement will be executed whenever the preceding if condition is false. You only want to return true once you've completed your for loop and have found no divisors. That's why the return statement needs to be outside the loop.

This happens because your for loop isn't over with the complete traverse of i, but the return true statement tells the code to execute it the very first time your if condition goes false, and then exit the loop. So, imagine I give you 10 chocolate bars and tell you to take a bite from each, and only collect the dark ones. You take a bite on the first, it's sweet, you put it away. You take a bite on the second and it's dark. You collect it and you tell me you are done, although you actually aren't (You didn't check the rest of the chocolate bars to see if there are more dark ones there or not). That's what you are doing in your code. Hope the example is clear and helpful :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM