无限循环发生在这里的某个地方?

时间:2014-01-21 16:50:31

标签: c++ loops infinite-loop primes

我正在编写一个程序来估计作为素数的非负整数的百分比。以下代码以某种方式产生无限循环,因为我的输出在我正在使用的在线编译器上说“超时”。但是,我无法弄清楚代码的哪一部分产生了这个问题。它看起来非常简单。

#include <iostream> 

bool isPrime(unsigned long L) { 
    if (L < 3) { 
        return true; 
    } else { 
        unsigned long i = 2;
        while (i < L)
           if (L % i++ == 0)
                return false;
    }
    return true;
}

int main() { 

    unsigned long k = 0;
    unsigned long N = ~k;
    unsigned long count = 0;
    while (k++ < N)  
        if (isPrime(k)) 
            ++count;

    long double percentPrime = count / N;
    std::cout << "Percentage of prime numbers from 0 to " << N << " = " << percentPrime;

    return 0;
} 

4 个答案:

答案 0 :(得分:2)

首先,你的循环不是无限的。它将一直运行到0xFFFFFFFF,这将永远。

它将永远使用的部分原因是您使用的是O(N^2)算法(因此需要0xFFFFFFFF * 0xFFFFFFFF次操作才能完成)。

您应该使用筛子,或者至少优化您的is_prime功能:

bool is_prime(unsigned int i, const std::deque<unsigned int>& previous_primes)
{
    std::size_t j = 0;
    while (previous_primes[j] * previous_primes[j] <= i)
    {
        if (i % previous_primes[j] == 0)
            return false;
        ++j;
    }
    return true;
}

然后你的主要代码就是:

// initialize some known primes
std::deque<unsigned int> primes;
primes.push_back(2);
primes.push_back(3);
primes.push_back(5);
primes.push_back(7);

for (unsigned int i = 9; i <= 0xFFFFFFFF; i += 2)
{
    if (is_prime(i, primes))
    {
        primes.push_back(i);
    }
}

// your percentage of primes would be (mathematically) primes.size() / 0xFFFFFFFF

请注意,由于迭代,这将仍然永远循环遍历从9到0xFFFFFFFF的所有奇数整数。

旁注

实际上,您正在编写一个程序来显示以下简单的证据:

  • 以2开头,因此素数的百分比必须小于.5,因为其他每个数字都可以被2整除。
  • 接下来,3,所以素数的百分比必须小于.33,因为每第3个数字可以被3整除。
  • 下一个5 ...

随着素数越来越大,最大百分比变为1/some infinite prime〜= 0.(当{接近无穷大时,f(x) = 1/x的极限为0)。

所以在这里,数学证明要比你对程序化证明的尝试快得多。

答案 1 :(得分:1)

unsigned long k = 0;
unsigned long N = ~k;

这里N将是0xFFFFFFFF,这是一个非常大的数字,所以循环不是无限长而是长。

答案 2 :(得分:1)

不是无限的,只是非常长。

如果你写了while (k++ <= N)而不是while (k++ < N) ...

,那将是无限的

BTW,1通常不被认为是素数,但是你的代码产生了它。

PS:如果你想粗略估计1...N范围内素数的百分比,那么你可以简单地做以下数学运算:100/log(N),其中log(N)是自然的N的对数。

答案 3 :(得分:1)

它似乎并不是无限的,但由于它很长且耗时,因此超时。

我建议用一些技巧改进你的素性测试:

1 - 您只需要测试数字直到其平方根(sqrt(L))

2 - 你只需要测试奇数的素数(所以你可以开始尝试将数字除以3并将测试增加2,所以你将测试3,5,7,9等等。 。)

干杯