我是大学生,并且有一项任务,需要找到大的素数。教授给了我以下“简单”算法,找到2个可能的素数。
第3步的示例。
假设p = 5
1 ^ 4%5 = 1
2 ^ 4%5 = 1
3 ^ 4%5 = 1
4 ^ 4%5 = 1
这表明5是素数。
我通过这项任务意识到计算素数不是开玩笑。我用上述算法看到的问题是,如果我猜测大数并用模幂运算测试它们,我可能会尝试将大数字增加到一个大数。这让我怀疑。我已经研究了确定性有限自动机和Eratosthenes的筛子。有没有人有任何建议要么改进给定的算法或提供任何形式的帮助?谢谢你的时间。
答案 0 :(得分:6)
您关注的算法称为Fermat primality test。但是,您的解释存在一些问题:
你说“确认gcd(a,p)是< 1”。这没有意义,因为gcd永远不会少于一个。你可以检查的是gcd(a,p)== 1。如果它不是1,则p不是素数。这可以检测出卡迈克尔数字,但可能只有很小的机会这样做。
进行测试的方式是,对于某个p值,你选择a的几个随机值并检查是否^(p-1)%p == 1.如果其中一个是不是1,那么p不是素数。您选择的值越多,您的准确度就越高。
你肯定无法检查x的所有值 - 因为有太多要检查的内容。
有一种快速的方法可以执行模幂运算,即使对于大的基数和指数也是如此。请参阅Wikipedia article。您仍然需要一种方法来对大整数执行乘法和模运算。
Eratosthenes的筛子仅用于寻找小素数。
此测试可能错误地确定Carmichael数字是素数。其他算法(例如Rabin-Miller)没有此问题。
答案 1 :(得分:-2)
在C#中有点简单。我不知道它在速度方面是否更快。
bool IsPrime(long n)
{
if (n == 1)
{
return false;
}
if (n < 4)
{
return true;
}
if ((n % 2) == 0)
{
return false;
}
if (n < 9)
{
return true;
}
if ((n % 3) == 0)
{
return false;
}
long r = (long)Math.Floor(Math.Sqrt(n));
long f = 5;
while (f <= r)
{
if ((n % f) == 0)
{
return false;
}
if ((n % (f + 2)) == 0)
{
return false;
}
f += 6;
}
return true;
}
答案 2 :(得分:-3)
前段时间我在C#中编写了一些供个人使用的功能。我希望这对你有好处
公共长tmp; public long [] tabnum = new long [1];public void priminum(long NUM) { 长的Resto; 长期的;
// 2 is only number pair prime
tabnum[0] = 2;
for (tmp = 3; tmp <= NUM; tmp++)
{
if ((tmp % 2) == 0) continue;// if num it's pair is not prime
for (long Y = 0; Y < tmp; Y++)
{
riso = Math.DivRem(tabnum[Y], tmp, out Resto);
if (Resto == 0) break;
if(riso <= tabnum[Y])
{
Array.Resize(ref tabnum, tabnum.Length + 1);
tabnum[tabnum.Length - 1] = tmp;
List1.Items.Add(tmp.ToString("###,###"));
break;
}
}
}
}
如果number为prime,则下一个函数返回true
private bool IsPrimo(ulong tmpNum) { ulong Y;
if (tmpNum == 2) return true;
if ((tmpNum % 2) == 0) return false;
for (Y = 2; Y <= tmpNum; Y++)
{
if ((tmpNum % Y) == 0) break;
if ((tmpNum / Y) <= Y) return true;
}
return false;
}