I want to find if a number is a prime number or not using the square root method. My number is working fine for different numbers when I test it but I know there is a bug that I can not find. Any help will be highly appreciated.
#include <math.h>
int is_prime(int n)
{
int i,root;
if(n == 2){
return 1;
}
if(n % 2 == 0){
return 0;
}
root = sqrt(n);
for(i = 3; i <= root; i = i + 2){
if(n % i == 0){
return 0;
}
}
return 1;
}
int main()
{
int n,m;
while (1){
printf("Please enter a number(enter 0 to exit):");
scanf("%d", &n);
if(n == 0){
break;
}
if(1 == is_prime(n)){
printf("%d is a prime number.\n", n);
}
else{
printf("%d is not a prime number.\n", n);
}
}
return 0;
}
there is a bug that I can not find
Beware the subtleties of floating point math
root = sqrt(n);
can result in a root
that is one less than expected due to imprecision/rounding. Example: Consider sqrt(49)
may return 6.999999999999999... making root = 6
. The loop stops before testing with 7 and returns prime(49)
incorrectly as true.
Instead iterate until the quotient is too large. This becomes true when i
is about the square root of n
.
// for(i = 3; i <= root; i = i + 2){
for(i = 3; i <= n/i; i = i + 2){
Avoid the below as i*i
may overflow for primes near INT_MAX
.
for(i = 3; i*i <= n; i = i + 2){ // Potential overflow
n/i
is often a "freebie" when near n%i
as good compilers emit common efficient code.
Alternatively, round up the square root calculation, if one is compelled to use sqrt()
. With other types like long long n
, this may be insufficient. Best to use integer math for an integer problem.
root = ceil(sqrt(n));
Corner bug :
Code returns true for is_prime(1)
. @Weather Vane Suggest returning in the end:
// return 1;
return n >= 2;
Code dies with is_prime(negative_odd)
as sqrt(negative_odd)
is attempted. Suggest sqrt()
-less solution.
Other problems may exist.
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.