Jump to content

Extensible prime generator: Difference between revisions

m
→‎{{header|Pascal}}: corrected. COllect primes for sieving was wrong implemented ( only first primes to 131071 were right )
(→‎OCaml: add)
m (→‎{{header|Pascal}}: corrected. COllect primes for sieving was wrong implemented ( only first primes to 131071 were right ))
Line 3,501:
=={{header|Pascal}}==
{{works with|Free Pascal}}
Limited to 2.7e14. Much faster than the other Version
<b>there is something wrong </b>
<pre >
http://www.primos.mat.br/Ate100G.html ->
75. de 16639648367 a 16875026921
76. de 16875026963 a 17110593779
77. de 17110593791 a 17346308407
...
my unit:
750000000 16875026921
760000000 17110593779
770000000 17346251243 <----Wrong
</pre>
 
Limited to 2.7e14. Much faster than the other Version. 94s to 257 s for the primes 2..1E11
First the unit.Still a work in progress.
 
Line 3,525 ⟶ 3,512:
<syntaxhighlight lang="pascal">
unit primsieve;
//{$O+,R+}
{$IFDEF FPC}
{$MODE objFPC}{$Optimization ON,ALL}
{$CODEALIGN proc=32,loop=1}
{$IFEND}
{segmented sieve of Erathostenes using only odd numbers}
Line 3,538 ⟶ 3,523:
function SieveSize :LongInt;
function Nextprime: Uint64;
function StartCount :Uint64;
function TotalCount :Uint64;
function PosOfPrime: Uint64;
Line 3,565 ⟶ 3,551:
{$ALIGN 32}
//prime = FoundPrimesOffset + 2*FoundPrimes[0..FoundPrimesCnt]
FoundPrimes : array[0..12252cSieveSize] of Wordword;
{$ALIGN 32}
sievePrimes : array[0..78498] of tSievePrim;// 1e6^2 ->1e12
// sievePrimes : array[0..1077863664579] of tSievePrim;// maximum 1e14
FoundPrimesOffset : Uint64;
FoundPrimesCnt,
Line 3,611 ⟶ 3,597:
function InsertSievePrimes(PrimPos:NativeInt):NativeInt;
var
jdelta :NativeUINtNativeInt;
i,pr,loLmt : NativeUInt;
begin
i := 0;
Line 3,619 ⟶ 3,605:
i := maxPreSievePrimeNum;
pr :=0;
jloLmt := Uint64(SieveNum)*cSieveSize*(2-LastInsertedSievePrime*cSieveSize);
delta := loLmt-LastInsertedSievePrime;
with sievePrimes[PrimPos] do
Begin
pr := FoundPrimes[i]*2+1;
svdeltaPrime := pr+jdelta;
jdelta := pr;
end;
 
inc(PrimPos);
for i := i+1 to FoundPrimesCnt-1 do
Line 3,634 ⟶ 3,622:
Begin
pr := FoundPrimes[i]*2+1;
svdeltaPrime := (pr-jdelta);
jdelta := pr;
end;
inc(PrimPos);
end;
LastInsertedSievePrime :=Uint64(SieveNum)*cSieveSize*2 loLmt+pr;
result := PrimPos;
end;
Line 3,690 ⟶ 3,678:
SieveNum :=0;
CopyPreSieveInSieve;
//normal sieving of first block sieve
i := 1; // start with 3
repeat
Line 3,708 ⟶ 3,696:
CollectPrimes;
PrimPos := InsertSievePrimes(0);
//correct for SieveNum = 0
LastInsertedSievePrime := FoundPrimes[PrimPos]*2+1;
CalcSievePrimOfs(PrimPos);
 
Init0Sieve;
sieveOneBlock;
//now start collect with SieveNum = 1
IF PrimPos < High(sievePrimes) then
Begin
Init0Sieve;
//Erste Sieb nochmals, aber ohne Eintrag
sieveOneBlock;
repeat
sieveOneBlock;
CollectPrimes;
dec(SieveNum);
PrimPos := InsertSievePrimes(PrimPos);
inc(SieveNum);
until PrimPos > High(sievePrimes);
end;
Init0Sieve;
end;
Line 3,812 ⟶ 3,799:
procedure CollectPrimes;
//extract primes to FoundPrimes
 
//
var
pSieve : pbyte;
Line 3,818 ⟶ 3,805:
i,idx : NativeUint;
Begin
FoundPrimesOffset := SieveNum*(2*cSieveSize);
FoundPrimesIdx := 0;
pFound :=@FoundPrimes[0];
Line 3,845 ⟶ 3,832:
end;
 
procedure SieveOneBlock;inline;
begin
CopyPreSieveInSieve;
Line 3,853 ⟶ 3,840:
end;
 
procedure NextSieve;inline;
Begin
SieveOneBlock;
Line 3,868 ⟶ 3,855:
end;
 
function PosOfPrime: Uint64;inline;
Begin
result := FoundPrimesTotal-FoundPrimesCnt+FoundPrimesIdx;
end;
 
function TotalCountStartCount : Uint64 ;inline;
begin
result := FoundPrimesTotal-FoundPrimesCnt;
end;
 
function TotalCount :Uint64;inline;
begin
result := FoundPrimesTotal;
end;
 
function SieveSize :LongInt;inline;
Begin
result := 2*cSieveSize;
end;
 
function SieveStart:Uint64;inline;
Begin
result := (SieveNum-1)*2*cSieveSize;
end;
 
procedure InitPrime;inline;
Begin
Init0Sieve;
Line 3,899 ⟶ 3,891:
InitPrime;
end.
</syntaxhighlight>
{compiler: fpc/3.2.0/ppcx64 -Xs -O4 "%f"
50851378 in 1000079360 dauerte 529 ms
455052800 in 10000007168 dauerte 6297 ms
4118057696 in 100000071680 dauerte 93783 ms
}</syntaxhighlight>
 
;the test program:
<syntaxhighlight lang="pascal">
program test;
{$IFDEF FPC}
{$MODE objFPC}{$Optimization ON,ALL}
{$IFEND}
 
uses
primsieve;
 
var
icnt,p,lmt : NativeIntUint64;
cnt : Uint64;
Begin
lmt := 1000*1000*1000;
writeln('First 25 primes');
For ip := 1 to 25 do0;
while TotalCount < lmt do
write(Nextprime:3);
Begin
writeln;
NextSieve;
Writeln;
inc(p);
writeln('Primes betwenn 100 and 150');
If p AND (4096-1) = 0 then
repeat
write(p:8,TotalCount:15,#13);
i := NextPrime
end;
until i > 100;
cnt := StartCount;
repeat
write(i:4);
i := NextPrime;
until i>150;
writeln;
Writeln;
repeat
i := NextPrime
until i > 7700;
cnt := 0;
repeat
p := NextPrime;
inc(cnt);
until cnt i :>= NextPrimelmt;
writeln(cnt:14,p:14);
until i> 8000;
end.
writeln('between 7700 and 8000 are ',cnt,' primes');
{
Writeln;
10^n primecount
writeln(' i.th prime');
# 1 4
cnt := 10000;
# 2 25
repeat
# 3 while TotalCount < cnt do 168
# 4 NextSieve; 1229
# 5 repeat 9592
# 6 i := NextPrime; 78498
# 7 until PosOfPrime = cnt; 664579
# 8 5761455
writeln(cnt:10,i:12);
# 9 cnt := cnt*10; 50847534
# 10 455052511
until cnt >100*1000*1000;
# 11 4118054813
end.</syntaxhighlight>
# 12 37607912018
;output:
}</syntaxhighlight>
<pre>
{{out|@home}}
First 25 primes
<pre>//4.4 Ghz Ryzen 5600G fpc 3.3.1 -O3 -Xs
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
50847534 999999937
 
real 0m0,386s
Primes betwenn 100 and 150
455052511 9999999967
101 103 107 109 113 127 131 137 139 149
real 0m4,702s
 
4118054813 99999999977
between 7700 and 8000 are 30 primes
real 1m11,085s
 
37607912018 999999999989
i.th prime
real 19m1,195s
10000 104729
100000 1299709
1000000 15485863
10000000 179424673
100000000 2038074743
 
real 0m1,121s
</pre>
 
132

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.