是否只需要检查(num / 2 + 1)以确定一个数字是否为素数?

时间:2014-09-16 20:39:23

标签: c++ primes

我已经成功编写了这样一个程序来完成这项任务,但是我和我的朋友目前正在就其中一个值进行辩论。

这是HIS循环功能:

for (int iii = 2; iii < (num / 2 + 1); iii++)
{
    if (num%iii == 0)
    {
        return false;
    }
}
return true;

我向他提出的问题是,&#34;你为什么需要&#34; 2 + 1&#34;?&#34;他不能只使用他声明的变量&#34; num&#34;?

3 个答案:

答案 0 :(得分:4)

您只需要查看sqrt(num) num/2num >= 4小于或等于n > sqrt(num)。这是因为如果数字num除以num/n < sqrt(num),则num除以n

该声明的证明:

正数x的平方根被定义为x * x == n所拥有的唯一正实数d。现在考虑一下n的除数d > nd。然后是(因为d2是除数)自然数d * d2 == n,使得d2 := n / d。很明显,x * x == n就是这样一个数字。从d * d2 == nd > xd2 < x可以得出结论x。这意味着,如果大于n的数字除以x,则还会有一个小于x的数字,它也会划分日期。总而言之,如果没有数字小于或等于n除以nnum >= 4就是素数。

这意味着函数对于大于或等于2的所有值都是正确的。对于num <= 1,这可以从上面得到。对于true,您的函数将始终返回2 <= num <=3,因为循环永远不会执行。对于true,循环正确返回+1,因为再次,循环永远不会输入。 (从技术上讲,你需要5/2=2 < sqrt(5)来证明5是素数因为{{1}}因为整数除法。)

答案 1 :(得分:0)

一些改进:

  • 您可以使用2进行测试,并避免使用所有其他偶数。
  • 你只需要测试直到sqrt(数字),已在其他答案中解释过。

代码:

#include <cmath>

bool is_prime(unsigned long number) {
    if (number % 2 == 0 && number != 2)
        return false;
    unsigned long sqrt_number = static_cast<unsigned long>(std::sqrt(number));
    for (unsigned long i = 3; i <= sqrt_number; i += 2) {
        if (number % i == 0)
            return false;
    }
    return true;
}

答案 2 :(得分:0)

您的代码正在实施&#34;素数&#34;测试。如果数字不能被除自身和1以外的任何整数整除,则数字为素数。

此问题空间有一些众所周知的参数/因素。

a)任何给定数量N除以产生整数值的最大值是N / 2。 b)如果N可以被偶数整除,它也可以被2整除,即它必须是偶数。

is_prime(N) {
    if is_even(N) {
       // if N is 2, it's prime, otherwise
       // any even number is divisible by
       // 2 and thus not prime.
       return (N == 2)
    }

    md = max_divisor(N)

    // we've eliminated even numbers, so we need only
    // test odd numbers.
    // all numbers are divisible by 1, so start at 3.
    for (divisor = 3; divisor <= md; divisor += 2) {
      // determine whether divisor divides into N
      // without remainder indicating non-prime N
      remainder = (N % divisor)
      if (remainder != 0)
        return false
    }
    return true
}

最大除数是一个数字,当它除以N时,将产生2。

max_divisor * 2 = N  ->
max_divisor = N / 2

如此简单:

max_divisor(N) return N / 2

检查偶数怎么样?我们可以通过两种方式之一做到这一点。我们可以模2,但许多人试图优化代码将记住他们的二进制逻辑并意识到他们只需要测试是否设置了最低位(位1)。

0001 = 1 (odd)
0010 = 2 (even)
0011 = 3 (odd)
0100 = 4 (even)
0101 = 5 (odd)
0110 = 6 (even)
0111 = 7 (odd)

非常简单:

is_even(N) (N % 2) == 0
or
is_even(N) (N & 1) == 0   

转换为C:

static inline bool isEven(unsigned int number) {
    return (number & 1) == 0;
}

static inline unsigned int maxDivisor(unsigned int number) {
    return (number / 2);
}

unsigned int isPrime(unsigned int number) {
    if (isEven(number)) {
       // if N is 2, it's prime, otherwise
       // any even number is divisible by
       // 2 and thus not prime.
       // fluffy expanded version
       return (number == 2) ? true : false;
       // compact version
       // return (number == 2);
    }

    const unsigned int md = maxDivisor(number);

    // we've eliminated even numbers, so we need only
    // test odd numbers.
    // all numbers are divisible by 1, so start at 3.
    for (unsigned int divisor = 3; divisor <= md; divisor += 2) {
      // determine whether divisor divides into number
      // without remainder indicating non-prime number
      const unsigned int remainder = (number % divisor);
      if (remainder != 0)
        return false;
      // compact version:
      //if (number % divisor)
      //  return false;
    }
    return true;
}

你的朋友&#34;(N / 2)+ 1&#34;是因为他使用的是小于而不是&lt; =,你可以删除&#34; + 1&#34;在他的代码中写下以下内容:

for (int iii = 2; iii <= (num / 2); iii++)