我有完全C语言的程序代码,并且效果很好,但是结果不正确。我在下面的代码源。谁能帮助我发生什么事或我错过了什么?欢迎大家更正此英语或代码。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main (int argc, char *argv[])
{
int n;
int result;
if (argc < 2)
{
printf ("Usage: p4 <number>\n");
}
n = atoi (argv[1]);
if (n < 2)
{
printf ("input number should be > 1\n");
}
result = isprime (n);
if (result == 1)
printf ("%d is prime\n", n);
else
printf ("%d is not prime\n", n);
return 0;
}
我制作了一个称为isprime的函数,如果传递给它的整数为质数,则返回true(即1),如果它是复合数(即非素数),则返回false(即0)。 2或任何奇数直到数字本身的平方根,否则为质数。对它进行编程后,输出结果不是我期望的参考值。
已编译:
p4: -Output of program (p4) is not correct for input '9872349871': ------ Yours: ------ 1282415279 is not prime ---- Reference: ---- 9872349871 is not prime --------------------
答案 0 :(得分:2)
问题在于输入值9872349871太大,无法容纳32位整数。
您需要重写程序以使用long long
而不是int
(这应该为您提供64位整数),并且为了解析命令行参数,您需要切换{{ 1}}到atoi
。
注意事项:如果您的atoll
实现(问题中未显示)通过乘以一个值({ {1}}),该平方值甚至可能溢出64位整数的限制。因此,您可能需要使用isprime
修改该功能,例如 。
答案 1 :(得分:1)
问题是您的测试用例'9872349871'太大,无法容纳在int中(在您的实现/机器上)。
一个简单的解决方法是(将所有内容更改为较长的使用strtol来捕获超出范围的问题):
编辑:根据您的编译器,long可能不足以容纳示例输入。确实可以保证long long可以是8个字节,但是只能在至少支持C99的编译器上工作。
真正重要的部分是检查您的输入值!否则,您的代码不会比以前更安全。
char *end;
long n = strtol(argv[1], &end, 10);
if(errno == ERANGE){
printf("The number you entered is too large!\n");
return -1;
}
完整代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <errno.h>
//OK, so this is a sloppy, inefficient implementation.
/*
int isprime(long n) {
for (long i = 2; i != n; ++i)
if (n%i == 0)
return 0;
return 1;
} */
// A better one:
int isprime(long n) {
if(n <= 3)
return n >= 2;
if(n%2 == 0)
return 0;
for (long i = 3; i <= sqrt(n); i += 2)
if (n%i == 0)
return 0;
return 1;
}
int main (int argc, char *argv[])
{
if (argc < 2)
{
printf ("Usage: p4 <number>\n");
return -1;
}
char *end;
long n = strtol(argv[1], &end, 10);
if(errno == ERANGE){
printf("The number you entered is too large!\n");
return -1;
}
if (n < 2)
{
printf ("input number should be > 1\n");
return -1;
}
int result = isprime(n);
if (result == 1)
printf ("%ld is prime\n", n);
else
printf ("%ld is not prime\n", n);
return 0;
}
答案 2 :(得分:0)
问题在于9872349871的数量非常大-太大而无法容纳int
。当您将其从字符串转换为int
时,它会被截断并得到1282415279。
如果将数字转换为十六进制,这很容易看到...
9872349871是24c701aaf(十六进制)
1282415279是4c701aaf(十六进制)
因此,不要在int
函数内部使用n
,而应在isprime
函数中使用long
long n = strtol(argv[1], &p, 10);
您要进行的编程练习应该已经说明了代码应能够处理的输入范围,因此您可以预见到此类问题。
答案 3 :(得分:-3)
以下code
可以工作:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>
int isprime(long long n) {
for (long long i = 2; i != n; ++i)
if (n%i == 0)
return 0;
return 1;
}
int main (int argc, char *argv[])
{
if (argc < 2)
{
printf ("Usage: p4 <number>\n");
return -1;
}
char* p;
long long n = strtoll(argv[1], &p, 10);
if (n < 2 || *p != '\0')
{
printf ("input wrong\n");
return -1;
}
int result = isprime(n);
if (result == 1)
printf ("%lld is prime\n", n);
else
printf ("%lld is not prime\n", n);
return 0;
}