为什么迭代每次都由 i+6 完成,为什么这个质数测试函数的条件是 i*i<=n?

why the iteration is done by i+6 every time and why the condition is i*i<=n for this prime testing function?

https://www.geeksforgeeks.org/primality-test-set-1-introduction-and-school-method/

// 一个基于C++程序的优化校核方法 // 如果一个数是素数

#include <bits/stdc++.h> 
using namespace std; 

bool isPrime(int n) 
{ 
    // Corner cases 
    if (n <= 1)  return false; 
    if (n <= 3)  return true; 

    // This is checked so that we can skip  
    // middle five numbers in below loop 
    if (n%2 == 0 || n%3 == 0) return false; 

    for (int i=5; i*i<=n; i=i+6) 
        if (n%i == 0 || n%(i+2) == 0) 
           return false; 

    return true; 
}

任何合数都至少有一个因子小于或等于它的平方根。为什么?因为如果它只有一个因子(除了它自己或一个),那将等于它的平方根。如果它有两个或更多,最小的一个必须小于它的平方根。因此无需检查大于平方根的数字——如果它不是素数,我们就已经找到了一个因数。

代码会提前检查 2 或 3 作为一个因素。之后,我们只需要检查不是二或三倍数的因子。所以在我们检查 5 和 7 之后,我们不需要检查 6、8、9 或 10。所以在每六个数字中我们只需要检查两个不是二或三的倍数。

当您搜索质数时,您可以遍历 2 和您的数字之间的所有数字,看看它们是否能整除您的数字。

for (int i=2; i < n; i=i+1) 
    if (n%i == 0)
       return false; 

但这会检查很多您不需要的数字。
第一个观察(优化)是任何 2 的倍数(偶数)已经通过简单地除以 2 检查一次来检查。

所以现在我们检查 2,然后跳过所有其他偶数字符。

if (n%2 == 0 ) return false;

for (int i=3; i < n; i=i+2) 
    if (n%i == 0)
       return false; 

下一个观察(优化)是您可以为三个人做几乎相同的事情。所以第一个测试涵盖了 2 和 3 的所有组合。现在在循环中你跳过每 6 个数字 (2*3) 并做一些测试以覆盖所有不是 2 或 3 的倍数的数字。

if (n%2 == 0 || n%3 == 0) return false; 

for (int i=5; i<n; i=i+6) 
    if (n%i == 0 || n%(i+2) == 0) 
       return false; 

所以这只是一个优化,意味着您不必尝试每个数字。

我们的下一个观察是您不需要尝试大于 n 的平方根的数字(这些数字永远不会被 n 整除)。因此,您可以将循环限制为 i*i < n,因为 i*isqrt(n).

if (n%2 == 0 || n%3 == 0) return false; 

for (int i=5; i*i<=n; i=i+6) 
    if (n%i == 0 || n%(i+2) == 0) 
       return false; 

虽然我个人会 sqrt() 一次而不是 i*i 每次循环。但是对于 n.

的小值,这可能会更慢