【发布时间】:2015-12-10 20:29:02
【问题描述】:
我有一个函数 FIsPrime,它接受 int64 并根据给定的 int64 是否为素数返回布尔值 True 或 False。
function FIsPrime(P:int64):boolean;
var
I:int64;
RSqrtP:Extended;
begin
I:= 3;
RSqrtP := sqrt(P) + 1;
while ((P mod I) <> 0) AND (I <= RSqrtP) AND ((P mod 2) <> 0) do
I := I + 2;
if I < RSqrtP then
FIsPrime := False
else
FIsPrime := True;
end;
但是,虽然这可行,但速度很慢。检查从 106 到 5×106 的数字需要 4 秒。
我正在按 1012 和 1015 的顺序测试数字 - 整个代码选择一个随机数并 × 1012 sup> 得到一个大的随机数。
这个随机数通过FIsPrime 函数运行并递增1直到它是素数:
function FFirstPrimeAbove(P:int64):int64;
var
BIsPrime: boolean;
begin
if P mod 2 = 0 then
inc(P);
repeat
BIsPrime := FIsPrime(P);
P := P + 2;
until (BIsPrime);
FFirstPrimeAbove := P;
end;
这可能需要一段时间 - 1012 大约需要 6 秒,1015 大约需要 7 秒。
虽然 14 秒不算多,但很烦人。有没有办法通过更有效的算法来减少这个时间?
我对 Pascal 还很陌生,但已经编程多年 - 所以任何更有效的算法都会很有用。
我查看了AKS Test,但有很多行话要克服——“多项式同余关系”、“多项式的泛化”和“二项式系数”等等。
任何关于我如何在 Delphi 中实现某些东西的基本提示都将不胜感激。
【问题讨论】:
-
这似乎与 Pascal 和 Delphi 无关。
-
@AndreasRejbrand 我正在写它是 Delphi - 所以答案将用 Delphi 编写。或者你的意思是快速算法的概念是无关的?
-
那么在这种情况下,我建议您进行一些研究。搜索主要的测试算法肯定会发现一些东西。
-
@蒂姆。这取决于您运行此功能的频率。如果你需要它经常存储中间素数,直到你的数字的平方根可能是它。对于 10**14,您需要将质数存储到 10*7,其中大约有 5,761,455 (people.mpim-bonn.mpg.de/zagier/files/doi/10.1007/BF03039306/…)
-
你为什么把你的函数称为
FIsPrime? F是干什么用的?像这样分配布尔值:somebool := somecondition.
标签: performance delphi primes pascal