C程序接受整数,如果它是Prime或Not Prime

时间:2018-11-01 16:10:37

标签: c integer primes long-integer

我有完全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
--------------------

4 个答案:

答案 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;
}
相关问题