输入大数字时命令终止

时间:2014-06-07 17:31:44

标签: c primes sieve-of-eratosthenes

我怎么得到一条消息"命令终止"当我尝试输入大量(约1000万)?程序显示数字是否为素数。

见下面的代码:

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

int main ( int argc, char *argv[] )
{
   unsigned long long number;
   bool prime ( unsigned long long );

   printf ("Enter a positive integer greater than 1: ");
   scanf ("%llu", &number );

   prime( number ) ?
      printf ( "%llu is a prime.\n", number ):
      printf ( "%llu is not a prime.\n", number);

   return EXIT_SUCCESS;
}

bool prime ( unsigned long long number )
{
   unsigned long long i, j;
   bool isPrime[number + 1];

   for ( i = 2; i <= number; i++ )
      isPrime[i] = true;

   for ( i = 2; i <= number - 1; i++ )
      for ( j = 1; i*j <= number; j++ )
         isPrime[i*j] = false;

   return isPrime[number];
}

1 个答案:

答案 0 :(得分:3)

问题是您尝试在堆栈上创建一个大于可用内存的数组isPrime。您应该使用

在堆上创建它
bool *isPrime;
isPrime = malloc((number + 1) * sizeof *isPrime);

显然只执行一次,而不是每次调用函数prime

另请注意,如果您只想知道一个数字是否为素数,您只需要搜索一个因子的数字的平方根 - 如果您找到一个因子就完成了。这使得您必须创建的数组大小更易于管理 - 但它确实涉及对算法的一些更改。

事后补充你在确定什么是素数的逻辑中有一个问题 - 你的内循环以j=1开头,这意味着即使素数也会被标记为非素数。以下是&#34;略有改进&#34;代码 - 尽管你还可以做得更好:

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

int main ( int argc, char *argv[] )
{
   unsigned long long number;
   bool prime ( unsigned long long );

   printf ("Enter a positive integer greater than 1: ");
   scanf ("%llu", &number );

   prime( number ) ?
      printf ( "%llu is a prime.\n", number ):
      printf ( "%llu is not a prime.\n", number);

   return EXIT_SUCCESS;
}

bool prime ( unsigned long long number )
{
   unsigned long long i, j, sq;
   bool *isPrime;
   sq = ceil(sqrt(number));
   isPrime = malloc((sq + 1)*sizeof *isPrime);

   // generate primes up to the square root of the number
   for ( i = 2; i <= sq; i++ )
      isPrime[i] = true;

   for ( i = 2; i < sq; i++ ) {
      // only need to mark multiples if this is a prime:
      if(isPrime[i]) {
        // start this loop at 2, not 1!
        for ( j = 2; i*j <= sq; j++ ) {
          isPrime[i*j] = false;
        }
      }
    }

   for ( i = 1; i < sq; i++)
   {
    if (isPrime[i] && number%i==0) return false;
   }

   return true;
}

基本测试:

gcc -Wall不会产生任何错误/警告

104729是一个素数(它是);代码不会因10000001(不是素数)的输入而崩溃。