Vantieghems 素数测试定理


问题陈述包括使用 Vantieghems 定理进行素数测试,即我们将检查用户输入的正数 N,并使用 Vantieghems 定理打印该数是否为素数。

Vantieghem 定理

Vantieghems 素数定理指出,如果从 1 到 N−1 的 i 值的 $\mathrm{2^{i}−1}$ 的乘积与模 $\mathrm{2^{N}−1}$ 的 N 同余,则正数 N 为素数。

如果这两个值同余,则数字 N 是素数,否则不是素数。

同余数:如果两个给定数字的差被 n 整除,或者可以说 n 是两个数字差的因子之一,则这两个数字被称为模 n 同余。根据该定理,如果 $\mathrm{2^{N}−1}$ 是 $\mathrm{2^{i}−1}$ 的乘积与 N 的差的因子之一,即它除以差后余数为 0,则这两个数字将是同余数。

让我们用一些例子来理解这个定理。

输入

N=3

输出

Yes

解释 - 从 1 到 N−1(即 1<=i<=N−1)的 i 值的 $\mathrm{2^{i}−1}$ 的乘积为 $\mathrm{(2^{1}−1)*(2^{2}−1)=1*3=3}$

N 的值为 3,因此为了使这些数字同余,两个数字的差(即 0)必须被 $\mathrm{(2^{N}−1)}$ 整除。

由于在这种情况下满足了 Vantieghems 定理的条件,因此 3 是素数。

输入

N=5

输出

Yes

解释 - $\mathrm{(2^{i}−1)}$ 的乘积,其中 i 在这种情况下从 1 到 4,因为 N=5。

$\mathrm{(2^{1}−1)*(2^{2}−1)*(2^{3}−1)*(2^{4}−1)=1*3*7*15=315}$

这里 N 的值为 5,因此为了使 315 和 5 模 $\mathrm{(2^{N}−1)}$(即 31)同余,两个数字 315 和 5 的差必须被 31 整除且没有余数。

差为 310,除以 31 得到 10,因此 5 是素数。

输入

N=6

输出

No

解释 - $\mathrm{(2^{i}−1)}$ 的乘积,其中 1<=i<=N−1。在这种情况下,对于 N=6,i 将从 1 到 5。因此,乘积的值将为:

$\mathrm{(2^{1}−1)*(2^{2}−1)*(2^{3}−1)*(2^{4}−1)*(2^{5}−1)=1*3*7*15*31=9765}$

N 的值为 6。因此,为了使 9765 和 6 模 $\mathrm{(2^{N}−1)\:i.e\:(2^{6}−1)=63}$ 同余,63 必须是 $\mathrm{(2^{i}−1)}$ 的乘积与 N 的差(即 9765−6=9759)的因子之一。

由于 63 不是 9759 的因子,因此 6 不是素数。

我们将在 C++ 中使用素数的 Vantieghems 定理条件来检查给定的数字 N 是否为素数。

算法

因为我们知道任何正数 N 只有在从 1 到 N−1 的 i 值的 $\mathrm{2^{i}−1}$ 的乘积与 N 本身模 $\mathrm{2^{N}−1}$ 同余时才是素数。

这意味着 $\mathrm{2^{i}−1}$ 的乘积与 N 的差必须是 $\mathrm{2^{N}−1}$ 的倍数,或者换句话说,差必须能被 $\mathrm{2^{N}−1}$ 整除。

  • 为了根据 Vantieghems 定理检查一个数字是否为素数,我们将简单地从 i=2 迭代到 i<=N−1,因为对于 i=1,答案将为 1。现在,我们将一直存储每个 i 值的 $\mathrm{2^{i}−1}$ 的乘积,直到 i=N−1 以获得乘积的值。

  • 为了计算 $\mathrm{2^{i}−1}$ 的值,我们将使用按位运算符,即用 i 的值左移 1,因为当我们将任何数字 n 左移 i 时,结果等于 $\mathrm{n*2^{i}}$。因此,在这种情况下,我们将 1 左移 i 以获得 $\mathrm{2^{i}}$ 的值。

  • 一旦我们得到乘积的值,我们将检查 $\mathrm{2^{i}−1}$ 的乘积与 N 模 $\mathrm{2^{N}−1}$ 是否同余。为了使 $\mathrm{2^{i}−1}$ 的乘积与 N 同余,这两个数的差必须能被 $\mathrm{2^{N}−1}$ 整除,因此我们将检查差模 $\mathrm{2^{N}−1}$ 是否等于零。如果它等于零,则该数字为素数。

  • 为了计算 $\mathrm{2^{N}−1}$ 的值,我们将简单地将 1 左移 N,这将等于 $\mathrm{1*2^{N}}$。

我们将在这个算法中使用 C++ 来检查数字是否为素数。

方法

在我们的方法中实现 Vantieghem 定理的步骤

  • 为了检查给定的数字是否为素数,我们将创建一个函数,在其中我们将使用根据 Vantieghem 定理判断一个数字是否为素数的条件。

  • 然后初始化一个变量来存储 $\mathrm{2^{i}−1}$ 的乘积,其中 1<=i<=N−1(N 是给定的数字)。该变量应为 long long 数据类型,因为 $\mathrm{2^{i}−1}$ 的乘积可能值很大。

  • 然后,我们将在一个 for 循环中从 i=1 迭代到 i<N,并使用左移运算符计算 $\mathrm{2^{i}−1}$ 的乘积来计算 $\mathrm{2^{i}}$ 的值。

  • 一旦我们得到 $\mathrm{2^{i}−1}$ 的乘积,我们现在将检查 $\mathrm{2^{i}−1}$ 与 N 的差是否能被 $\mathrm{2^{N}−1}$ 整除,因为这两个数的差必须是 $\mathrm{2^{N}−1}$ 的倍数才能是素数。

  • 如果条件满足,我们将返回该数字为素数,否则我们将返回该数字不是素数。

示例

// C++ code to check if the number is a prime number or not using Vantieghem's Theorem
#include <bits/stdc++.h>

using namespace std;

//function to check the condition of Vantieghem's Theorem for a number to be a prime
bool check(int N)
{
    if(N==1){
        return false;
    }
	long long product = 1; //to store the product of 2^i-1
	
	for (int i=1; i < N; i++) {
        //to find the product of 2^i-1, where 1<=i<=N-1
        product = product*((1LL << i) - 1);
	}
	
	//to check the condition of Vantieghem's Theorem
	//the product of 2^i-1 - N should be the multiple of 2^N -1
	 if ((product-N) % ((1LL << N) - 1) == 0 ){ //using left shift operator to calculate 2^N
            return true;
	 }
            
    else{
        return false;
    }
  
}

int main()
{
    int N;
    N=1;
    //calling the function
	if(check(N)==true){
	    cout<<N<<" is a prime number"<<endl;
	}
	else{
	    cout<<N<<" is not a prime number"<<endl;
	}
	return 0;
}

输出

1 is not a prime number

注意:该代码将为 N 从 1 到 11 的值提供正确的输出,因为对于 N>11,在计算 $\mathrm{2^i−1}$ 的值时,long long 数据类型会发生溢出。

时间复杂度 - O(N),因为我们在 for 循环中迭代 N 次来计算 2^i−1 的乘积。

空间复杂度 - O(1),因为没有使用额外的空间来解决问题。

结论

在本文中,我们详细讨论了 Vantieghem 定理,用于检查数字是否为素数。我们在 C++ 中的代码中使用根据 Vantieghem 定理判断数字是否为素数的条件,以检查该数字是否为素数。

希望您理解了 Vantieghem 定理,并在阅读本文后解决了您关于该定理的所有疑问。

更新于: 2023年8月28日

82 次浏览

开启您的 职业生涯

通过完成课程获得认证

开始学习
广告

© . All rights reserved.