Sieve of Eratosthenes: Difference between revisions

(326 intermediate revisions by 94 users not shown)
Line 29:
*   [[sequence of primes by Trial Division]]
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F primes_upto(limit)
V is_prime = [0B]*2 [+] [1B]*(limit - 1)
L(n) 0 .< Int(limit ^ 0.5 + 1.5)
I is_prime[n]
L(i) (n*n..limit).step(n)
is_prime[i] = 0B
R enumerate(is_prime).filter((i, prime) -> prime).map((i, prime) -> i)
 
print(primes_upto(100))</syntaxhighlight>
 
{{out}}
<pre>
[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]
</pre>
 
=={{header|360 Assembly}}==
For maximum compatibility, this program uses only the basic instruction set.
<langsyntaxhighlight 360_Assemblylang="360_assembly">* Sieve of Eratosthenes
ERATOST CSECT
USING ERATOST,R12
Line 102 ⟶ 120:
CRIBLE DC 100000X'01'
YREGS
END ERATOST</langsyntaxhighlight>
{{out}}
<pre style="height:20ex">
Line 150 ⟶ 168:
=={{header|6502 Assembly}}==
If this subroutine is called with the value of <i>n</i> in the accumulator, it will store an array of the primes less than <i>n</i> beginning at address 1000 hex and return the number of primes it has found in the accumulator.
<langsyntaxhighlight lang="6502asm">ERATOS: STA $D0 ; value of n
LDA #$00
LDX #$00
Line 188 ⟶ 206:
JMP COPY
COPIED: TYA ; how many found
RTS</langsyntaxhighlight>
 
=={{header|68000 Assembly}}==
Line 197 ⟶ 215:
Some of the macro code is derived from the examples included with EASy68K.
See 68000 "100 Doors" listing for additional information.
<langsyntaxhighlight lang="68000devpac">*-----------------------------------------------------------
* Title : BitSieve
* Written by : G. A. Tippery
Line 451 ⟶ 469:
Summary2: DC.B ' prime numbers found.',CR,LF,$00
 
END START ; last line of source</langsyntaxhighlight>
 
 
=={{header|8086 Assembly}}==
 
<syntaxhighlight lang="asm">MAXPRM: equ 5000 ; Change this value for more primes
cpu 8086
bits 16
org 100h
section .text
erato: mov cx,MAXPRM ; Initialize array (set all items to prime)
mov bp,cx ; Keep a copy in BP
mov di,sieve
mov al,1
rep stosb
;;; Sieve
mov bx,sieve ; Set base register to array
inc cx ; CX=1 (CH=0, CL=1); CX was 0 before
mov si,cx ; Start at number 2 (1+1)
.next: inc si ; Next number
cmp cl,[bx+si] ; Is this number marked as prime?
jne .next ; If not, try next number
mov ax,si ; Otherwise, calculate square,
mul si
mov di,ax ; and put it in DI
cmp di,bp ; Check array bounds
ja output ; We're done when SI*SI>MAXPRM
.mark: mov [bx+di],ch ; Mark byte as composite
add di,si ; Next composite
cmp di,bp ; While maximum not reached
jbe .mark
jmp .next
;;; Output
output: mov si,2 ; Start at 2
.test: dec byte [bx+si] ; Prime?
jnz .next ; If not, try next number
mov ax,si ; Otherwise, print number
call prax
.next: inc si
cmp si,MAXPRM
jbe .test
ret
;;; Write number in AX to standard output (using MS-DOS)
prax: push bx ; Save BX
mov bx,numbuf
mov bp,10 ; Divisor
.loop: xor dx,dx ; Divide AX by 10, modulus in DX
div bp
add dl,'0' ; ASCII digit
dec bx
mov [bx],dl ; Store ASCII digit
test ax,ax ; More digits?
jnz .loop
mov dx,bx ; Print number
mov ah,9 ; 9 = MS-DOS syscall to print string
int 21h
pop bx ; Restore BX
ret
section .data
db '*****' ; Room for number
numbuf: db 13,10,'$'
section .bss
sieve: resb MAXPRM</syntaxhighlight>
 
{{out}}
<pre>2
3
5
7
11
...
4969
4973
4987
4993
4999
</pre>
 
=={{header|8th}}==
<syntaxhighlight lang="8th">
with: n
 
\ create a new buffer which will function as a bit vector
: bit-vec SED: n -- b
dup 3 shr swap 7 band if 1+ then b:new b:clear ;
 
\ given a buffer, sieving prime, and limit, cross off multiples
\ of the sieving prime.
: +composites SED: b n n -- b
>r dup sqr rot \ want: -- n index b
repeat
over 1- true b:bit!
>r over + r>
over r@ > until!
rdrop nip nip ;
 
\ SoE algorithm proper
: make-sieve SED: n -- b
dup>r bit-vec 2
repeat
tuck 1- b:bit@ not
if
over r@ +composites
then swap 1+
dup sqr r@ < while!
rdrop drop ;
 
\ traverse the final buffer, creating an array of primes
: sieve>a SED: b n -- a
>r a:new swap
( 1- b:bit@ not if >r I a:push r> then ) 2 r> loop drop ;
 
;with
 
: sieve SED: n -- a
dup make-sieve swap sieve>a ;
</syntaxhighlight>
{{Out}}
<pre>
ok> 100 sieve .
[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]
ok> 1_000_000 sieve a:len . \ count primes up to 1,000,000
78498
ok> -1 a:@ . \ largest prime < 1,000,000
999983
</pre>
 
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program cribleEras64.s */
 
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeConstantesARM64.inc"
 
.equ MAXI, 100
 
/*********************************/
/* Initialized data */
/*********************************/
.data
sMessResult: .asciz "Prime : @ \n"
szCarriageReturn: .asciz "\n"
 
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
TablePrime: .skip 8 * MAXI
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x4,qAdrTablePrime // address prime table
mov x0,#2 // prime 2
bl displayPrime
mov x1,#2
mov x2,#1
1: // loop for multiple of 2
str x2,[x4,x1,lsl #3] // mark multiple of 2
add x1,x1,#2
cmp x1,#MAXI // end ?
ble 1b // no loop
mov x1,#3 // begin indice
mov x3,#1
2:
ldr x2,[x4,x1,lsl #3] // load table élément
cmp x2,#1 // is prime ?
beq 4f
mov x0,x1 // yes -> display
bl displayPrime
mov x2,x1
3: // and loop to mark multiples of this prime
str x3,[x4,x2,lsl #3]
add x2,x2,x1 // add the prime
cmp x2,#MAXI // end ?
ble 3b // no -> loop
4:
add x1,x1,2 // other prime in table
cmp x1,MAXI // end table ?
ble 2b // no -> loop
 
100: // standard end of the program
mov x0,0 // return code
mov x8,EXIT // request to exit program
svc 0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrsMessResult: .quad sMessResult
qAdrTablePrime: .quad TablePrime
 
/******************************************************************/
/* Display prime table elements */
/******************************************************************/
/* x0 contains the prime */
displayPrime:
stp x1,lr,[sp,-16]! // save registers
ldr x1,qAdrsZoneConv
bl conversion10 // call décimal conversion
ldr x0,qAdrsMessResult
ldr x1,qAdrsZoneConv // insert conversion in message
bl strInsertAtCharInc
bl affichageMess // display message
100:
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
qAdrsZoneConv: .quad sZoneConv
 
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
<pre>
Prime : 2
Prime : 3
Prime : 5
Prime : 7
Prime : 11
Prime : 13
Prime : 17
Prime : 19
Prime : 23
Prime : 29
Prime : 31
Prime : 37
Prime : 41
Prime : 43
Prime : 47
Prime : 53
Prime : 59
Prime : 61
Prime : 67
Prime : 71
Prime : 73
Prime : 79
Prime : 83
Prime : 89
Prime : 97
</pre>
 
=={{header|ABAP}}==
<syntaxhighlight lang="lisp">
<lang Lisp>
PARAMETERS: p_limit TYPE i OBLIGATORY DEFAULT 100.
 
Line 496 ⟶ 760:
ENDIF.
ENDLOOP.
</syntaxhighlight>
</lang>
 
=={{header|ABC}}==
<syntaxhighlight lang="ABC">HOW TO SIEVE UP TO n:
SHARE sieve
PUT {} IN sieve
FOR cand IN {2..n}: PUT 1 IN sieve[cand]
FOR cand IN {2..floor root n}:
IF sieve[cand] = 1:
PUT cand*cand IN comp
WHILE comp <= n:
PUT 0 IN sieve[comp]
PUT comp+cand IN comp
 
HOW TO REPORT prime n:
SHARE sieve
IF n<2: FAIL
REPORT sieve[n] = 1
 
SIEVE UP TO 100
FOR n IN {1..100}:
IF prime n: WRITE n</syntaxhighlight>
{{out}}
<pre>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</pre>
 
=={{header|ACL2}}==
<langsyntaxhighlight Lisplang="lisp">(defun nats-to-from (n i)
(declare (xargs :measure (nfix (- n i))))
(if (zp (- n i))
Line 527 ⟶ 815:
 
(defun sieve (limit)
(sieve-r 2 limit))</langsyntaxhighlight>
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">DEFINE MAX="1000"
 
PROC Main()
BYTE ARRAY t(MAX+1)
INT i,j,k,first
 
FOR i=0 TO MAX
DO
t(i)=1
OD
 
t(0)=0
t(1)=0
 
i=2 first=1
WHILE i<=MAX
DO
IF t(i)=1 THEN
IF first=0 THEN
Print(", ")
FI
PrintI(i)
FOR j=2*i TO MAX STEP i
DO
t(j)=0
OD
first=0
FI
i==+1
OD
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Sieve_of_Eratosthenes.png Screenshot from Atari 8-bit computer]
<pre>
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, 101, 103,
107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223,
227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347,
349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607,
613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743,
751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883,
887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997
</pre>
 
=={{header|ActionScript}}==
Works with ActionScript 3.0 (this is utilizing the actions panel, not a separated class file)
<langsyntaxhighlight lang="actionscript">function eratosthenes(limit:int):Array
{
var primes:Array = new Array();
Line 554 ⟶ 887:
}
var e:Array = eratosthenes(1000);
trace(e);</langsyntaxhighlight>
Output:
{{out}}
Line 563 ⟶ 896:
=={{header|Ada}}==
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, Ada.Command_Line;
 
procedure Eratos is
 
Last: Positive := Positive'Value(Ada.Command_Line.Argument(1));
Prime: array(1 .. Last) of Boolean := (1 => False, others => True);
Line 572 ⟶ 905:
Cnt: Positive;
begin
while Base * Base <= Last loop
exit when Base * Base > Last;
if Prime(Base) then
Cnt := Base + Base;
while Cnt <= Last loop
exit when Cnt > Last;
Prime(Cnt) := False;
Cnt := Cnt + Base;
Line 590 ⟶ 921:
end if;
end loop;
end Eratos;</langsyntaxhighlight>
 
{{out}}
Line 598 ⟶ 929:
=={{header|Agda}}==
 
<langsyntaxhighlight lang="agda">
-- imports
open import Data.Nat as ℕ using (ℕ; suc; zero; _+_; _∸_)
Line 645 ⟶ 976:
remove _ ys zero = nothing ∷ ys i
remove y ys (suc j) = y ∷ ys j
</syntaxhighlight>
</lang>
 
=={{header|Agena}}==
Tested with Agena 2.9.5 Win32
<langsyntaxhighlight lang="agena"># Sieve of Eratosthenes
 
# generate and return a sequence containing the primes up to sieveSize
Line 680 ⟶ 1,011:
 
# test the sieve proc
for i in sieve( 100 ) do write( " ", i ) od; print();</langsyntaxhighlight>
{{out}}
<pre>
Line 717 ⟶ 1,048:
 
'''Works with:''' ALGOL 60 for OS/360
<langsyntaxhighlight lang="algol60">'BEGIN'
'INTEGER' 'ARRAY' CANDIDATES(/0..1000/);
'INTEGER' I,J,K;
Line 756 ⟶ 1,087:
'END'
'END'
'END'</langsyntaxhighlight>
 
=={{header|ALGOL 68}}==
<langsyntaxhighlight lang="algol68">BOOL prime = TRUE, non prime = FALSE;
PROC eratosthenes = (INT n)[]BOOL:
(
Line 776 ⟶ 1,107:
);
print((eratosthenes(80),new line))</langsyntaxhighlight>
{{out}}
<pre>
FTTFTFTFFFTFTFFFTFTFFFTFFFFFTFTFFFFFTFFFTFTFFFTFFFFFTFFFFFTFTFFFFFTFFFTFTFFFFFTF
</pre>
 
=={{header|ALGOL W}}==
=== Standard, non-optimised sieve ===
<syntaxhighlight lang="algolw">begin
 
% implements the sieve of Eratosthenes %
% s(i) is set to true if i is prime, false otherwise %
% algol W doesn't have a upb operator, so we pass the size of the %
% array in n %
procedure sieve( logical array s ( * ); integer value n ) ;
begin
 
% start with everything flagged as prime %
for i := 1 until n do s( i ) := true;
 
% sieve out the non-primes %
s( 1 ) := false;
for i := 2 until truncate( sqrt( n ) )
do begin
if s( i )
then begin
for p := i * i step i until n do s( p ) := false
end if_s_i
end for_i ;
 
end sieve ;
 
% test the sieve procedure %
 
integer sieveMax;
 
sieveMax := 100;
begin
 
logical array s ( 1 :: sieveMax );
 
i_w := 2; % set output field width %
s_w := 1; % and output separator width %
 
% find and display the primes %
sieve( s, sieveMax );
for i := 1 until sieveMax do if s( i ) then writeon( i );
 
end
 
end.</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
=== Odd numbers only version ===
 
Alternative version that only stores odd numbers greater than 1 in the sieve.
<syntaxhighlight lang="algolw">begin
% implements the sieve of Eratosthenes %
% only odd numbers appear in the sieve, which starts at 3 %
% s( i ) is set to true if ( i * 2 ) + 1 is prime %
procedure sieve2( logical array s ( * ); integer value n ) ;
begin
% start with everything flagged as prime %
for i := 1 until n do s( i ) := true;
% sieve out the non-primes %
% the subscripts of s are 1 2 3 4 5 6 7 8 9 10 11 12 13... %
% which correspond to 3 5 7 9 11 13 15 17 19 21 23 25 27... %
for i := 1 until truncate( sqrt( n ) ) do begin
if s( i ) then begin
integer ip;
ip := ( i * 2 ) + 1;
for p := i + ip step ip until n do s( p ) := false
end if_s_i
end for_i ;
end sieve2 ;
% test the sieve2 procedure %
integer primeMax, arrayMax;
primeMax := 100;
arrayMax := ( primeMax div 2 ) - 1;
begin
logical array s ( 1 :: arrayMax);
i_w := 2; % set output field width %
s_w := 1; % and output separator width %
% find and display the primes %
sieve2( s, arrayMax );
write( 2 );
for i := 1 until arrayMax do if s( i ) then writeon( ( i * 2 ) + 1 );
end
end.</syntaxhighlight>
{{out}}
Same as the standard version.
 
=={{header|ALGOL-M}}==
<langsyntaxhighlight lang="algol">
BEGIN
 
COMMENT
FIND PRIMES UP TO THE SPECIFIED LIMIT (HERE 1,000) USING
THECLASSIC SIEVE OF ERATOSTHENES;
 
% CALCULATE INTEGER SQUARE ROOT %
Line 815 ⟶ 1,235:
 
% INITIALIZE TABLE %
WRITE("INITIALIZING ... ");
FOR I := 1 STEP 1 UNTIL LIMIT DO
FLAGS[I] := TRUE;
 
% SIEVE FOR PRIMES %
WRITEON("SIEVING ... ");
FOR I := 2 STEP 1 UNTIL ISQRT(LIMIT) DO
BEGIN
Line 826 ⟶ 1,248:
END;
 
% WRITE OUT THE PRIMES EIGHTTEN PER LINE %
WRITEON("PRINTING");
COUNT := 0;
COL := 1;
WRITE(" ");
FOR I := 2 STEP 1 UNTIL LIMIT DO
BEGIN
Line 837 ⟶ 1,260:
COUNT := COUNT + 1;
COL := COL + 1;
IF COL > 810 THEN
BEGIN
WRITE(" ");
COL := 1;
END;
Line 845 ⟶ 1,268:
END;
 
WRITE(" ");
WRITE(COUNT, " primesPRIMES wereWERE foundFOUND.");
 
END
</syntaxhighlight>
</lang>
 
=={{header|ALGOL W}}==
<lang algolw>begin
 
% implements the sieve of Eratosthenes %
% s(i) is set to true if i is prime, false otherwise %
% algol W doesn't have a upb operator, so we pass the size of the %
% array in n %
procedure sieve( logical array s ( * ); integer value n ) ;
begin
 
% start with everything flagged as prime %
for i := 1 until n do s( i ) := true;
 
% sieve out the non-primes %
s( 1 ) := false;
for i := 2 until truncate( sqrt( n ) )
do begin
if s( i )
then begin
for p := i * i step i until n do s( p ) := false
end if_s_i
end for_i ;
 
end sieve ;
 
% test the sieve procedure %
 
integer sieveMax;
 
sieveMax := 100;
begin
 
logical array s ( 1 :: sieveMax );
 
i_w := 2; % set output field width %
s_w := 1; % and output separator width %
 
% find and display the primes %
sieve( s, sieveMax );
for i := 1 until sieveMax do if s( i ) then writeon( i );
 
end
 
end.</lang>
{{out}}
<pre>
FINDING PRIMES FROM 2 TO 1000
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
INTIALIZING ... SIEVING ... PRINTING
2 3 5 7 11 13 17 19 23 29
31 37 41 43 47 53 59 61 67 71
. . .
877 881 883 887 907 911 919 929 937 941
947 953 967 971 977 983 991 997
 
168 PRIMES WERE FOUND.
</pre>
 
=={{Headerheader|APL}}==
 
All these versions requires<tt> ⎕io←0 </tt>(index origin 0).
Line 911 ⟶ 1,297:
=== Non-Optimized Version ===
 
<langsyntaxhighlight lang="apl">sieve2←{
b←⍵⍴1
b[⍳2⌊⍵]←0
Line 920 ⟶ 1,306:
}
 
primes2←{⍵/⍳⍴⍵}∘sieve2</langsyntaxhighlight>
 
The required list of prime divisors obtains by recursion (<tt>{⍵/⍳⍴⍵}∇⌈⍵*0.5</tt>).
 
=== Optimized Version ===|
 
<langsyntaxhighlight lang="apl">sieve←{
b←⍵⍴{∧⌿↑(×/⍵)⍴¨~⍵↑¨1}2 3 5
b[⍳6⌊⍵]←(6⌊⍵)⍴0 0 1 1 0 1
Line 935 ⟶ 1,321:
}
 
primes←{⍵/⍳⍴⍵}∘sieve</langsyntaxhighlight>
 
The optimizations are as follows:
Line 944 ⟶ 1,330:
=== Examples ===
 
<langsyntaxhighlight lang="apl"> primes 100
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
 
Line 956 ⟶ 1,342:
 
+/∘sieve¨ 10*⍳10
0 4 25 168 1229 9592 78498 664579 5761455 50847534</langsyntaxhighlight>
 
The last expression computes the number of primes < 1e0 1e1 ... 1e9.
The last number 50847534 can perhaps be called the anti-Bertelsen's number (http://mathworld.wolfram.com/BertelsensNumber.html).
 
=={{Headerheader|AppleScript}}==
{{incorrect|AppleScript|This version uses rem testing and so is a trial division algorithm, not a sieve of Eratosthenes.}}
Note: This version of Trial Division has something like O(n^(3/2) asymptotic execution complexity rather than O(n log (log n)) for the true sieve.
 
<langsyntaxhighlight lang="applescript">toon sievesieveOfEratosthenes(Nlimit)
script o
property numberList : {missing value}
on array()
end script
set L to {}
repeat with in from 12 to Nlimit
set end of Lo's numberList to in
end repeat
repeat with n from 2 to (limit ^ 0.5 div 1)
if (item n of o's numberList is n) then
L
repeat with multiple from (n * n) to limit by n
end array
set item multiple of o's numberList to missing value
end script
end repeat
end if
set L to result's array()
end repeat
set item 1 of L to false
return o's numberList's numbers
repeat with x in L
end sieveOfEratosthenes
repeat with y in L
try
if (x < y ^ 2) then exit repeat
if (x mod y = 0) then
set x's contents to false
exit repeat
end if
end try
end repeat
end repeat
numbers in L
end sieve
 
sieveOfEratosthenes(1000)</syntaxhighlight>
 
{{out}}
sieve(1000)</lang>
<syntaxhighlight lang="applescript">{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, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997}</syntaxhighlight>
 
=={{header|ARM Assembly}}==
{{out}}
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
 
/* ARM assembly Raspberry PI */
/* program cribleEras.s */
 
/* REMARK 1 : this program use routines in a include file
see task Include a file language arm assembly
for the routine affichageMess conversion10
see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes */
/************************************/
.include "../constantes.inc"
 
.equ MAXI, 101
 
 
/*********************************/
/* Initialized data */
/*********************************/
.data
sMessResult: .asciz "Prime : @ \n"
szCarriageReturn: .asciz "\n"
 
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
TablePrime: .skip 4 * MAXI
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
ldr r4,iAdrTablePrime @ address prime table
mov r0,#2 @ prime 2
bl displayPrime
mov r1,#2
mov r2,#1
1: @ loop for multiple of 2
str r2,[r4,r1,lsl #2] @ mark multiple of 2
add r1,#2
cmp r1,#MAXI @ end ?
ble 1b @ no loop
mov r1,#3 @ begin indice
mov r3,#1
2:
ldr r2,[r4,r1,lsl #2] @ load table élément
cmp r2,#1 @ is prime ?
beq 4f
mov r0,r1 @ yes -> display
bl displayPrime
mov r2,r1
3: @ and loop to mark multiples of this prime
str r3,[r4,r2,lsl #2]
add r2,r1 @ add the prime
cmp r2,#MAXI @ end ?
ble 3b @ no -> loop
4:
add r1,#2 @ other prime in table
cmp r1,#MAXI @ end table ?
ble 2b @ no -> loop
 
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc #0 @ perform the system call
iAdrszCarriageReturn: .int szCarriageReturn
iAdrsMessResult: .int sMessResult
iAdrTablePrime: .int TablePrime
 
/******************************************************************/
/* Display prime table elements */
/******************************************************************/
/* r0 contains the prime */
displayPrime:
push {r1,lr} @ save registers
ldr r1,iAdrsZoneConv
bl conversion10 @ call décimal conversion
ldr r0,iAdrsMessResult
ldr r1,iAdrsZoneConv @ insert conversion in message
bl strInsertAtCharInc
bl affichageMess @ display message
100:
pop {r1,lr}
bx lr
iAdrsZoneConv: .int sZoneConv
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"
</syntaxhighlight>
<pre>
Prime : 2
{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, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997}
Prime : 3
Prime : 5
Prime : 7
Prime : 11
Prime : 13
Prime : 17
Prime : 19
Prime : 23
Prime : 29
Prime : 31
Prime : 37
Prime : 41
Prime : 43
Prime : 47
Prime : 53
Prime : 59
Prime : 61
Prime : 67
Prime : 71
Prime : 73
Prime : 79
Prime : 83
Prime : 89
Prime : 97
Prime : 101
</pre>
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">sieve: function [upto][
=={{Header|AutoHotkey}}==
composites: array.of: inc upto false
loop 2..to :integer sqrt upto 'x [
if not? composites\[x][
loop range.step: x x^2 upto 'c [
composites\[c]: true
]
]
]
result: new []
loop.with:'i composites 'c [
unless c -> 'result ++ i
]
return result -- [0,1]
]
 
print sieve 100</syntaxhighlight>
 
{{out}}
 
<pre>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</pre>
 
=={{header|AutoHotkey}}==
{{AutoHotkey case}}Source: [http://www.autohotkey.com/forum/topic44657.html AutoHotkey forum] by Laszlo
<langsyntaxhighlight lang="autohotkey">MsgBox % "12345678901234567890`n" Sieve(20)
 
Sieve(n) { ; Sieve of Eratosthenes => string of 0|1 chars, 1 at position k: k is prime
Line 1,021 ⟶ 1,539:
}
Return S
}</langsyntaxhighlight>
 
=={{Header|AutoIt}}==
===Alternative Version===
<lang autoit>#include <Array.au3>
<syntaxhighlight lang="autohotkey">Sieve_of_Eratosthenes(n){
arr := []
loop % n-1
if A_Index>1
arr[A_Index] := true
 
for i, v in arr {
if (i>Sqrt(n))
break
else if arr[i]
while ((j := i*2 + (A_Index-1)*i) < n)
arr.delete(j)
}
return Arr
}</syntaxhighlight>
Examples:<syntaxhighlight lang="autohotkey">n := 101
Arr := Sieve_of_Eratosthenes(n)
loop, % n-1
output .= (Arr[A_Index] ? A_Index : ".") . (!Mod(A_Index, 10) ? "`n" : "`t")
MsgBox % output
return</syntaxhighlight>
{{out}}
<pre>. 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 . . .</pre>
 
=={{header|AutoIt}}==
<syntaxhighlight lang="autoit">#include <Array.au3>
$M = InputBox("Integer", "Enter biggest Integer")
Global $a[$M], $r[$M], $c = 1
Line 1,037 ⟶ 1,590:
$r[0] = $c - 1
ReDim $r[$c]
_ArrayDisplay($r)</langsyntaxhighlight>
 
=={{header|AWK}}==
Line 1,062 ⟶ 1,615:
input from commandline as well as stdin,
and input is checked for valid numbers:
<langsyntaxhighlight lang="awk">
# usage: gawk -v n=101 -f sieve.awk
 
Line 1,081 ⟶ 1,634:
 
END { print "Bye!" }
</syntaxhighlight>
</lang>
 
Here is an alternate version that uses an associative array to record composites with a prime dividing it. It can be considered a slow version, as it does not cross out composites until needed. This version assumes enough memory to hold all primes up to ULIMIT. It prints out noncomposites greater than 1.
<langsyntaxhighlight lang="awk">
BEGIN { ULIMIT=100
 
Line 1,096 ⟶ 1,649:
else print ( S[(n+n)] = n )
}
</syntaxhighlight>
</lang>
 
==Bash==
Line 1,104 ⟶ 1,657:
{{works with|FreeBASIC}}
{{works with|RapidQ}}
<langsyntaxhighlight lang="freebasic">DIM n AS Integer, k AS Integer, limit AS Integer
 
INPUT "Enter number to search to: "; limit
Line 1,120 ⟶ 1,673:
FOR n = 2 TO limit
IF flags(n) = 0 THEN PRINT n; ", ";
NEXT n</langsyntaxhighlight>
 
==={{header|Applesoft BASIC}}===
<langsyntaxhighlight lang="basic">10 INPUT "ENTER NUMBER TO SEARCH TO: ";LIMIT
20 DIM FLAGS(LIMIT)
30 FOR N = 2 TO SQR (LIMIT)
Line 1,134 ⟶ 1,687:
100 FOR N = 2 TO LIMIT
110 IF FLAGS(N) = 0 THEN PRINT N;", ";
120 NEXT N</langsyntaxhighlight>
 
==={{header|Atari BASIC}}===
{{trans|Commodore BASIC}}
Auto-initialization of arrays is not reliable, so we have to do our own. Also, PRINTing with commas doesn't quite format as nicely as one might hope, so we do a little extra work to keep the columns lined up.
<syntaxhighlight lang="basic">100 REM SIEVE OF ERATOSTHENES
110 PRINT "LIMIT";:INPUT LI
120 DIM N(LI):FOR I=0 TO LI:N(I)=1:NEXT I
130 SL = SQR(LI)
140 N(0)=0:N(1)=0
150 FOR P=2 TO SL
160 IF N(P)=0 THEN 200
170 FOR I=P*P TO LI STEP P
180 N(I)=0
190 NEXT I
200 NEXT P
210 C=0
220 FOR I=2 TO LI
230 IF N(I)=0 THEN 260
240 PRINT I,:C=C+1
250 IF C=3 THEN PRINT:C=0
260 NEXT I
270 IF C THEN PRINT</syntaxhighlight>
{{Out}}
<pre> Ready
RUN
LIMIT?100
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</pre>
 
==={{header|Commodore BASIC}}===
Since C= BASIC initializes arrays to all zeroes automatically, we avoid needing our own initialization loop by simply letting 0 mean prime and using 1 for composite.
<syntaxhighlight lang="basic">100 REM SIEVE OF ERATOSTHENES
110 INPUT "LIMIT";LI
120 DIM N(LI)
130 SL = SQR(LI)
140 N(0)=1:N(1)=1
150 FOR P=2 TO SL
160 : IF N(P) THEN 200
170 : FOR I=P*P TO LI STEP P
180 : N(I)=1
190 : NEXT I
200 NEXT P
210 FOR I=2 TO LI
220 : IF N(I)=0 THEN PRINT I,
230 NEXT I
240 PRINT
</syntaxhighlight>
{{Out}}
<pre>
READY.
RUN
LIMIT? 100
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
 
READY.
</pre>
 
==={{header|IS-BASIC}}===
<langsyntaxhighlight ISlang="is-BASICbasic">100 PROGRAM "Sieve.bas"
110 LET LIMIT=100
120 NUMERIC T(1 TO LIMIT)
Line 1,152 ⟶ 1,774:
230 FOR I=2 TO LIMIT ! Display the primes
240 IF T(I)=0 THEN PRINT I;
250 NEXT</langsyntaxhighlight>
 
==={{header|Locomotive Basic}}===
<langsyntaxhighlight lang="locobasic">10 DEFINT a-z
20 INPUT "Limit";limit
30 DIM f(limit)
Line 1,166 ⟶ 1,788:
100 FOR n=2 TO limit
110 IF f(n)=0 THEN PRINT n;",";
120 NEXT</langsyntaxhighlight>
 
==={{header|MSX Basic}}===
<syntaxhighlight lang="msx basic">5 REM Tested with MSXPen web emulator
<lang MSX Basic>5 Rem MSX BRRJPA
6 REM Translated from Rosetta's ZX Spectrum implementation
10 INPUT "Search until: ";L
10 INPUT "Enter number to search to: ";l
20 DIM p(L)
20 DIM p(l)
30 FOR n=2 TO SQR (L+1000)
30 FOR n=2 TO SQR(l)
40 IF p(n)<>0 THEN goto 80
5040 FORIF k=p(n*n TO)<>0 LTHEN STEPNEXT n
50 FOR k=n*n TO l STEP n
60 LET p(k)=1
70 NEXT k
80 NEXT n
90 FORREM n=2Display TOthe Lprimes
100 IFFOR p(n)=02 THENTO PRINT n;", ";l
110 IF p(n)=0 THEN PRINT n;", ";
110 NEXT n</lang>
120 NEXT n</syntaxhighlight>
 
 
==={{header|Sinclair ZX81 BASIC}}===
Line 1,187 ⟶ 1,810:
 
A note on <code>FAST</code> and <code>SLOW</code>: under normal circumstances the CPU spends about 3/4 of its time driving the display and only 1/4 doing everything else. Entering <code>FAST</code> mode blanks the screen (which we do not want to update anyway), resulting in substantially improved performance; we then return to <code>SLOW</code> mode when we have something to print out.
<langsyntaxhighlight lang="basic"> 10 INPUT L
20 FAST
30 DIM N(L)
Line 1,199 ⟶ 1,822:
110 FOR I=2 TO L
120 IF NOT N(I) THEN PRINT I;" ";
130 NEXT I</langsyntaxhighlight>
 
==={{header|ZX Spectrum Basic}}===
<langsyntaxhighlight lang="zxbasic">10 INPUT "Enter number to search to: ";l
20 DIM p(l)
30 FOR n=2 TO SQR l
Line 1,213 ⟶ 1,836:
100 FOR n=2 TO l
110 IF p(n)=0 THEN PRINT n;", ";
120 NEXT n</langsyntaxhighlight>
 
==={{header|BBC BASICQBasic}}===
{{works with|QBasic|1.1}}
<lang bbcbasic> limit% = 100000
{{works with|QuickBasic|4.5}}
DIM sieve% limit%
<syntaxhighlight lang="qbasic">limit = 120
 
prime% = 2
DIM flags(limit)
WHILE prime%^2 < limit%
FOR I%n = prime%*2 TO limit% STEP prime%
sieve%?I%flags(n) = 1
NEXT n
NEXT
 
REPEAT prime% += 1 : UNTIL sieve%?prime%=0
PRINT "Prime numbers less than or equal to "; limit; " are: "
ENDWHILE
FOR n = 2 TO SQR(limit)
IF flags(n) REM= Display1 the primes:THEN
FOR I%i = 1n * n TO limit% STEP n
IF sieve%?I% = 0 PRINTflags(i) I%;= 0
NEXT NEXT</lang>i
END IF
NEXT n
 
FOR n = 1 TO limit
IF flags(n) THEN PRINT USING "####"; n;
NEXT n</syntaxhighlight>
{{out}}
<pre>Prime numbers less than or equal to 120 are:
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 101 103 107 109 113</pre>
 
==={{header|BASIC256}}===
<syntaxhighlight lang="basic256">arraybase 1
limit = 120
 
dim flags(limit)
for n = 2 to limit
flags[n] = True
next n
 
print "Prime numbers less than or equal to "; limit; " are: "
for n = 2 to sqr(limit)
if flags[n] then
for i = n * n to limit step n
flags[i] = False
next i
end if
next n
 
for n = 1 to limit
if flags[n] then print rjust(n,4);
next n</syntaxhighlight>
{{out}}
<pre>Prime numbers less than or equal to 120 are:
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 101 103 107 109 113</pre>
 
==={{header|True BASIC}}===
{{trans|QBasic}}
<syntaxhighlight lang="qbasic">LET limit = 120
DIM flags(0)
MAT redim flags(limit)
FOR n = 2 to limit
LET flags(n) = 1
NEXT n
PRINT "Prime numbers less than or equal to "; limit; " are: "
FOR n = 2 to sqr(limit)
IF flags(n) = 1 then
FOR i = n*n to limit step n
LET flags(i) = 0
NEXT i
END IF
NEXT n
FOR n = 1 to limit
IF flags(n)<>0 then PRINT using "####": n;
NEXT n
END</syntaxhighlight>
{{out}}
<pre>Same as QBasic entry.</pre>
 
==={{header|QL SuperBASIC}}===
====using 'easy way' to 'add' 2n wheels====
{{trans|ZX Spectrum Basic}}
Sets h$ to 1 for higher multiples of 2 via <code>FILL$</code>, later on sets <code>STEP</code> to 2n; replaces Floating Pt array p(z) with string variable h$(z) to sieve out all primes < z=441 (<code>l</code>=21) in under 1K, so that h$ is fillable to its maximum (32766), even on a 48K ZX Spectrum if translated back.
<syntaxhighlight lang="qbasic">
10 INPUT "Enter Stopping Pt for squared factors: ";z
15 LET l=SQR(z)
20 LET h$="10" : h$=h$ & FILL$("01",z)
40 FOR n=3 TO l
50 IF h$(n): NEXT n
60 FOR k=n*n TO z STEP n+n: h$(k)=1
80 END FOR n
90 REM Display the primes
100 FOR n=2 TO z: IF h$(n)=0: PRINT n;", ";
</syntaxhighlight>
 
====2i wheel emulation of Sinclair ZX81 BASIC====
Backward-compatible also on Spectrums, as well as 1K ZX81s for all primes < Z=441. N.B. the <code>STEP</code> of 2 in line 40 mitigates line 50's inefficiency when going to 90. <syntaxhighlight lang="qbasic">
10 INPUT Z
15 LET L=SQR(Z)
30 LET H$="10"
32 FOR J=3 TO Z STEP 2
34 LET H$=H$ & "01"
36 NEXT J
40 FOR I=3 TO L STEP 2
50 IF H$(I)="1" THEN GOTO 90
60 FOR J=I*I TO Z STEP I+I
70 LET H$(J)="1"
80 NEXT J
90 NEXT I
110 FOR I=2 TO Z
120 IF H$(I)="0" THEN PRINT I!
130 NEXT I
</syntaxhighlight>
 
====2i wheel emulation of Sinclair ZX80 BASIC====
. . . with 2:1 compression (of 16-bit integer variables on ZX80s) such that it obviates having to account for any multiple of 2; one has to input odd upper limits on factors to be squared, <code>L</code> (=21 at most on 1K ZX80s for all primes till 439).
Backward-compatible on ZX80s after substituting ** for ^ in line 120.<syntaxhighlight lang="qbasic">
10 INPUT L
15 LET Z=(L+1)*(L- 1)/2
30 DIM H(Z)
40 FOR I=3 TO L STEP 2
50 IF H((I-1)/ 2) THEN GOTO 90
60 FOR J=I*I TO L*L STEP I+I
70 LET H((J-1)/ 2)=1
80 NEXT J
90 NEXT I
110 FOR I=0 TO Z
120 IF NOT H(I) THEN PRINT 0^I+1+I*2!
130 NEXT I
</syntaxhighlight>
 
====Sieve of Sundaram====
Objections that the latter emulation has strayed far from the given task are obviously justified. Yet not as obvious is that we are now
just a slight transformation away from the Sieve of Sundaram, as transformed as follows: <code>O</code> is the highest value for an Index of succesive diagonal elements in Sundaram's matrix, for which H(J) also includes the off-diagonal elements in-between, such that
duplicate entries are omitted. Thus, a slightly transformed Sieve of Sundaram is what Eratosthenes' Sieve becomes upon applying all
optimisations incorporated into the prior entries for QL SuperBASIC, except for any equivalent to line 50 in them.
Backward-compatible on 1K ZX80s for all primes < 441 (O=10) after substituting ** for ^ in line 120.<syntaxhighlight lang="qbasic">
10 INPUT O
15 LET Z=2*O*O+O*2
30 DIM H(Z)
40 FOR I=1 TO O
45 LET A=2*I*I+I*2
50 REM IF H(A) THEN GOTO 90
60 FOR J=A TO Z STEP 1+I*2
65 REM IF H(J) THEN GOTO 80
70 LET H(J)=1
80 NEXT J
90 NEXT I
110 FOR I=0 TO Z
120 IF NOT H(I) THEN PRINT 0^I+1+I*2!
130 NEXT I
</syntaxhighlight>
 
====Eulerian optimisation====
While slower than the optimised Sieve of Eratosthenes before it, the Sieve of Sundaram above has a compatible compression scheme that's more convenient than the conventional one used beforehand. It is therefore applied below along with Euler's alternative optimisation in a reversed implementation that lacks backward-compatibility to ZX80 BASIC. This program is designed around features & limitations of the QL, yet can be rewritten more efficiently for 1K ZX80s, as they allow integer variables to be parameters of <code>FOR</code> statements (& as their 1K of static RAM is equivalent to L1 cache, even in <code>FAST</code> mode). That's left as an exercise for ZX80 enthusiasts, who for o%=14 should be able to generate all primes < 841, i.e. 3 orders of (base 2) magnitude above the limit for the program listed under Sinclair ZX81 BASIC. In QL SuperBASIC, o% may at most be 127--generating all primes < 65,025 (almost 2x the upper limit for indices & integer variables used to calculate them ~2x faster than for floating point as used in line 30, after which the integer code mimics an assembly algorithm for the QL's 68008.)
<syntaxhighlight lang="qbasic">
10 INPUT "Enter highest value of diagonal index q%: ";o%
15 LET z%=o%*(2+o%*2) : h$=FILL$(" ",z%+o%) : q%=1 : q=q% : m=z% DIV (2*q%+1)
30 FOR p=m TO q STEP -1: h$((2*q+1)*p+q)="1"
42 GOTO 87
61 IF h$(p%)="1": GOTO 63
62 IF p%<q%: GOTO 87 : ELSE h$((2*q%+1)*p%+q%)="1"
63 LET p%=p%-1 : GOTO 61
87 LET q%=q%+1 : IF h$(q%)="1": GOTO 87
90 LET p%=z% DIV (2*q%+1) : IF q%<=o%: GOTO 61
100 LET z%=z%-1 : IF z%=0: PRINT N%(z%) : STOP
101 IF h$(z%)=" ": PRINT N%(z%)!
110 GOTO 100
127 DEF FN N%(i)=0^i+1+i*2
</syntaxhighlight>
 
=={{header|Batch File}}==
<langsyntaxhighlight lang="dos">:: Sieve of Eratosthenes for Rosetta Code - PG
@echo off
setlocal ENABLEDELAYEDEXPANSION
Line 1,252 ⟶ 2,024:
if !crible.%%i! EQU 1 echo %%i
)
pause</langsyntaxhighlight>
{{Out}}
<pre style="height:20ex">limit: 100
Line 1,280 ⟶ 2,052:
89
97</pre>
 
=={{header|BBC BASIC}}==
<syntaxhighlight lang="bbcbasic"> limit% = 100000
DIM sieve% limit%
prime% = 2
WHILE prime%^2 < limit%
FOR I% = prime%*2 TO limit% STEP prime%
sieve%?I% = 1
NEXT
REPEAT prime% += 1 : UNTIL sieve%?prime%=0
ENDWHILE
REM Display the primes:
FOR I% = 1 TO limit%
IF sieve%?I% = 0 PRINT I%;
NEXT</syntaxhighlight>
 
=={{header|BCPL}}==
<syntaxhighlight lang="bcpl">get "libhdr"
 
manifest $( LIMIT = 1000 $)
 
let sieve(prime,max) be
$( let i = 2
0!prime := false
1!prime := false
for i = 2 to max do i!prime := true
while i*i <= max do
$( if i!prime do
$( let j = i*i
while j <= max do
$( j!prime := false
j := j + i
$)
$)
i := i + 1
$)
$)
 
let start() be
$( let prime = vec LIMIT
let col = 0
sieve(prime, LIMIT)
for i = 2 to LIMIT do
if i!prime do
$( writef("%I4",i)
col := col + 1
if col rem 20 = 0 then wrch('*N')
$)
wrch('*N')
$)</syntaxhighlight>
{{out}}
<pre> 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 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281
283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409
419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541
547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659
661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809
811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941
947 953 967 971 977 983 991 997</pre>
=== Odds-only bit packed array version (64 bit) ===
This sieve also uses an iterator structure to enumerate the primes in the sieve. It's inspired by the golang bit packed sieve that returns a closure as an iterator. However, BCPL does not support closures, so the code uses an iterator object.
<syntaxhighlight lang="bcpl">
GET "libhdr"
 
LET lowbit(n) =
0 -> -1,
VALOF {
// The table is byte packed to conserve space; therefore we must
// unpack the structure.
//
LET deBruijn64 = TABLE
#x0001300239311C03, #x3D3A322A261D1104,
#x3E373B2435332B16, #x2D27211E18120C05,
#x3F2F381B3C292510, #x362334152C20170B,
#x2E1A280F22141F0A, #x190E13090D080706
 
LET x6 = (n & -n) * #x3F79D71B4CB0A89 >> 58
RESULTIS deBruijn64[x6 >> 3] >> (7 - (x6 & 7) << 3) & #xFF
}
 
LET primes_upto(limit) =
limit < 3 -> 0,
VALOF {
LET bit_sz = (limit + 1) / 2 - 1
LET bit, p = ?, ?
LET q, r = bit_sz >> 6, bit_sz & #x3F
LET sz = q - (r > 0)
LET sieve = getvec(sz)
 
// Initialize the array
FOR i = 0 TO q - 1 DO
sieve!i := -1
IF r > 0 THEN sieve!q := ~(-1 << r)
sieve!sz := -1 // Sentinel value to mark the end -
// (after sieving, we'll never have 64 consecutive odd primes.)
 
// run the sieve
bit := 0
{
WHILE (sieve[bit >> 6] & 1 << (bit & #x3F)) = 0 DO
bit +:= 1
p := 2*bit + 3
q := p*p
IF q > limit THEN RESULTIS sieve
r := (q - 3) >> 1
UNTIL r >= bit_sz DO {
sieve[r >> 6] &:= ~(1 << (r & #x3F))
r +:= p
}
bit +:= 1
} REPEAT
}
 
MANIFEST { // fields in an iterable
sieve_start; sieve_bits; sieve_ptr
}
 
LET prime_iter(sieve) = VALOF {
LET iter = getvec(2)
iter!sieve_start := 0
iter!sieve_bits := sieve!0
iter!sieve_ptr := sieve
RESULTIS iter
}
 
LET nextprime(iter) =
!iter!sieve_ptr = -1 -> 0, // guard entry if at the end already
VALOF {
LET p, x = ?, ?
 
// iter!sieve_start is also a flag to yield 2.
IF iter!sieve_start = 0 {
iter!sieve_start := 3
RESULTIS 2
}
x := iter!sieve_bits
{
TEST x ~= 0
THEN {
p := (lowbit(x) << 1) + iter!sieve_start
x &:= x - 1
iter!sieve_bits := x
RESULTIS p
}
ELSE {
iter!sieve_start +:= 128
iter!sieve_ptr +:= 1
x := !iter!sieve_ptr
IF x = -1 RESULTIS 0
}
} REPEAT
}
 
LET show(sieve) BE {
LET iter = prime_iter(sieve)
LET c, p = 0, ?
{
p := nextprime(iter)
IF p = 0 THEN {
wrch('*n')
freevec(iter)
RETURN
}
IF c MOD 10 = 0 THEN wrch('*n')
c +:= 1
writef("%8d", p)
} REPEAT
}
 
LET start() = VALOF {
LET n = ?
LET argv = VEC 20
LET sz = ?
LET primes = ?
 
sz := rdargs("upto/a/n/p", argv, 20)
IF sz = 0 RESULTIS 1
n := !argv!0
primes := primes_upto(n)
IF primes = 0 RESULTIS 1 // no array allocated because limit too small
show(primes)
freevec(primes)
RESULTIS 0
}
</syntaxhighlight>
{{Out}}
<pre>
$ ./sieve 1000
 
BCPL 64-bit Cintcode System (13 Jan 2020)
0.000>
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 101 103 107 109 113
127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229
233 239 241 251 257 263 269 271 277 281
283 293 307 311 313 317 331 337 347 349
353 359 367 373 379 383 389 397 401 409
419 421 431 433 439 443 449 457 461 463
467 479 487 491 499 503 509 521 523 541
547 557 563 569 571 577 587 593 599 601
607 613 617 619 631 641 643 647 653 659
661 673 677 683 691 701 709 719 727 733
739 743 751 757 761 769 773 787 797 809
811 821 823 827 829 839 853 857 859 863
877 881 883 887 907 911 919 929 937 941
947 953 967 971 977 983 991 997
0.005>
</pre>
 
=={{header|Befunge}}==
Line 1,286 ⟶ 2,271:
@ ^ p3\" ":<
2 234567890123456789012345678901234567890123456789012345678901234567890123456789
 
=={{header|Binary Lambda Calculus}}==
 
The BLC sieve of Eratosthenes as documented at https://github.com/tromp/AIT/blob/master/characteristic_sequences/primes.lam is the 167 bit program
 
<pre>00010001100110010100011010000000010110000010010001010111110111101001000110100001110011010000000000101101110011100111111101111000000001111100110111000000101100000110110</pre>
 
The infinitely long output is
 
<pre>001101010001010001010001000001010000010001010001000001000001010000010001010000010001000001000000010001010001010001000000000000010001000001010000000001010000010000010001000001000001010000000001010001010000000000010000000000010001010001000001010000000001000001000001000001010000010001010000000001000000000000010001010001000000000000010000010000000001010001000001000...</pre>
 
=={{header|BQN}}==
 
A more efficient sieve (primes below one billion in under a minute) is provided as <code>PrimesTo</code> in bqn-libs [https://github.com/mlochbaum/bqn-libs/blob/master/primes.bqn primes.bqn].
 
<syntaxhighlight lang="bqn">Primes ← {
𝕩≤2 ? ↕0 ; # No primes below 2
p ← 𝕊⌈√n←𝕩 # Initial primes by recursion
b ← 2≤↕n # Initial sieve: no 0 or 1
E ← {↕∘⌈⌾((𝕩×𝕩+⊢)⁼)n} # Multiples of 𝕩 under n, starting at 𝕩×𝕩
/ b E⊸{0¨⌾(𝕨⊸⊏)𝕩}´ p # Cross them out
}</syntaxhighlight>
 
{{out}}
<syntaxhighlight lang="bqn"> Primes 100
⟨ 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 ⟩
≠∘Primes¨ 10⋆↕7 # Number of primes below 1e0, 1e1, ... 1e6
⟨ 0 4 25 168 1229 9592 78498 ⟩</syntaxhighlight>
 
=={{header|Bracmat}}==
This solution does not use an array. Instead, numbers themselves are used as variables. The numbers that are not prime are set (to the silly value "nonprime"). Finally all numbers up to the limit are tested for being initialised. The uninitialised (unset) ones must be the primes.
<langsyntaxhighlight lang="bracmat">( ( eratosthenes
= n j i
. !arg:?n
Line 1,310 ⟶ 2,323:
)
& eratosthenes$100
)</langsyntaxhighlight>
{{out}}
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
 
=={{header|C}}==
Plain sieve, without any optimizations:<langsyntaxhighlight lang="c">#include <stdlib.h>
#include <math.h>
 
Line 1,342 ⟶ 2,355:
}
return sieve;
}</langsyntaxhighlight>Possible optimizations include sieving only odd numbers (or more complex wheels), packing the sieve into bits to improve locality (and allow larger sieves), etc.
 
'''Another example:'''
Line 1,349 ⟶ 2,362:
Then, in a loop, fill zeroes into those places where i * j is less than or equal to n (number of primes requested), which means they have multiples!
To understand this better, look at the output of the following example.
To print this back, we look for ones in the array and only print those spots. <langsyntaxhighlight Clang="c">#include <stdio.h>
#include <malloc.h>
void sieve(int *, int);
Line 1,387 ⟶ 2,400:
}
printf("\n\n");
}</langsyntaxhighlight>{{out}}<syntaxhighlight lang Shell="shell">i:2
j:2
Before a[2*2]: 1
Line 1,411 ⟶ 2,424:
i:9
i:10
Primes numbers from 1 to 10 are : 2, 3, 5, 7, </langsyntaxhighlight>
 
=={{header|C++}}==
===Standard Library===
 
This implementation follows the standard library pattern of [http://en.cppreference.com/w/cpp/algorithm/iota std::iota]. The start and end iterators are provided for the container. The destination container is used for marking primes and then filled with the primes which are less than the container size. This method requires no memory allocation inside the function.
 
<lang cpp>#include <iostream>
#include <algorithm>
#include <vector>
 
// requires Iterator satisfies RandomAccessIterator
template <typename Iterator>
size_t prime_sieve(Iterator start, Iterator end)
{
if (start == end) return 0;
// clear the container with 0
std::fill(start, end, 0);
// mark composites with 1
for (Iterator prime_it = start + 1; prime_it != end; ++prime_it)
{
if (*prime_it == 1) continue;
// determine the prime number represented by this iterator location
size_t stride = (prime_it - start) + 1;
// mark all multiples of this prime number up to max
Iterator mark_it = prime_it;
while ((end - mark_it) > stride)
{
std::advance(mark_it, stride);
*mark_it = 1;
}
}
// copy marked primes into container
Iterator out_it = start;
for (Iterator it = start + 1; it != end; ++it)
{
if (*it == 0)
{
*out_it = (it - start) + 1;
++out_it;
}
}
return out_it - start;
}
 
int main(int argc, const char* argv[])
{
std::vector<int> primes(100);
size_t count = prime_sieve(primes.begin(), primes.end());
// display the primes
for (size_t i = 0; i < count; ++i)
std::cout << primes[i] << " ";
std::cout << std::endl;
return 1;
}</lang>
 
=== Boost ===
 
<lang cpp>// yield all prime numbers less than limit.
template<class UnaryFunction>
void primesupto(int limit, UnaryFunction yield)
{
std::vector<bool> is_prime(limit, true);
const int sqrt_limit = static_cast<int>(std::sqrt(limit));
for (int n = 2; n <= sqrt_limit; ++n)
if (is_prime[n]) {
yield(n);
 
for (unsigned k = n*n, ulim = static_cast<unsigned>(limit); k < ulim; k += n)
//NOTE: "unsigned" is used to avoid an overflow in `k+=n` for `limit` near INT_MAX
is_prime[k] = false;
}
 
for (int n = sqrt_limit + 1; n < limit; ++n)
if (is_prime[n])
yield(n);
}</lang>
 
Full program:
 
{{works with|Boost}}<lang cpp>/**
$ g++ -I/path/to/boost sieve.cpp -o sieve && sieve 10000000
*/
#include <inttypes.h> // uintmax_t
#include <limits>
#include <cmath>
#include <iostream>
#include <sstream>
#include <vector>
 
#include <boost/lambda/lambda.hpp>
 
int main(int argc, char *argv[])
{
using namespace std;
using namespace boost::lambda;
 
int limit = 10000;
if (argc == 2) {
stringstream ss(argv[--argc]);
ss >> limit;
 
if (limit < 1 or ss.fail()) {
cerr << "USAGE:\n sieve LIMIT\n\nwhere LIMIT in the range [1, "
<< numeric_limits<int>::max() << ")" << endl;
return 2;
}
}
 
// print primes less then 100
primesupto(100, cout << _1 << " ");
cout << endl;
 
// find number of primes less then limit and their sum
int count = 0;
uintmax_t sum = 0;
primesupto(limit, (var(sum) += _1, var(count) += 1));
 
cout << "limit sum pi(n)\n"
<< limit << " " << sum << " " << count << endl;
}</lang>
 
=={{header|C sharp|C#}}==
{{works with|C sharp|C#|2.0+}}
<langsyntaxhighlight lang="csharp">using System;
using System.Collections;
using System.Collections.Generic;
Line 1,579 ⟶ 2,471:
}
}
}</langsyntaxhighlight>
 
===UnboundedRichard Bird Sieve===
 
'''Richard Bird Sieve'''
 
{{trans|F#}}
 
To show that C# code can be written in somewhat functional paradigms, the following in an implementation of the Richard Bird sieve from the Epilogue of [Melissa E. O'Neill's definitive article](http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf) in Haskell:
<langsyntaxhighlight lang="csharp">using System;
using System.Collections;
using System.Collections.Generic;
Line 1,628 ⟶ 2,518:
}
IEnumerator IEnumerable.GetEnumerator() { return (IEnumerator)GetEnumerator(); }
}</langsyntaxhighlight>
 
'''===Tree Folding Sieve'''===
 
{{trans|F#}}
 
The above code can easily be converted to "'''odds-only'''" and a infinite tree-like folding scheme with the following minor changes:
<langsyntaxhighlight lang="csharp">using System;
using System.Collections;
using System.Collections.Generic;
Line 1,683 ⟶ 2,573:
}
IEnumerator IEnumerable.GetEnumerator() { return (IEnumerator)GetEnumerator(); }
}</langsyntaxhighlight>
 
The above code runs over ten times faster than the original Richard Bird algorithm.
 
'''===Priority Queue Sieve'''===
 
{{trans|F#}}
 
First, an implementation of a Min Heap Priority Queue is provided as extracted from the entry at [http://rosettacode.org/wiki/Priority_queue#C.23 RosettaCode], with only the necessary methods duplicated here:
<langsyntaxhighlight lang="csharp">namespace PriorityQ {
using KeyT = System.UInt32;
using System;
Line 1,749 ⟶ 2,639:
public static MinHeapPQ<V> replaceMin(KeyT k, V v, MinHeapPQ<V> pq) {
pq.rplcmin(k, v); return pq; }
}</langsyntaxhighlight>
 
 
===Restricted Base Primes Queue===
 
The following code implements an improved version of the '''odds-only''' O'Neil algorithm, which provides the improvements of only adding base prime composite number streams to the queue when the sieved number reaches the square of the base prime (saving a huge amount of memory and considerable execution time, including not needing as wide a range of a type for the internal prime numbers) as well as minimizing stream processing using fusion:
 
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;
using System.Collections;
using System.Collections.Generic;
Line 1,787 ⟶ 2,681:
public IEnumerator<PrimeT> GetEnumerator() { return nmrtr(); }
IEnumerator IEnumerable.GetEnumerator() { return (IEnumerator)GetEnumerator(); }
}</langsyntaxhighlight>
 
The above code is at least about 2.5 times faster than the Tree Folding version.
 
 
'''Dictionary (Hash table) Sieve'''
===Dictionary (Hash table) Sieve===
 
The above code adds quite a bit of overhead in having to provide a version of a Priority Queue for little advantage over a Dictionary (hash table based) version as per the code below:
 
<lang csharp>using System;
<syntaxhighlight lang="csharp">using System;
using System.Collections;
using System.Collections.Generic;
Line 1,827 ⟶ 2,723:
public IEnumerator<PrimeT> GetEnumerator() { return nmrtr(); }
IEnumerator IEnumerable.GetEnumerator() { return (IEnumerator)GetEnumerator(); }
}</langsyntaxhighlight>
 
The above code runs in about three quarters of the time as the above Priority Queue based version for a range of a million primes which will fall even further behind for increasing ranges due to the Dictionary providing O(1) access times as compared to the O(log n) access times for the Priority Queue; the only slight advantage of the PQ based version is at very small ranges where the constant factor overhead of computing the table hashes becomes greater than the "log n" factor for small "n".
 
===Best performance: CPU-Cache-Optimized Segmented Sieve===
'''Page Segmented Array Sieve'''
 
All of the above unbounded versions are really just an intellectual exercise as with very little extra lines of code above the fastest Dictionary based version, one can have an bit-packed page-segmented array based version as follows:
<langsyntaxhighlight lang="csharp">using System;
using System.Collections;
using System.Collections.Generic;
Line 1,890 ⟶ 2,786:
public IEnumerator<PrimeT> GetEnumerator() { return nmrtr(); }
IEnumerator IEnumerable.GetEnumerator() { return (IEnumerator)GetEnumerator(); }
}</langsyntaxhighlight>
 
The above code is about 25 times faster than the Dictionary version at computing the first about 50 million primes (up to a range of one billion), with the actual enumeration of the result sequence now taking longer than the time it takes to cull the composite number representation bits from the arrays, meaning that it is over 50 times faster at actually sieving the primes. The code owes its speed as compared to a naive "one huge memory array" algorithm to using an array size that is the size of the CPU L1 or L2 caches and using bit-packing to fit more number representations into this limited capacity; in this way RAM memory access times are reduced by a factor of from about four to about 10 (depending on CPU and RAM speed) as compared to those naive implementations, and the minor computational cost of the bit manipulations is compensated by a large factor in total execution time.
 
The time to enumerate the result primes sequence can be reduced somewhat (about a second) by removing the automatic iterator "yield return" statements and converting them into a "rullroll-your-own" IEnumerable<PrimeT> implementation, but for page segmentation of '''odds-only''', this iteration of the results will still take longer than the time to actually cull the composite numbers from the page arrays.
 
In order to make further gains in speed, custom methods must be used to avoid using iterator sequences. If this is done, then further gains can be made by extreme wheel factorization (up to about another about four times gain in speed) and multi-processing (with another gain in speed proportional to the actual independent CPU cores used).
Line 1,901 ⟶ 2,797:
 
All of the above unbounded code can be tested by the following "main" method (replace the name "PrimesXXX" with the name of the class to be tested):
<langsyntaxhighlight lang="csharp"> static void Main(string[] args) {
Console.WriteLine(new PrimesXXX().ElementAt(1000000 - 1)); // zero based indexing...
}</langsyntaxhighlight>
 
To produce the following output for all tested versions (although some are considerably faster than others):
{{output}}
<pre>15485863</pre>
 
=={{header|C++}}==
===Standard Library===
 
This implementation follows the standard library pattern of [http://en.cppreference.com/w/cpp/algorithm/iota std::iota]. The start and end iterators are provided for the container. The destination container is used for marking primes and then filled with the primes which are less than the container size. This method requires no memory allocation inside the function.
 
<syntaxhighlight lang="cpp">#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
 
// Fills the range [start, end) with 1 if the integer corresponding to the index is composite and 0 otherwise.
// requires: I is RandomAccessIterator
template<typename I>
void mark_composites(I start, I end)
{
std::fill(start, end, 0);
 
for (auto it = start + 1; it != end; ++it)
{
if (*it == 0)
{
auto prime = std::distance(start, it) + 1;
// mark all multiples of this prime number as composite.
auto multiple_it = it;
while (std::distance(multiple_it, end) > prime)
{
std::advance(multiple_it, prime);
*multiple_it = 1;
}
}
}
}
 
// Fills "out" with the prime numbers in the range 2...N where N = distance(start, end).
// requires: I is a RandomAccessIterator
// O is an OutputIterator
template <typename I, typename O>
O sieve_primes(I start, I end, O out)
{
mark_composites(start, end);
for (auto it = start + 1; it != end; ++it)
{
if (*it == 0)
{
*out = std::distance(start, it) + 1;
++out;
}
}
return out;
}
 
int main()
{
std::vector<uint8_t> is_composite(1000);
sieve_primes(is_composite.begin(), is_composite.end(), std::ostream_iterator<int>(std::cout, " "));
 
// Alternative to store in a vector:
// std::vector<int> primes;
// sieve_primes(is_composite.begin(), is_composite.end(), std::back_inserter(primes));
}
</syntaxhighlight>
 
=== Boost ===
 
<syntaxhighlight lang="cpp">// yield all prime numbers less than limit.
template<class UnaryFunction>
void primesupto(int limit, UnaryFunction yield)
{
std::vector<bool> is_prime(limit, true);
const int sqrt_limit = static_cast<int>(std::sqrt(limit));
for (int n = 2; n <= sqrt_limit; ++n)
if (is_prime[n]) {
yield(n);
 
for (unsigned k = n*n, ulim = static_cast<unsigned>(limit); k < ulim; k += n)
//NOTE: "unsigned" is used to avoid an overflow in `k+=n` for `limit` near INT_MAX
is_prime[k] = false;
}
 
for (int n = sqrt_limit + 1; n < limit; ++n)
if (is_prime[n])
yield(n);
}</syntaxhighlight>
 
Full program:
 
{{works with|Boost}}<syntaxhighlight lang="cpp">/**
$ g++ -I/path/to/boost sieve.cpp -o sieve && sieve 10000000
*/
#include <inttypes.h> // uintmax_t
#include <limits>
#include <cmath>
#include <iostream>
#include <sstream>
#include <vector>
 
#include <boost/lambda/lambda.hpp>
 
int main(int argc, char *argv[])
{
using namespace std;
using namespace boost::lambda;
 
int limit = 10000;
if (argc == 2) {
stringstream ss(argv[--argc]);
ss >> limit;
 
if (limit < 1 or ss.fail()) {
cerr << "USAGE:\n sieve LIMIT\n\nwhere LIMIT in the range [1, "
<< numeric_limits<int>::max() << ")" << endl;
return 2;
}
}
 
// print primes less then 100
primesupto(100, cout << _1 << " ");
cout << endl;
 
// find number of primes less then limit and their sum
int count = 0;
uintmax_t sum = 0;
primesupto(limit, (var(sum) += _1, var(count) += 1));
 
cout << "limit sum pi(n)\n"
<< limit << " " << sum << " " << count << endl;
}</syntaxhighlight>
 
=={{header|Chapel}}==
{{incorrect|Chapel|Doesn't compile since at least Chapel version 1.20 to 1.24.1.}}
This solution uses nested iterators to create new wheels at run time:
<langsyntaxhighlight lang="chapel">// yield prime and remove all multiples of it from children sieves
iter sieve(prime):int {
 
Line 1,921 ⟶ 2,947:
 
// candidate is a multiple of this prime
if composite == candidate then {
// remember size of last composite
last = composite;
Line 1,933 ⟶ 2,959:
yield candidate;
}
}</langsyntaxhighlight>The topmost sieve needs to be started with 2 (the smallest prime):
<langsyntaxhighlight lang="chapel">config const N = 30;
for p in sieve(2) {
write(" ",if p); > N {
if p > N then {
writeln();
break;
}
write(" ", p);
}</lang>
}</syntaxhighlight>
 
===Alternate Conventional Bit-Packed Implementation===
 
The following code implements the conventional monolithic (one large array) Sieve of Eratosthenes where the representations of the numbers use only one bit per number, using an iteration for output so as to not require further memory allocation:
 
compile with the `--fast` option
 
<syntaxhighlight lang="chapel">use Time;
use BitOps;
 
type Prime = uint(32);
 
config const limit: Prime = 1000000000; // sieve limit
 
proc main() {
write("The first 25 primes are: ");
for p in primes(100) do write(p, " "); writeln();
var count = 0; for p in primes(1000000) do count += 1;
writeln("Count of primes to a million is: ", count, ".");
var timer: Timer;
timer.start();
 
count = 0;
for p in primes(limit) do count += 1;
 
timer.stop();
write("Found ", count, " primes up to ", limit);
writeln(" in ", timer.elapsed(TimeUnits.milliseconds), " milliseconds.");
}
 
iter primes(n: Prime): Prime {
const szlmt = n / 8;
var cmpsts: [0 .. szlmt] uint(8); // even number of byte array rounded up
 
for bp in 2 .. n {
if cmpsts[bp >> 3] & (1: uint(8) << (bp & 7)) == 0 {
const s0 = bp * bp;
if s0 > n then break;
for c in s0 .. n by bp { cmpsts[c >> 3] |= 1: uint(8) << (c & 7); }
}
}
 
for p in 2 .. n do if cmpsts[p >> 3] & (1: uint(8) << (p & 7)) == 0 then yield p;
 
}</syntaxhighlight>
 
{{out}}
 
<pre>The first 25 primes are: 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
Count of primes to a million is: 78498.
Found 50847534 primes up to 1000000000 in 7964.05 milliseconds.</pre>
 
Time as run using Chapel version 24.1 on an Intel Skylake i5-6500 at 3.6 GHz (turbo, single threaded).
 
===Alternate Odds-Only Bit-Packed Implementation===
 
<syntaxhighlight lang="chapel">use Time;
use BitOps;
 
type Prime = int(32);
 
config const limit: Prime = 1000000000; // sieve limit
 
proc main() {
write("The first 25 primes are: ");
for p in primes(100) do write(p, " "); writeln();
var count = 0; for p in primes(1000000) do count += 1;
writeln("Count of primes to a million is: ", count, ".");
var timer: Timer;
timer.start();
 
count = 0;
for p in primes(limit) do count += 1;
 
timer.stop();
write("Found ", count, " primes up to ", limit);
writeln(" in ", timer.elapsed(TimeUnits.milliseconds), " milliseconds.");
}
 
iter primes(n: Prime): Prime {
const ndxlmt = (n - 3) / 2;
const szlmt = ndxlmt / 8;
var cmpsts: [0 .. szlmt] uint(8); // even number of byte array rounded up
 
for i in 0 .. ndxlmt { // never gets to the end!
if cmpsts[i >> 3] & (1: uint(8) << (i & 7)) == 0 {
const bp = i + i + 3;
const s0 = (bp * bp - 3) / 2;
if s0 > ndxlmt then break;
for s in s0 .. ndxlmt by bp do cmpsts[s >> 3] |= 1: uint(8) << (s & 7);
}
}
 
yield 2;
for i in 0 .. ndxlmt do
if cmpsts[i >> 3] & (1: uint(8) << (i & 7)) == 0 then yield i + i + 3;
 
}</syntaxhighlight>
 
{{out}}
 
<pre>The first 25 primes are: 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
Count of primes to a million is: 78498.
Found 50847534 primes up to 1000000000 in 4008.16 milliseconds.</pre>
 
Time as run using Chapel version 24.1 on an Intel Skylake i5-6500 at 3.6 GHz (turbo, single threaded).
 
As you can see, sieving odds-only is about twice as fast due to the reduced number of operations; it also uses only half the amount of memory. However, this is still not all that fast at about 14.4 CPU clock cycles per sieve culling operation due to the size of the array exceeding the CPU cache size(s).
 
===Hash Table Based Odds-Only Version===
 
{{trans|Python}} [https://rosettacode.org/wiki/Sieve_of_Eratosthenes#Infinite_generator_with_a_faster_algorithm code link]
{{works with|Chapel|1.25.1}}
 
<syntaxhighlight lang="chapel">use Time;
 
config const limit = 100000000;
 
type Prime = uint(32);
 
class Primes { // needed so we can use next to get successive values
var n: Prime; var obp: Prime; var q: Prime;
var bps: owned Primes?;
var keys: domain(Prime); var dict: [keys] Prime;
proc next(): Prime { // odd primes!
if this.n < 5 { this.n = 5; return 3; }
if this.bps == nil {
this.bps = new Primes(); // secondary odd base primes feed
this.obp = this.bps!.next(); this.q = this.obp * this.obp;
}
while true {
if this.n >= this.q { // advance secondary stream of base primes...
const adv = this.obp * 2; const key = this.q + adv;
this.obp = this.bps!.next(); this.q = this.obp * this.obp;
this.keys += key; this.dict[key] = adv;
}
else if this.keys.contains(this.n) { // found a composite; advance...
const adv = this.dict[this.n]; this.keys.remove(this.n);
var nkey = this.n + adv;
while this.keys.contains(nkey) do nkey += adv;
this.keys += nkey; this.dict[nkey] = adv;
}
else { const p = this.n; this.n += 2; return p; }
this.n += 2;
}
return 0; // to keep compiler happy in returning a value!
}
iter these(): Prime { yield 2; while true do yield this.next(); }
}
 
proc main() {
var count = 0;
write("The first 25 primes are: ");
for p in new Primes() { if count >= 25 then break; write(p, " "); count += 1; }
writeln();
var timer: Timer;
timer.start();
 
count = 0;
for p in new Primes() { if p > limit then break; count += 1; }
 
timer.stop();
write("Found ", count, " primes up to ", limit);
writeln(" in ", timer.elapsed(TimeUnits.milliseconds), " milliseconds.");
}</syntaxhighlight>
 
{{out}}
 
<pre>The first 25 primes are: 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
Found 5761455 primes up to 100000000 in 5195.41 milliseconds.</pre>
 
Time as run using Chapel version 24.1 on an Intel Skylake i5-6500 at 3.6 GHz (turbo, single threaded).
 
As you can see, this is much slower than the array based versions but much faster than previous Chapel version code as the hashing has been greatly improved.
 
As an alternate to the use of a built-in library, the following code implements a specialized BasePrimesTable that works similarly to the way the Python associative arrays work as to hashing algorithm used (no hashing, as the hash values for integers are just themselves) and something similar to the Python method of handling hash table collisions is used:
 
{{works with|Chapel|1.25.1}}
Compile with the `--fast` compiler command line option
 
<syntaxhighlight lang="chapel">use Time;
config const limit = 100000000;
type Prime = uint(32);
 
record BasePrimesTable { // specialized for the use here...
record BasePrimeEntry { var fullkey: Prime; var val: Prime; }
var cpcty: int = 8; var sz: int = 0;
var dom = { 0 .. cpcty - 1 }; var bpa: [dom] BasePrimeEntry;
proc grow() {
const ndom = dom; var cbpa: [ndom] BasePrimeEntry = bpa[ndom];
bpa = new BasePrimeEntry(); cpcty *= 2; dom = { 0 .. cpcty - 1 };
for kv in cbpa do if kv.fullkey != 0 then add(kv.fullkey, kv.val);
}
proc find(k: Prime): int { // internal get location of value or -1
const msk = cpcty - 1; var skey = k: int & msk;
var perturb = k: int; var loop = 8;
do {
if bpa[skey].fullkey == k then return skey;
perturb >>= 5; skey = (5 * skey + 1 + perturb) & msk;
loop -= 1; if perturb > 0 then loop = 8;
} while loop > 0;
return -1; // not found!
}
proc contains(k: Prime): bool { return find(k) >= 0; }
proc add(k, v: Prime) { // if exists then replaces else new entry
const fndi = find(k);
if fndi >= 0 then bpa[fndi] = new BasePrimeEntry(k, v);
else {
sz += 1; if 2 * sz > cpcty then grow();
const msk = cpcty - 1; var skey = k: int & msk;
var perturb = k: int; var loop = 8;
do {
if bpa[skey].fullkey == 0 {
bpa[skey] = new BasePrimeEntry(k, v); return; }
perturb >>= 5; skey = (5 * skey + 1 + perturb) & msk;
loop -= 1; if perturb > 0 then loop = 8;
} while loop > 0;
}
}
proc remove(k: Prime) { // if doesn't exist does nothing
const fndi = find(k);
if fndi >= 0 { bpa[fndi].fullkey = 0; sz -= 1; }
}
proc this(k: Prime): Prime { // returns value or 0 if not found
const fndi = find(k);
if fndi < 0 then return 0; else return bpa[fndi].val;
}
}
 
class Primes { // needed so we can use next to get successive values
var n: Prime; var obp: Prime; var q: Prime;
var bps: shared Primes?; var dict = new BasePrimesTable();
proc next(): Prime { // odd primes!
if this.n < 5 { this.n = 5; return 3; }
if this.bps == nil {
this.bps = new Primes(); // secondary odd base primes feed
this.obp = this.bps!.next(); this.q = this.obp * this.obp;
}
while true {
if this.n >= this.q { // advance secondary stream of base primes...
const adv = this.obp * 2; const key = this.q + adv;
this.obp = this.bps!.next(); this.q = this.obp * this.obp;
this.dict.add(key, adv);
}
else if this.dict.contains(this.n) { // found a composite; advance...
const adv = this.dict[this.n]; this.dict.remove(this.n);
var nkey = this.n + adv;
while this.dict.contains(nkey) do nkey += adv;
this.dict.add(nkey, adv);
}
else { const p = this.n; this.n += 2; return p; }
this.n += 2;
}
return 0; // to keep compiler happy in returning a value!
}
iter these(): Prime { yield 2; while true do yield this.next(); }
}
 
proc main() {
var count = 0;
write("The first 25 primes are: ");
for p in new Primes() { if count >= 25 then break; write(p, " "); count += 1; }
writeln();
var timer: Timer;
timer.start();
count = 0;
for p in new Primes() { if p > limit then break; count += 1; }
timer.stop();
write("Found ", count, " primes up to ", limit);
writeln(" in ", timer.elapsed(TimeUnits.milliseconds), " milliseconds.");
}</syntaxhighlight>
 
{{out}}
 
<pre>The first 25 primes are: 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
Found 5761455 primes up to 100000000 in 2351.79 milliseconds.</pre>
 
This last code is quite usable up to a hundred million (as here) or even a billion in a little over ten times the time, but is still slower than the very simple odds-only monolithic array version and is also more complex, although it uses less memory (only for the hash table for the base primes of about eight Kilobytes for sieving to a billion compared to over 60 Megabytes for the monolithic odds-only simple version).
 
Chapel version 1.25.1 provides yet another option as to the form of the code although the algorithm is the same in that one can now override the hashing function for Chapel records so that they can be used as the Key Type for Hash Map's as follows:
 
{{works with|Chapel|1.25.1}}
Compile with the `--fast` compiler command line option
 
<syntaxhighlight lang="chapel">use Time;
 
use Map;
config const limit = 100000000;
type Prime = uint(32);
class Primes { // needed so we can use next to get successive values
record PrimeR { var prime: Prime; proc hash() { return prime; } }
var n: PrimeR = new PrimeR(0); var obp: Prime; var q: Prime;
var bps: owned Primes?;
var dict = new map(PrimeR, Prime);
proc next(): Prime { // odd primes!
if this.n.prime < 5 { this.n.prime = 5; return 3; }
if this.bps == nil {
this.bps = new Primes(); // secondary odd base primes feed
this.obp = this.bps!.next(); this.q = this.obp * this.obp;
}
while true {
if this.n.prime >= this.q { // advance secondary stream of base primes...
const adv = this.obp * 2; const key = new PrimeR(this.q + adv);
this.obp = this.bps!.next(); this.q = this.obp * this.obp;
this.dict.add(key, adv);
}
else if this.dict.contains(this.n) { // found a composite; advance...
const adv = this.dict.getValue(this.n); this.dict.remove(this.n);
var nkey = new PrimeR(this.n.prime + adv);
while this.dict.contains(nkey) do nkey.prime += adv;
this.dict.add(nkey, adv);
}
else { const p = this.n.prime;
this.n.prime += 2; return p; }
this.n.prime += 2;
}
return 0; // to keep compiler happy in returning a value!
}
iter these(): Prime { yield 2; while true do yield this.next(); }
}
proc main() {
var count = 0;
write("The first 25 primes are: ");
for p in new Primes() { if count >= 25 then break; write(p, " "); count += 1; }
writeln();
var timer: Timer;
timer.start();
count = 0;
for p in new Primes() { if p > limit then break; count += 1; }
timer.stop();
write("Found ", count, " primes up to ", limit);
writeln(" in ", timer.elapsed(TimeUnits.milliseconds), " milliseconds.");
}</syntaxhighlight>
 
This works in about exactly the same time as the last previous code, but doesn't require special custom adaptations of the associative array so that the standard library Map can be used.
 
===Functional Tree Folding Odds-Only Version===
 
Chapel isn't really a very functional language even though it has some functional forms of code in the Higher Order Functions (HOF's) of zippered, scanned, and reduced, iterations and has first class functions (FCF's) and lambdas (anonymous functions), these last can't be closures (capture variable bindings from external scope(s)), nor can the work around of using classes to emulate closures handle recursive (Y-combinator type) variable bindings using reference fields (at least currently with version 1.22). However, the Tree Folding add-on to the Richard Bird lazy list sieve doesn't require any of the things that can't be emulated using classes, so a version is given as follows:
 
{{trans|Nim}} [https://rosettacode.org/wiki/Sieve_of_Eratosthenes#Nim_Unbounded_Versions code link]
{{works with|Chapel|1.22|- compile with the --fast compiler command line flag for full optimization}}
<syntaxhighlight lang="chapel">use Time;
 
type Prime = uint(32);
 
config const limit = 1000000: Prime;
 
// Chapel doesn't have closures, so we need to emulate them with classes...
class PrimeCIS { // base prime stream...
var head: Prime;
proc next(): shared PrimeCIS { return new shared PrimeCIS(); }
}
 
class PrimeMultiples: PrimeCIS {
var adv: Prime;
override proc next(): shared PrimeCIS {
return new shared PrimeMultiples(
this.head + this.adv, this.adv): shared PrimeCIS; }
}
 
class PrimeCISCIS { // base stream of prime streams; never used directly...
var head: shared PrimeCIS;
proc init() { this.head = new shared PrimeCIS(); }
proc next(): shared PrimeCISCIS {
return new shared PrimeCISCIS(); }
}
 
class AllMultiples: PrimeCISCIS {
var bps: shared PrimeCIS;
proc init(bsprms: shared PrimeCIS) {
const bp = bsprms.head; const sqr = bp * bp; const adv = bp + bp;
this.head = new shared PrimeMultiples(sqr, adv): PrimeCIS;
this.bps = bsprms;
}
override proc next(): shared PrimeCISCIS {
return new shared AllMultiples(this.bps.next()): PrimeCISCIS; }
}
 
class Union: PrimeCIS {
var feeda, feedb: shared PrimeCIS;
proc init(fda: shared PrimeCIS, fdb: shared PrimeCIS) {
const ahd = fda.head; const bhd = fdb.head;
this.head = if ahd < bhd then ahd else bhd;
this.feeda = fda; this.feedb = fdb;
}
override proc next(): shared PrimeCIS {
const ahd = this.feeda.head; const bhd = this.feedb.head;
if ahd < bhd then
return new shared Union(this.feeda.next(), this.feedb): shared PrimeCIS;
if ahd > bhd then
return new shared Union(this.feeda, this.feedb.next()): shared PrimeCIS;
return new shared Union(this.feeda.next(),
this.feedb.next()): shared PrimeCIS;
}
}
 
class Pairs: PrimeCISCIS {
var feed: shared PrimeCISCIS;
proc init(fd: shared PrimeCISCIS) {
const fs = fd.head; const sss = fd.next(); const ss = sss.head;
this.head = new shared Union(fs, ss): shared PrimeCIS; this.feed = sss;
}
override proc next(): shared PrimeCISCIS {
return new shared Pairs(this.feed.next()): shared PrimeCISCIS; }
}
 
class Composites: PrimeCIS {
var feed: shared PrimeCISCIS;
proc init(fd: shared PrimeCISCIS) {
this.head = fd.head.head; this.feed = fd;
}
override proc next(): shared PrimeCIS {
const fs = this.feed.head.next();
const prs = new shared Pairs(this.feed.next()): shared PrimeCISCIS;
const ncs = new shared Composites(prs): shared PrimeCIS;
return new shared Union(fs, ncs): shared PrimeCIS;
}
}
 
class OddPrimesFrom: PrimeCIS {
var cmpsts: shared PrimeCIS;
override proc next(): shared PrimeCIS {
var n = head + 2; var cs = this.cmpsts;
while true {
if n < cs.head then
return new shared OddPrimesFrom(n, cs): shared PrimeCIS;
n += 2; cs = cs.next();
}
return this.cmpsts; // never used; keeps compiler happy!
}
}
 
class OddPrimes: PrimeCIS {
proc init() { this.head = 3; }
override proc next(): shared PrimeCIS {
const bps = new shared OddPrimes(): shared PrimeCIS;
const mlts = new shared AllMultiples(bps): shared PrimeCISCIS;
const cmpsts = new shared Composites(mlts): shared PrimeCIS;
return new shared OddPrimesFrom(5, cmpsts): shared PrimeCIS;
}
}
 
iter primes(): Prime {
yield 2; var cur = new shared OddPrimes(): shared PrimeCIS;
while true { yield cur.head; cur = cur.next(); }
}
 
// test it...
write("The first 25 primes are: "); var cnt = 0;
for p in primes() { if cnt >= 25 then break; cnt += 1; write(" ", p); }
 
Time as run using Chapel version 24.1 on an Intel Skylake i5-6500 at 3.6 GHz (turbo, single threaded).
 
var timer: Timer; timer.start(); cnt = 0;
for p in primes() { if p > limit then break; cnt += 1; }
timer.stop(); write("\nFound ", cnt, " primes up to ", limit);
writeln(" in ", timer.elapsed(TimeUnits.milliseconds), " milliseconds.");</syntaxhighlight>
{{out}}
<pre>The first 25 primes are: 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
Found 78498 primes up to 1000000 in 344.859 milliseconds.</pre>
 
Time as run using Chapel version 24.1 on an Intel Skylake i5-6500 at 3.6 GHz (turbo, single threaded).
 
The above code is really just a toy example to show that Chapel can handle some tasks functionally (within the above stated limits) although doing so is slower than the Hash Table version above and also takes more memory as the nested lazy list structure consumes more memory in lazy list links and "plumbing" than does the simple implementation of a Hash Table. It also has a worst asymptotic performance with an extra `log(n)` factor where `n` is the sieving range; this can be shown by running the above program with `--limit=10000000` run time command line option to sieve to ten million which takes about 4.5 seconds to count the primes up to ten million (a factor of ten higher range, but much higher than the expected increased factor of about 10 per cent extra as per the Hash Table version with about 20 per cent more operations times the factor of ten for this version). Other than for the extra operations, this version is generally slower due to the time to do the many small allocations/de-allocations of the functional object instances, and this will be highly dependent on the platform on which it is run: cygwin on Windows may be particularly slow due to the extra level of indirection, and some on-line IDE's may also be slow due to their level of virtualization.
 
===A Multi-Threaded Page-Segmented Odds-Only Bit-Packed Version===
 
To take advantage of the features that make Chapel shine, we need to use it to do some parallel computations, and to efficiently do that for the Sieve of Eratosthenes, we need to divide the work into page segments where we can assign each largish segment to a separate thread/task; this also improves the speed due to better cache associativity with most memory accesses to values that are already in the cache(s). Once we have divided the work, Chapel offers lots of means to implement the parallelism but to be a true Sieve of Eratosthenes, we need to have the ability to output the results in order; with many of the convenience mechanisms not doing that, the best/simplest option is likely task parallelism with the output results assigned to an rotary indexed array containing the `sync` results. It turns out that, although the Chapel compiler can sometimes optimize the code so the overhead of creating tasks is not onerous, for this case where the actual tasks are somewhat complex, the compiler can't recognize that an automatically generated thread pool(s) are required so we need to generate the thread pool(s) manually. The code that implements the multi-threading of page segments using thread pools is as follows:
{{works with|Chapel|1.24.1|- compile with the --fast compiler command line flag for full optimization}}
<syntaxhighlight lang="chapel">use Time; use BitOps; use CPtr;
 
type Prime = uint(64);
type PrimeNdx = int(64);
type BasePrime = uint(32);
 
config const LIMIT = 1000000000: Prime;
 
config const L1 = 16; // CPU L1 cache size in Kilobytes (1024);
assert (L1 == 16 || L1 == 32 || L1 == 64,
"L1 cache size must be 16, 32, or 64 Kilobytes!");
config const L2 = 128; // CPU L2 cache size in Kilobytes (1024);
assert (L2 == 128 || L2 == 256 || L2 == 512,
"L2 cache size must be 128, 256, or 512 Kilobytes!");
const CPUL1CACHE: int = L1 * 1024 * 8; // size in bits!
const CPUL2CACHE: int = L2 * 1024 * 8; // size in bits!
config const NUMTHRDS = here.maxTaskPar;
assert(NUMTHRDS >= 1, "NUMTHRDS must be at least one!");
 
const WHLPRMS = [ 2: Prime, 3: Prime, 5: Prime, 7: Prime,
11: Prime, 13: Prime, 17: Prime];
const FRSTSVPRM = 19: Prime; // past the pre-cull primes!
// 2 eliminated as even; 255255 in bytes...
const WHLPTRNSPN = 3 * 5 * 7 * 11 * 13 * 17;
// rounded up to next 64-bit boundary plus a 16 Kilobyte buffer for overflow...
const WHLPTRNBTSZ = ((WHLPTRNSPN * 8 + 63) & (-64)) + 131072;
 
// number of base primes within small span!
const SZBPSTRTS = 6542 - WHLPRMS.size + 1; // extra one for marker!
// number of base primes for CPU L1 cache buffer!
const SZMNSTRTS = (if L1 == 16 then 12251 else
if L1 == 32 then 23000 else 43390)
- WHLPRMS.size + 1; // extra one for marker!
 
// using this Look Up Table faster than bit twiddling...
const bitmsk = for i in 0 .. 7 do 1:uint(8) << i;
 
var WHLPTRN: SieveBuffer = new SieveBuffer(WHLPTRNBTSZ); fillWHLPTRN(WHLPTRN);
proc fillWHLPTRN(ref wp: SieveBuffer) {
const hi = WHLPRMS.size - 1;
const rng = 0 .. hi; var whlhd = new shared BasePrimeArr({rng});
// contains wheel pattern primes skipping the small wheel prime (2)!...
// never advances past the first base prime arr as it ends with a huge!...
for i in rng do whlhd.bparr[i] = (if i != hi then WHLPRMS[i + 1] // skip 2!
else 0x7FFFFFFF): BasePrime; // last huge!
var whlbpas = new shared BasePrimeArrs(whlhd);
var whlstrts = new StrtsArr({rng});
wp.cull(0, WHLPTRNBTSZ, whlbpas, whlstrts);
// eliminate wheel primes from the WHLPTRN buffer!...
wp.cmpsts[0] = 0xFF: uint(8);
}
 
// the following two must be classes for compability with sync...
class PrimeArr { var dom = { 0 .. -1 }; var prmarr: [dom] Prime; }
class BasePrimeArr { var dom = { 0 .. -1 }; var bparr: [dom] BasePrime; }
record StrtsArr { var dom = { 0 .. -1 }; var strtsarr: [dom] int(32); }
record SieveBuffer {
var dom = { 0 .. -1 }; var cmpsts: [dom] uint(8) = 0;
proc init() {}
proc init(btsz: int) { dom = { 0 .. btsz / 8 - 1 }; }
proc deinit() { dom = { 0 .. -1 }; }
 
proc fill(lwi: PrimeNdx) { // fill from the WHLPTRN stamp...
const sz = cmpsts.size; const mvsz = min(sz, 16384);
var mdlo = ((lwi / 8) % (WHLPTRNSPN: PrimeNdx)): int;
for i in 0 .. sz - 1 by 16384 {
c_memcpy(c_ptrTo(cmpsts[i]): c_void_ptr,
c_ptrTo(WHLPTRN.cmpsts[mdlo]): c_void_ptr, mvsz);
mdlo += 16384; if mdlo >= WHLPTRNSPN then mdlo -= WHLPTRNSPN;
}
}
 
proc count(btlmt: int) { // count by 64 bits using CPU popcount...
const lstwrd = btlmt / 64; const lstmsk = (-2):uint(64) << (btlmt & 63);
const cmpstsp = c_ptrTo(cmpsts: [dom] uint(8)): c_ptr(uint(64));
var i = 0; var cnt = (lstwrd * 64 + 64): int;
while i < lstwrd { cnt -= popcount(cmpstsp[i]): int; i += 1; }
return cnt - popcount(cmpstsp[lstwrd] | lstmsk): int;
}
 
// most of the time is spent doing culling operations as follows!...
proc cull(lwi: PrimeNdx, bsbtsz: int, bpas: BasePrimeArrs,
ref strts: StrtsArr) {
const btlmt = cmpsts.size * 8 - 1; const bplmt = bsbtsz / 32;
const ndxlmt = lwi: Prime + btlmt: Prime; // can't overflow!
const strtssz = strts.strtsarr.size;
// C pointer for speed magic!...
const cmpstsp = c_ptrTo(cmpsts[0]);
const strtsp = c_ptrTo(strts.strtsarr);
 
// first fill the strts array with pre-calculated start addresses...
var i = 0; for bp in bpas {
// calculate page start address for the given base prime...
const bpi = bp: int; const bbp = bp: Prime; const ndx0 = (bbp - 3) / 2;
const s0 = (ndx0 + ndx0) * (ndx0 + 3) + 3; // can't overflow!
if s0 > ndxlmt then {
if i < strtssz then strtsp[i] = -1: int(32); break; }
var s = 0: int;
if s0 >= lwi: Prime then s = (s0 - lwi: Prime): int;
else { const r = (lwi: Prime - s0) % bbp;
if r == 0 then s = 0: int; else s = (bbp - r): int; };
if i < strtssz - 1 { strtsp[i] = s: int(32); i += 1; continue; }
if i < strtssz { strtsp[i] = -1; i = strtssz; }
// cull the full buffer for this given base prime as usual...
// only works up to limit of int(32)**2!!!!!!!!
while s <= btlmt { cmpstsp[s >> 3] |= bitmsk[s & 7]; s += bpi; }
}
 
// cull the smaller sub buffers according to the strts array...
for sbtlmt in bsbtsz - 1 .. btlmt by bsbtsz {
i = 0; for bp in bpas { // bp never bigger than uint(32)!
// cull the sub buffer for this given base prime...
var s = strtsp[i]: int; if s < 0 then break;
var bpi = bp: int; var nxt = 0x7FFFFFFFFFFFFFFF;
if bpi <= bplmt { // use loop "unpeeling" for a small improvement...
const slmt = s + bpi * 8 - 1;
while s <= slmt {
const bmi = s & 7; const msk = bitmsk[bmi];
var c = s >> 3; const clmt = sbtlmt >> 3;
while c <= clmt { cmpstsp[c] |= msk; c += bpi; }
nxt = min(nxt, (c << 3): int(64) | bmi: int(64)); s += bpi;
}
strtsp[i] = nxt: int(32); i += 1;
}
else { while s <= sbtlmt { // standard cull loop...
cmpstsp[s >> 3] |= bitmsk[s & 7]; s += bpi; }
strtsp[i] = s: int(32); i += 1; }
}
}
}
}
 
// a generic record that contains a page result generating function;
// allows manual iteration through the use of the next() method;
// multi-threaded through the use of a thread pool...
class PagedResults {
const cnvrtrclsr; // output converter closure emulator, (lwi, sba) => output
var lwi: PrimeNdx; var bsbtsz: int;
var bpas: shared BasePrimeArrs? = nil: shared BasePrimeArrs?;
var sbs: [ 0 .. NUMTHRDS - 1 ] SieveBuffer = new SieveBuffer();
var strts: [ 0 .. NUMTHRDS - 1 ] StrtsArr = new StrtsArr();
var qi: int = 0;
var wrkq$: [ 0 .. NUMTHRDS - 1 ] sync PrimeNdx;
var rsltsq$: [ 0 .. NUMTHRDS - 1 ] sync cnvrtrclsr(lwi, sbs(0)).type;
 
proc init(cvclsr, li: PrimeNdx, bsz: int) {
cnvrtrclsr = cvclsr; lwi = li; bsbtsz = bsz; }
 
proc deinit() { // kill the thread pool when out of scope...
if bpas == nil then return; // no thread pool!
for i in wrkq$.domain {
wrkq$[i].writeEF(-1); while true { const r = rsltsq$[i].readFE();
if r == nil then break; }
}
}
proc next(): cnvrtrclsr(lwi, sbs(0)).type {
proc dowrk(ri: int) { // used internally!...
while true {
const li = wrkq$[ri].readFE(); // following to kill thread!
if li < 0 { rsltsq$[ri].writeEF(nil: cnvrtrclsr(li, sbs(ri)).type); break; }
sbs[ri].fill(li);
sbs[ri].cull(li, bsbtsz, bpas!, strts[ri]);
rsltsq$[ri].writeEF(cnvrtrclsr(li, sbs[ri]));
}
}
if this.bpas == nil { // init on first use; avoids data race!
this.bpas = new BasePrimeArrs();
if this.bsbtsz < CPUL1CACHE {
this.sbs = new SieveBuffer(bsbtsz);
this.strts = new StrtsArr({0 .. SZBPSTRTS - 1});
}
else {
this.sbs = new SieveBuffer(CPUL2CACHE);
this.strts = new StrtsArr({0 .. SZMNSTRTS - 1});
}
// start threadpool and give it inital work...
for i in rsltsq$.domain {
begin with (const in i) dowrk(i);
this.wrkq$[i].writeEF(this.lwi); this.lwi += this.sbs[i].cmpsts.size * 8;
}
}
const rslt = this.rsltsq$[qi].readFE();
this.wrkq$[qi].writeEF(this.lwi);
this.lwi += this.sbs[qi].cmpsts.size * 8;
this.qi = if qi >= NUMTHRDS - 1 then 0 else qi + 1;
return rslt;
}
iter these() { while lwi >= 0 do yield next(); }
}
 
// the sieve buffer to base prime array converter closure...
record SB2BPArr {
proc this(lwi: PrimeNdx, sb: SieveBuffer): shared BasePrimeArr? {
const bsprm = (lwi + lwi + 3): BasePrime;
const szlmt = sb.cmpsts.size * 8 - 1; var i, j = 0;
var arr = new shared BasePrimeArr({ 0 .. sb.count(szlmt) - 1 });
while i <= szlmt { if sb.cmpsts[i >> 3] & bitmsk[i & 7] == 0 {
arr.bparr[j] = bsprm + (i + i): BasePrime; j += 1; }
i += 1; }
return arr;
}
}
 
// a memoizing lazy list of BasePrimeArr's...
class BasePrimeArrs {
var head: shared BasePrimeArr;
var tail: shared BasePrimeArrs? = nil: shared BasePrimeArrs?;
var lock$: sync bool = true;
var feed: shared PagedResults(SB2BPArr) =
new shared PagedResults(new SB2BPArr(), 65536, 65536);
 
proc init() { // make our own first array to break data race!
var sb = new SieveBuffer(256); sb.fill(0);
const sb2 = new SB2BPArr();
head = sb2(0, sb): shared BasePrimeArr;
this.complete(); // fake base primes!
sb = new SieveBuffer(65536); sb.fill(0);
// use (completed) self as source of base primes!
var strts = new StrtsArr({ 0 .. 256 });
sb.cull(0, 65536, this, strts);
// replace head with new larger version culled using fake base primes!...
head = sb2(0, sb): shared BasePrimeArr;
}
 
// for initializing for use by the fillWHLPTRN proc...
proc init(hd: shared BasePrimeArr) {
head = hd; feed = new shared PagedResults(new SB2BPArr(), 0, 0);
}
 
// for initializing lazily extended list as required...
proc init(hd: shared BasePrimeArr, fd: PagedResults) { head = hd; feed = fd; }
 
proc next(): shared BasePrimeArrs {
if this.tail == nil { // in case other thread slipped through!
if this.lock$.readFE() && this.tail == nil { // empty sync -> block others!
const nhd = this.feed.next(): shared BasePrimeArr;
this.tail = new shared BasePrimeArrs(nhd , this.feed);
}
this.lock$.writeEF(false); // fill the sync so other threads can do nothing!
}
return this.tail: shared BasePrimeArrs; // necessary cast!
}
iter these(): BasePrime {
for bp in head.bparr do yield bp; var cur = next();
while true {
for bp in cur.head.bparr do yield bp; cur = cur.next(); }
}
}
 
record SB2PrmArr {
proc this(lwi: PrimeNdx, sb: SieveBuffer): shared PrimeArr? {
const bsprm = (lwi + lwi + 3): Prime;
const szlmt = sb.cmpsts.size * 8 - 1; var i, j = 0;
var arr = new shared PrimeArr({0 .. sb.count(szlmt) - 1});
while i <= szlmt { if sb.cmpsts[i >> 3] & bitmsk[i & 7] == 0 then {
arr.prmarr[j] = bsprm + (i + i): Prime; j += 1; }
i += 1; }
return arr;
}
}
 
iter primes(): Prime {
for p in WHLPRMS do yield p: Prime;
for pa in new shared PagedResults(new SB2PrmArr(), 0, CPUL1CACHE) do
for p in pa!.prmarr do yield p;
}
 
// use a class so that it can be used as a generic sync value!...
class CntNxt { const cnt: int; const nxt: PrimeNdx; }
 
// a class that emulates a closure and a return value...
record SB2Cnt {
const nxtlmt: PrimeNdx;
proc this(lwi: PrimeNdx, sb: SieveBuffer): shared CntNxt? {
const btszlmt = sb.cmpsts.size * 8 - 1; const lstndx = lwi + btszlmt: PrimeNdx;
const btlmt = if lstndx > nxtlmt then max(0, (nxtlmt - lwi): int) else btszlmt;
return new shared CntNxt(sb.count(btlmt), lstndx);
}
}
 
// couut primes to limit, just like it says...
proc countPrimesTo(lmt: Prime): int(64) {
const nxtlmt = ((lmt - 3) / 2): PrimeNdx; var count = 0: int(64);
for p in WHLPRMS { if p > lmt then break; count += 1; }
if lmt < FRSTSVPRM then return count;
for cn in new shared PagedResults(new SB2Cnt(nxtlmt), 0, CPUL1CACHE) {
count += cn!.cnt: int(64); if cn!.nxt >= nxtlmt then break;
}
return count;
}
 
// test it...
write("The first 25 primes are: "); var cnt = 0;
for p in primes() { if cnt >= 25 then break; cnt += 1; write(" ", p); }
 
cnt = 0; for p in primes() { if p > 1000000 then break; cnt += 1; }
writeln("\nThere are ", cnt, " primes up to a million.");
 
write("Sieving to ", LIMIT, " with ");
write("CPU L1/L2 cache sizes of ", L1, "/", L2, " KiloBytes ");
writeln("using ", NUMTHRDS, " threads.");
 
var timer: Timer; timer.start();
// the slow way!:
// var count = 0; for p in primes() { if p > LIMIT then break; count += 1; }
const count = countPrimesTo(LIMIT); // the fast way!
timer.stop();
 
write("Found ", count, " primes up to ", LIMIT);
writeln(" in ", timer.elapsed(TimeUnits.milliseconds), " milliseconds.");</syntaxhighlight>
{{out}}
<pre>The first 25 primes are: 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
There are 78498 primes up to a million.
Sieving to 1000000000 with CPU L1/L2 cache sizes of 16/128 KiloBytes using 4 threads.
Found 50847534 primes up to 1000000000 in 128.279 milliseconds.</pre>
 
Time as run using Chapel version 1.24.1 on an Intel Skylake i5-6500 at 3.2 GHz (base, multi-threaded).
 
Note that the above code does implement some functional concepts as in a memoized lazy list of base prime arrays, but as this is used at the page level, the slowish performance doesn't impact the overall execution time much and the code is much more elegant in using this concept such that we compute new pages of base primes as they are required for increasing range.
 
Some of the most tricky bits due to having thread pools is stopping and de-initializing when they go out of scope; this is done by the `deinit` method of the `PagedResults` generic class, and was necessary to prevent a segmentation fault when the thread pool goes out of scope.
 
The tight inner loops for culling composite number representations have been optimized to some extent in using "loop unpeeling" for smaller base primes to simplify the loops down to simple masking by a constant with eight separate loops for the repeating pattern over bytes and culling by sub buffer CPU L1 cache sizes over the outer sieve buffer size of the CPU L2 cache size in order to make the task work-sized chunks larger for less task context switching overheads and for reduced time lost to culling start address calculations per base prime (which needs to use some integer division that is always slower than other integer operations). This last optimization allows for reasonably efficient culling up to the square of the CPU L2 cache size in bits or 1e12 for the one Megabit CPU L2 cache size many mid-range Intel CPU's have currently when used for multi-threading (half of the actual size for Hyper-Threaded - HT - threads as they share both the L1 and the L2 caches over the pairs of Hyper-Threaded (HT) threads per core).
 
Although this code can be used for much higher sieving ranges, it is not recommended due to not yet being tuned for better efficiency above 1e12; there are no checks limiting the user to this range, but, as well as decreasing efficiency for sieving limits much higher than this, at some point there will be errors due to integer overflows but these will be for huge sieving ranges taking days -> weeks -> months -> years to execute on common desktop CPU's.
 
A further optimization used is to create a pre-culled `WHLPTRN` `SieveBuffer` where the odd primes (since we cull odds-only) of 3, 5, 7, 11, 13, and 17 have already been culled and using that to pre-fill the page segment buffers so that no culling by these base prime values is required, this reduces the number of operations by about 45% compared to if it wasn't done but the ratio of better performance is only about 34.5% better as this changes the ratio of (fast) smaller base primes to larger (slower) ones.
 
All of the improvements to this point allow the shown performance as per the displayed output for the above program; using a command line argument of `--L1=32 --L2=256 --LIMIT=100000000000` (a hundred billion - 1e11 - on this computer, which has cache sizes of that amount and no Hyper-Threading - HT), it can count the primes to 1e11 in about 17.5 seconds using the above mentioned CPU. It will be over two times faster than this using a more modern desktop CPU such as the Intel Core i7-9700K which has twice as many effective cores, a higher CPU clock rate, is about 10% to 15% faster due the a more modern CPU architecture which is three generations newer. Of course using a top end AMD Threadripper CPU with its 64/128 cores/threads will be almost eight times faster again except that it will lose about 20% due to its slower clock speed when all cores/threads are used; note that high core CPU's will only give these speed gains for large sieving ranges such as 1e11 and above since otherwise there aren't enough work chunks to go around for all the threads available!
 
Incredibly, even run single threaded (argument of `--NUMTHRDS=1`) this implementation is only about 20% slower than the reference Sieve of Atkin "primegen/primespeed" implementation in counting the number of primes to a billion and is about 20% faster in counting the primes to a hundred billion (arguments of `--LIMIT=100000000000 --NUMTHRDS=1`) with both using the same size of CPU L1 cache buffer of 16 Kilobytes; This implementation does not yet have the level of wheel optimization of the Sieve of Atkin as it has only the limited wheel optimization of Odds-Only plus the use of the pre-cull fill. Maximum wheel factorization will reduce the number of operations for this code to less than about half the current number, making it faster than the Sieve of Atkin for all ranges, and approach the speed of Kim Walisch's "primesieve". However, not having primitive element pointers and pointer operations, there are some optimizations used that Kim Walisch's "primesieve" uses of extreme loop unrolling that mean that it can never quite reach the speed of "primeseive" by about 20% to 30%.
 
The above code is a fairly formidable benchmark, which I have also written in Fortran as in likely the major computer language that is comparable. I see that Chapel has the following advantages over Fortran:
 
1) It is somewhat cleaner to read and write code with more modern forms of expression, especially as to declaring variables/constants which can often be inferred as to type.
 
2) The Object Oriented Programming paradigm has been designed in from the beginning and isn't just an add-on that needs to be careful not to break legacy code; Fortran's method of expression this paradigm using modules seems awkward by comparison.
 
3) It has some more modern forms of automatic memory management as to type safety and sharing of allocated memory structures.
 
4) It has several modern forms of managing concurrency built in from the beginning rather than being add-on's or just being the ability to call through to OpenMP/MPI.
 
That said, it also as the following disadvantages, at least as I see it:
 
1) One of the worst things about Chapel is the slow compilation speed, which is about ten times slower than GNU gfortran.
 
2) It's just my personal opinion, but so much about forms of expression have been modernized and improved, it seems very dated to go back to using curly braces to delineate code blocks and semi-colons as line terminators; Most modern languages at least dispense with the latter.
 
3) Some programming features offered are still being defined, although most evolutionary changes now no longer are breaking code changes.
 
Speed isn't really an issue with either one, with some types of tasks better suited to one or the other but mostly about the same; for this particular task they are about the same if one were to implement the same algorithmic optimizations other than that one can do some of the extreme loop unrolling optimization with Fortran that can't be done with Chapel as Fortran has some limited form of pointers, although not the full set of pointer operators that C/C++ like languages have. I think that if both were optimized as much as each is capable, Fortran may run about 20% faster, perhaps due to the maturity of its compile and due to the availablity of (limited) pointer operations.
 
The primary additional optimization available to Chapel code is the addition of Maximum Wheel-Factorization as per [https://stackoverflow.com/a/57108107/549617 my StackOverflow JavaScript Tutorial answer], with the other major improvement to add "bucket sieving" for sieving limits above about 1e12 so as to get reasonable efficiency up to 1e16 and above.
 
=={{header|Clojure}}==
<syntaxhighlight lang="clojure">(defn primes< [n]
{{incorrect|Clojure|The first version uses rem testing and so is a trial division algorithm, not a sieve of Eratosthenes.}}
(remove (set (mapcat #(range (* % %) n %)
Note: this is not a Sieve of Eratosthenes; it is just an inefficient version (because it doesn't trial just the found primes <= the square root of the range) trial division.
(range 2 (Math/sqrt n))))
(range 2 n)))</syntaxhighlight>
 
The above is **not strictly a Sieve of Eratosthenes** as the composite culling ranges (in the ''mapcat'') include all of the multiples of all of the numbers and not just the multiples of primes. When tested with <code clojure>(println (time (count (primes< 1000000))))</code>, it takes about 5.5 seconds just to find the number of primes up to a million, partly because of the extra work due to the use of the non-primes, and partly because of the constant enumeration using sequences with multiple levels of function calls. Although very short, this code is likely only useful up to about this range of a million.
''primes<'' is a functional interpretation of the Sieve of Eratosthenes. It merely removes the set of composite numbers from the set of odd numbers (wheel of 2) leaving behind only prime numbers. It uses a transducer internally with "into #{}".
<lang clojure>
(defn primes< [n]
(if (<= n 2)
()
(remove (into #{}
(mapcat #(range (* % %) n %))
(range 3 (Math/sqrt n) 2))
(cons 2 (range 3 n 2)))))
</lang>
 
It may be written using the ''into #{}'' function to run slightly faster due to the ''set'' function being concerned with only distinct elements whereas the ''into #{}'' only does the conjunction, and even at that doesn't do that much as it does the conjunction to an empty sequence, the code as follows:
Calculates primes up to and including ''n'' using a mutable boolean array but otherwise entirely functional code.
 
<lang clojure>
<syntaxhighlight lang="clojure">(defn primes-to< [n]
(remove (into #{}
(mapcat #(range (* % %) n %)
(range 2 (Math/sqrt n))))
(range 2 n)))</syntaxhighlight>
 
The above code is slightly faster for the reasons given, but is still not strictly a Sieve of Eratosthenes due to sieving by all numbers and not just by the base primes.
 
The following code also uses the ''into #{}'' transducer but has been slightly wheel-factorized to sieve odds-only:
<syntaxhighlight lang="clojure">(defn primes< [n]
(if (< n 2) ()
(cons 2 (remove (into #{}
(mapcat #(range (* % %) n %)
(range 3 (Math/sqrt n) 2)))
(range 3 n 2)))))</syntaxhighlight>
 
The above code is a little over twice as fast as the non-odds-only due to the reduced number of operations. It still isn't strictly a Sieve of Eratosthenes as it sieves by all odd base numbers and not only by the base primes.
 
The following code calculates primes up to and including ''n'' using a mutable boolean array but otherwise entirely functional code; it is tens (to a hundred) times faster than the purely functional codes due to the use of mutability in the boolean array:
<syntaxhighlight lang="clojure">(defn primes-to
"Computes lazy sequence of prime numbers up to a given number using sieve of Eratosthenes"
[n]
Line 1,972 ⟶ 3,853:
(do (dorun (map #(cullp %) (filter #(not (aget cmpsts %))
(range 2 (inc root)))))
(filter #(not (aget cmpsts %)) (range 2 (inc n))))))</syntaxhighlight>
</lang>
 
'''Alternative implementation using Clojure's side-effect oriented list comprehension.'''
 
<langsyntaxhighlight lang="clojure"> (defn primes-to
(defn primes-to
"Returns a lazy sequence of prime numbers less than lim"
[lim]
Line 1,988 ⟶ 3,867:
(doseq [j (range (* i i) lim i)]
(aset refs j false)))
(filter #(aget refs %) (range 2 lim)))))</syntaxhighlight>
</lang>
 
'''Alternative implementation using Clojure's side-effect oriented list comprehension. Odds only.'''
<langsyntaxhighlight lang="clojure">(defn primes-to
(defn primes-to
"Returns a lazy sequence of prime numbers less than lim"
[lim]
Line 2,003 ⟶ 3,880:
(doseq [j (range (* (+ i i) (inc i)) max-i (+ i i 1))]
(aset refs j false)))
(cons 2 (map #(+ % % 1) (filter #(aget refs %) (range 1 max-i)))))))</syntaxhighlight>
 
</lang>
This implemantation is about twice as fast thanas the previous one and useuses only half the memory.
From the index of the array, it calculates the value it represents as (2*i + 1), the step between two indexindices that representsrepresent
the multiples of primes to mark as composite is also (2*i + 1).
The index of the square of the prime to start composite marking is 2*i*(i+1).
Line 2,012 ⟶ 3,889:
'''Alternative very slow entirely functional implementation using lazy sequences'''
 
<langsyntaxhighlight lang="clojure">(defn primes-to
(defn primes-to
"Computes lazy sequence of prime numbers up to a given number using sieve of Eratosthenes"
[n]
Line 2,021 ⟶ 3,897:
(cons p (lazy-seq (nxtprm (-> (range (* p p) (inc n) p)
set (remove cs) rest)))))))]
(nxtprm (range 2 (inc n)))))</syntaxhighlight>
</lang>
 
The reason that the above code is so slow is that it has has a high constant factor overhead due to using a (hash) set to remove the composites from the future composites stream, each prime composite stream removal requires a scan across all remaining composites (compared to using an array or vector where only the culled values are referenced, and due to the slowness of Clojure sequence operations as compared to iterator/sequence operations in other languages.
Line 2,029 ⟶ 3,904:
 
Here is an immutable boolean vector based non-lazy sequence version other than for the lazy sequence operations to output the result:
<langsyntaxhighlight lang="clojure">(defn primes-to
(defn primes-to
"Computes lazy sequence of prime numbers up to a given number using sieve of Eratosthenes"
[max-prime]
Line 2,044 ⟶ 3,918:
(assoc 1 false)
(sieve 2))
(map-indexed #(vector %2 %1)) (filter first) (map second))))</syntaxhighlight>
</lang>
 
The above code is still quite slow due to the cost of the immutable copy-on-modify operations.
Line 2,052 ⟶ 3,925:
 
The following code implements an odds-only sieve using a mutable bit packed long array, only using a lazy sequence for the output of the resulting primes:
<syntaxhighlight lang="clojure">(set! *unchecked-math* true)
<lang clojure>
(set! *unchecked-math* true)
 
(defn primes-to
Line 2,079 ⟶ 3,951:
(recur (inc i)))))))))]
(if (< n 2) nil
(cons 3 (if (< n 3) nil (do (cull) (lazy-seq (nxtprm 0)))))))))</syntaxhighlight>
</lang>
 
The above code is about as fast as any "one large sieving array" type of program in any computer language with this level of wheel factorization other than the lazy sequence operations are quite slow: it takes about ten times as long to enumerate the results as it does to do the actual sieving work of culling the composites from the sieving buffer array. The slowness of sequence operations is due to nested function calls, but primarily due to the way Clojure implements closures by "boxing" all arguments (and perhaps return values) as objects in the heap space, which then need to be "un-boxed" as primitives as necessary for integer operations. Some of the facilities provided by lazy sequences are not needed for this algorithm, such as the automatic memoization which means that each element of the sequence is calculated only once; it is not necessary for the sequence values to be retraced for this algorithm.
Line 2,087 ⟶ 3,958:
 
The following code overcomes many of those limitations by using an internal (OPSeq) "deftype" which implements the ISeq interface as well as the Counted interface to provide immediate count returns (based on a pre-computed total), as well as the IReduce interface which can greatly speed come computations based on the primes sequence (eased greatly using facilities provided by Clojure 1.7.0 and up):
<langsyntaxhighlight lang="clojure">(defn primes-tox
(defn primes-tox
"Computes lazy sequence of prime numbers up to a given number using sieve of Eratosthenes"
[n]
Line 2,160 ⟶ 4,030:
(toString [this] (if (= cnt tcnt) "()"
(.toString (seq (map identity this))))))
(->OPSeq 0 cmpsts 0 (numprms))))))))</syntaxhighlight>
</lang>
 
'(time (count (primes-tox 10000000)))' takes about 40 milliseconds (compiled) to produce 664579.
Line 2,179 ⟶ 4,048:
 
'''A Clojure version of Richard Bird's Sieve using Lazy Sequences (sieves odds only)'''
<langsyntaxhighlight lang="clojure">(defn primes-Bird
(defn primes-Bird
"Computes the unbounded sequence of primes using a Sieve of Eratosthenes algorithm by Richard Bird."
[]
Line 2,201 ⟶ 4,069:
(do (def oddprms (cons 3 (lazy-seq (let [cmpsts (-> oddprms (allmtpls) (mrgmltpls))]
(minusStrtAt 5 cmpsts)))))
(cons 2 (lazy-seq oddprms)))))</syntaxhighlight>
</lang>
 
The above code is quite slow due to both that the data structure is a linear merging of prime multiples and due to the slowness of the Clojure sequence operations.
Line 2,209 ⟶ 4,076:
 
The following code speeds up the above code by merging the linear sequence of sequences as above by pairs into a right-leaning tree structure:
<syntaxhighlight lang="clojure">(defn primes-treeFolding
<lang clojure>
(defn primes-treeFolding
"Computes the unbounded sequence of primes using a Sieve of Eratosthenes algorithm modified from Bird."
[]
Line 2,234 ⟶ 4,100:
(do (def oddprms (cons 3 (lazy-seq (let [cmpsts (-> oddprms (allmtpls) (mrgmltpls))]
(minusStrtAt 5 cmpsts)))))
(cons 2 (lazy-seq oddprms)))))</syntaxhighlight>
</lang>
 
The above code is still slower than it should be due to the slowness of Clojure's sequence operations.
Line 2,242 ⟶ 4,107:
 
The following code uses a custom "deftype" non-memoizing Co Inductive Stream/Sequence (CIS) implementing the ISeq interface to make the sequence operations more efficient and is about four times faster than the above code:
<langsyntaxhighlight lang="clojure">(deftype CIS [v cont]
clojure.lang.ISeq
(first [_] v)
Line 2,290 ⟶ 4,155:
(do (def oddprms (->CIS 3 (fn [] (let [cmpsts (-> oddprms (allmtpls) (mrgmltpls))]
(minusStrtAt 5 cmpsts)))))
(->CIS 2 (fn [] oddprms)))))</langsyntaxhighlight>
 
'(time (count (take-while #(<= (long %) 10000000) (primes-treeFoldingx))))' takes about 3.4 seconds for a range of 10 million.
Line 2,299 ⟶ 4,164:
 
The following code is a version of the O'Neill Haskell code but does not use wheel factorization other than for sieving odds only (although it could be easily added) and uses a Hash Map (constant amortized access time) rather than a Priority Queue (log n access time for combined remove-and-insert-anew operations, which are the majority used for this algorithm) with a lazy sequence for output of the resulting primes; the code has the added feature that it uses a secondary base primes sequence generator and only adds prime culling sequences to the composites map when they are necessary, thus saving time and limiting storage to only that required for the map entries for primes up to the square root of the currently sieved number:
 
<lang clojure>
<syntaxhighlight lang="clojure">(defn primes-hashmap
"Infinite sequence of primes using an incremental Sieve or Eratosthenes with a Hashmap"
[]
Line 2,316 ⟶ 4,181:
(cons c (lazy-seq (nxtoddprm (+ c 2) q bsprms cmpsts))))))]
(do (def baseoddprms (cons 3 (lazy-seq (nxtoddprm 5 9 baseoddprms {}))))
(cons 2 (lazy-seq (nxtoddprm 3 9 baseoddprms {}))))))</syntaxhighlight>
</lang>
 
The above code is slower than the best tree folding version due to the added constant factor overhead of computing the hash functions for every hash map operation even though it has computational complexity of (n log log n) rather than the worse (n log n log log n) for the previous incremental tree folding sieve. It is still about 100 times slower than the sieve based on the bit-packed mutable array due to these constant factor hashing overheads.
Line 2,326 ⟶ 4,190:
 
In order to implement the O'Neill Priority Queue incremental Sieve of Eratosthenes algorithm, one requires an efficient implementation of a Priority Queue, which is not part of standard Clojure. For this purpose, the most suitable Priority Queue is a binary tree heap based MinHeap algorithm. The following code implements a purely functional (using entirely immutable state) MinHeap Priority Queue providing the required functions of (emtpy-pq) initialization, (getMin-pq pq) to examinte the minimum key/value pair in the queue, (insert-pq pq k v) to add entries to the queue, and (replaceMinAs-pq pq k v) to replaace the minimum entry with a key/value pair as given (it is more efficient that if functions were provided to delete and then re-insert entries in the queue; there is therefore no "delete" or other queue functions supplied as the algorithm does not requrie them:
 
<lang clojure>(deftype PQEntry [k, v]
<syntaxhighlight lang="clojure">(deftype PQEntry [k, v]
Object
(toString [_] (str "<" k "," v ">")))
Line 2,371 ⟶ 4,236:
(if (<= kl kr)
(recur l #(cont (->PQNode kvl % r)))
(recur r #(cont (->PQNode kvr l %))))))))))))</langsyntaxhighlight>
 
Note that the above code is written partially using continuation passing style so as to leave the "recur" calls in tail call position as required for efficient looping in Clojure; for practical sieving ranges, the algorithm could likely use just raw function recursion as recursion depth is unlikely to be used beyond a depth of about ten or so, but raw recursion is said to be less code efficient.
 
The actual incremental sieve using the Priority Queue is as follows, which code uses the same optimizations of postponing the addition of prime composite streams to the queue until the square root of the currently sieved number is reached and using a secondary base primes stream to generate the primes composite stream markers in the queue as was used for the Hash Map version:
 
<lang clojure>(defn primes-pq
<syntaxhighlight lang="clojure">(defn primes-pq
"Infinite sequence of primes using an incremental Sieve or Eratosthenes with a Priority Queue"
[]
Line 2,394 ⟶ 4,260:
(cons c (lazy-seq (nxtoddprm (+ c 2) q bsprms cmpsts)))))))]
(do (def baseoddprms (cons 3 (lazy-seq (nxtoddprm 5 9 baseoddprms (empty-pq)))))
(cons 2 (lazy-seq (nxtoddprm 3 9 baseoddprms (empty-pq)))))))</langsyntaxhighlight>
 
The above code is faster than the Hash Map version up to about a sieving range of fifteen million or so, but gets progressively slower for larger ranges due to having (n log n log log n) computational complexity rather than the (n log log n) for the Hash Map version, which has a higher constant factor overhead that is overtaken by the extra "log n" factor.
Line 2,410 ⟶ 4,276:
To show that Clojure does not need to be particularly slow, the following version runs about twice as fast as the non-segmented unbounded array based version above (extremely fast compared to the non-array based versions) and only a little slower than other equivalent versions running on virtual machines: C# or F# on DotNet or Java and Scala on the JVM:
 
<langsyntaxhighlight lang="clojure">(set! *unchecked-math* true)
 
(def PGSZ (bit-shift-left 1 14)) ;; size of CPU cache
Line 2,557 ⟶ 4,423:
(next pgseq)
(+ cnt (count-pg PGBTS pg))))))]
(nxt-pg 0 (primes-pages) 1))))</langsyntaxhighlight>
 
The above code runs just as fast as other virtual machine languages when run on a 64-bit JVM; however, when run on a 32-bit JVM it runs almost five times slower. This is likely due to Clojure only using 64-bit integers for integer operations and these operations getting JIT compiled to use library functions to simulate those operations using combined 32-bit operations under a 32-bit JVM whereas direct CPU operations can be used on a 64-bit JVM
Line 2,568 ⟶ 4,434:
 
The base primes culling page size is reduced from the page size for the main primes so that there is less overhead for smaller primes ranges; otherwise excess base primes are generated for fairly small sieve ranges.
 
=={{header|CLU}}==
<syntaxhighlight lang="clu">% Sieve of Eratosthenes
eratosthenes = proc (n: int) returns (array[bool])
prime: array[bool] := array[bool]$fill(1, n, true)
prime[1] := false
 
for p: int in int$from_to(2, n/2) do
if prime[p] then
for c: int in int$from_to_by(p*p, n, p) do
prime[c] := false
end
end
end
return(prime)
end eratosthenes
 
% Print primes up to 1000 using the sieve
start_up = proc ()
po: stream := stream$primary_output()
prime: array[bool] := eratosthenes(1000)
col: int := 0
 
for i: int in array[bool]$indexes(prime) do
if prime[i] then
col := col + 1
stream$putright(po, int$unparse(i), 5)
if col = 10 then
col := 0
stream$putc(po, '\n')
end
end
end
end start_up</syntaxhighlight>
{{out}}
<pre> 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 101 103 107 109 113
127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229
233 239 241 251 257 263 269 271 277 281
283 293 307 311 313 317 331 337 347 349
353 359 367 373 379 383 389 397 401 409
419 421 431 433 439 443 449 457 461 463
467 479 487 491 499 503 509 521 523 541
547 557 563 569 571 577 587 593 599 601
607 613 617 619 631 641 643 647 653 659
661 673 677 683 691 701 709 719 727 733
739 743 751 757 761 769 773 787 797 809
811 821 823 827 829 839 853 857 859 863
877 881 883 887 907 911 919 929 937 941
947 953 967 971 977 983 991 997</pre>
 
=={{header|CMake}}==
<langsyntaxhighlight lang="cmake">function(eratosthenes var limit)
# Check for integer overflow. With CMake using 32-bit signed integer,
# this check fails when limit > 46340.
Line 2,604 ⟶ 4,522:
endforeach(i)
set(${var} ${list} PARENT_SCOPE)
endfunction(eratosthenes)</langsyntaxhighlight>
# Print all prime numbers through 100.
eratosthenes(primes 100)
Line 2,610 ⟶ 4,528:
 
=={{header|COBOL}}==
<langsyntaxhighlight lang="cobol">*> Please ignore the asterisks in the first column of the next comments,
*> which are kludges to get syntax highlighting to work.
IDENTIFICATION DIVISION.
Line 2,664 ⟶ 4,582:
 
GOBACK
.</langsyntaxhighlight>
 
=={{header|Comal}}==
{{trans|BASIC}}
<syntaxhighlight lang="comal">// Sieve of Eratosthenes
input "Limit? ": limit
dim sieve(1:limit)
sqrlimit:=sqr(limit)
sieve(1):=1
p:=2
while p<=sqrlimit do
while sieve(p) and p<sqrlimit do
p:=p+1
endwhile
if p>sqrlimit then goto done
for i:=p*p to limit step p do
sieve(i):=1
endfor i
p:=p+1
endwhile
done:
print 2,
for i:=3 to limit do
if sieve(i)=0 then
print ", ",i,
endif
endfor i
print</syntaxhighlight>
 
{{Out}}
<pre>
Limit? 100
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
 
end</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun sieve-of-eratosthenes (maximum)
(loop
with sieve = (make-array (1+ maximum)
Line 2,677 ⟶ 4,631:
and do (loop for composite from (expt candidate 2)
to maximum by candidate
do (setf (bit sieve composite) 1))))</langsyntaxhighlight>
 
Working with odds only (above twice speedup), and marking composites only for primes up to the square root of the maximum:
 
<langsyntaxhighlight lang="lisp">(defun sieve-odds (maximum)
"Prime numbers sieve for odd numbers.
Returns a list with all the primes that are less than or equal to maximum."
Line 2,694 ⟶ 4,648:
:do (loop :for j :from (* i (1+ i) 2) :to maxi :by odd-number
:do (setf (sbit sieve j) 1))
:finally (return (cons 2 values))))</langsyntaxhighlight>
 
The indexation scheme used here interprets each index <code>i</code> as standing for the value <code>2i+1</code>. Bit <code>0</code> is unused, a small price to pay for the simpler index calculations compared with the <code>2i+3</code> indexation scheme. The multiples of a given odd prime <code>p</code> are enumerated in increments of <code>2p</code>, which corresponds to the index increment of <code>p</code> on the sieve array. The starting point <code>p*p = (2i+1)(2i+1) = 4i(i+1)+1</code> corresponds to the index <code>2i(i+1)</code>.
 
While formally a ''wheel'', odds are uniformly spaced and do not require any special processing except for value translation. Wheels proper aren't uniformly spaced and are thus trickier.
 
=={{header|Cowgol}}==
<syntaxhighlight lang="cowgol">include "cowgol.coh";
 
# To change the maximum prime, change the size of this array
# Everything else is automatically filled in at compile time
var sieve: uint8[5000];
 
# Make sure all elements of the sieve are set to zero
MemZero(&sieve as [uint8], @bytesof sieve);
 
# Generate the sieve
var prime: @indexof sieve := 2;
while prime < @sizeof sieve loop
if sieve[prime] == 0 then
var comp: @indexof sieve := prime * prime;
while comp < @sizeof sieve loop
sieve[comp] := 1;
comp := comp + prime;
end loop;
end if;
prime := prime + 1;
end loop;
 
# Print all primes
var cand: @indexof sieve := 2;
while cand < @sizeof sieve loop
if sieve[cand] == 0 then
print_i16(cand as uint16);
print_nl();
end if;
cand := cand + 1;
end loop;</syntaxhighlight>
 
{{out}}
<pre>2
3
5
7
11
...
4967
4969
4973
4987
4999</pre>
 
=={{header|Craft Basic}}==
<syntaxhighlight lang="basic">define limit = 120
 
dim flags[limit]
 
for n = 2 to limit
 
let flags[n] = 1
 
next n
 
print "prime numbers less than or equal to ", limit ," are:"
 
for n = 2 to sqrt(limit)
 
if flags[n] = 1 then
 
for i = n * n to limit step n
 
let flags[i] = 0
 
next i
 
endif
 
next n
 
for n = 1 to limit
 
if flags[n] then
 
print n
 
endif
 
next n</syntaxhighlight>
{{out| Output}}<pre>
prime numbers less than or equal to 120 are:
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 101 103 107 109 113 </pre>
 
=={{header|Crystal}}==
 
===Basic Version===
 
This implementation uses a `BitArray` so it is automatically bit-packed to use just one bit per number representation:
 
<syntaxhighlight lang="ruby"># compile with `--release --no-debug` for speed...
 
require "bit_array"
 
alias Prime = UInt64
 
class SoE
include Iterator(Prime)
@bits : BitArray; @bitndx : Int32 = 2
 
def initialize(range : Prime)
if range < 2
@bits = BitArray.new 0
else
@bits = BitArray.new((range + 1).to_i32)
end
ba = @bits; ndx = 2
while true
wi = ndx * ndx
break if wi >= ba.size
if ba[ndx]
ndx += 1; next
end
while wi < ba.size
ba[wi] = true; wi += ndx
end
ndx += 1
end
end
 
def next
while @bitndx < @bits.size
if @bits[@bitndx]
@bitndx += 1; next
end
rslt = @bitndx.to_u64; @bitndx += 1; return rslt
end
stop
end
end
 
print "Primes up to a hundred: "
SoE.new(100).each { |p| print " ", p }; puts
print "Number of primes to a million: "
puts SoE.new(1_000_000).each.size
print "Number of primes to a billion: "
start_time = Time.monotonic
print SoE.new(1_000_000_000).each.size
elpsd = (Time.monotonic - start_time).total_milliseconds
puts " in #{elpsd} milliseconds."</syntaxhighlight>
 
{{out}}
<pre>Primes up to a hundred: 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
Number of primes to a million: 78498
Number of primes to a billion: 50847534 in 10219.222539 milliseconds.</pre>
 
This is as run on an Intel SkyLake i5-6500 at 3.6 GHz (automatic boost for single threaded as here).
 
===Odds-Only Version===
 
the non-odds-only version as per the above should never be used because in not using odds-only, it uses twice the memory and over two and a half times the CPU operations as the following odds-only code, which is very little more complex:
 
<syntaxhighlight lang="ruby"># compile with `--release --no-debug` for speed...
 
require "bit_array"
 
alias Prime = UInt64
 
class SoE_Odds
include Iterator(Prime)
@bits : BitArray; @bitndx : Int32 = -1
 
def initialize(range : Prime)
if range < 3
@bits = BitArray.new 0
else
@bits = BitArray.new(((range - 1) >> 1).to_i32)
end
ba = @bits; ndx = 0
while true
wi = (ndx + ndx) * (ndx + 3) + 3 # start cull index calculation
break if wi >= ba.size
if ba[ndx]
ndx += 1; next
end
bp = ndx + ndx + 3
while wi < ba.size
ba[wi] = true; wi += bp
end
ndx += 1
end
end
 
def next
while @bitndx < @bits.size
if @bitndx < 0
@bitndx += 1; return 2_u64
elsif @bits[@bitndx]
@bitndx += 1; next
end
rslt = (@bitndx + @bitndx + 3).to_u64; @bitndx += 1; return rslt
end
stop
end
end
 
print "Primes up to a hundred: "
SoE_Odds.new(100).each { |p| print " ", p }; puts
print "Number of primes to a million: "
puts SoE_Odds.new(1_000_000).each.size
print "Number of primes to a billion: "
start_time = Time.monotonic
print SoE_Odds.new(1_000_000_000).each.size
elpsd = (Time.monotonic - start_time).total_milliseconds
puts " in #{elpsd} milliseconds."</syntaxhighlight>
 
{{out}}
<pre>Primes up to a hundred: 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
Number of primes to a million: 78498
Number of primes to a billion: 50847534 in 4877.829642 milliseconds.</pre>
 
As can be seen, this is over two times faster than the non-odds-only version when run on the same CPU due to reduced pressure on the CPU data cache; however it is only reasonably performant for ranges of a few millions, and above that a page-segmented version of odds-only (or further wheel factorization) should be used plus other techniques for a further reduction of number of CPU clock cycles per culling/marking operation.
 
===Page-Segmented Odds-Only Version===
 
For sieving of ranges larger than a few million efficiently, a page-segmented sieve should always be used to preserve CPU cache associativity by making the page size to be about that of the CPU L1 data cache. The following code implements a page-segmented version that is an extensible sieve (no upper limit needs be specified) using a secondary memoized feed of base prime value arrays which use a smaller page-segment size for efficiency. When the count of the number of primes is desired, the sieve is polymorphic in output and counts the unmarked composite bits by using fast `popcount` instructions taken 64-bits at a time. The code is as follows:
 
<syntaxhighlight lang="ruby"># compile with `--release --no-debug` for speed...
 
alias Prime = UInt64
alias PrimeNdx = Int64
alias PrimeArr = Array(Prime)
alias SieveBuffer = Pointer(UInt8)
alias BasePrime = UInt32
alias BasePrimeArr = Array(BasePrime)
 
CPUL1CACHE = 131072 # 16 Kilobytes in nimber of bits
 
BITMASK = Pointer(UInt8).malloc(8) { |i| 1_u8 << i }
 
# Count number of non-composite (zero) bits within index range...
# sieve buffer is always evenly divisible by 64-bit words...
private def count_page_to(ndx : Int32, sb : SieveBuffer)
lstwrdndx = ndx >> 6; mask = (~1_u64) << (ndx & 63)
cnt = lstwrdndx * 64 + 64; sbw = sb.as(Pointer(UInt64))
lstwrdndx.times { |i| cnt -= sbw[i].popcount }
cnt - (sbw[lstwrdndx] | mask).popcount
end
 
# Cull composite bits from sieve buffer using base prime arrays;
# starting at overall given prime index for given buffer bit size...
private def cull_page(pndx : PrimeNdx, bitsz : Int32,
bps : Iterator(BasePrimeArr), sb : SieveBuffer)
bps.each { |bpa|
bpa.each { |bpu32|
bp = bpu32.to_i64; bpndx = (bp - 3) >> 1
swi = (bpndx + bpndx) * (bpndx + 3) + 3 # calculate start prime index
return if swi >= pndx + bitsz.to_i64
bpi = bp.to_i32 # calculate buffer start culling index...
bi = (swi >= pndx) ? (swi - pndx).to_i32 : begin
r = (pndx - swi) % bp; r == 0 ? 0 : bpi - r.to_i32
end
# when base prime is small enough, cull using strided loops to
# simplify the inner loops at the cost of more loop overhead...
# allmost all of the work is done by the following loop...
if bpi < (bitsz >> 4)
bilmt = bi + (bpi << 3); cplmt = sb + (bitsz >> 3)
bilmt = CPUL1CACHE if bilmt > CPUL1CACHE
while bi < bilmt
cp = sb + (bi >> 3); msk = BITMASK[bi & 7]
while cp < cplmt # use pointer to save loop overhead
cp[0] |= msk; cp += bpi
end
bi += bpi
end
else
while bi < bitsz # bitsz
sb[bi >> 3] |= BITMASK[bi & 7]; bi += bpi
end
end } }
end
 
# Iterator over processed prime pages, polymorphic by the converter function...
private class PagedResults(T)
@bpas : BasePrimeArrays
@cmpsts : SieveBuffer
 
def initialize(@prmndx : PrimeNdx,
@cmpstsbitsz : Int32,
@cnvrtrfnc : (Int64, Int32, SieveBuffer) -> T)
@bpas = BasePrimeArrays.new
@cmpsts = SieveBuffer.malloc(((@cmpstsbitsz + 63) >> 3) & (-8))
end
 
private def dopage
(@prmndx..).step(@cmpstsbitsz.to_i64).map { |pn|
@cmpsts.clear(@cmpstsbitsz >> 3)
cull_page(pn, @cmpstsbitsz, @bpas.each, @cmpsts)
@cnvrtrfnc.call(pn, @cmpstsbitsz, @cmpsts) }
end
 
def each
dopage
end
 
def each(& : T -> _) : Nil
itr = dopage
while true
value = itr.next
break if value.is_a?(Iterator::Stop)
yield value
end
end
end
 
# Secondary memoized chain of BasePrime arrays (by small page size),
# which is actually a iterable lazy list (memoized) of BasePrimeArr;
# Crystal has closures, so it is easy to implement a LazyList class
# which memoizes the results of the thunk so it is only executed once...
private class BasePrimeArrays
@baseprmarr : BasePrimeArr # head of lezy list
@tail : BasePrimeArrays? = nil # tail starts as non-existing
 
def initialize # special case for first page of base primes
# converter of sieve buffer to base primes array...
sb2bparrprc = -> (pn : PrimeNdx, bl : Int32, sb : SieveBuffer) {
cnt = count_page_to(bl - 1, sb)
bparr = BasePrimeArr.new(cnt, 0); j = 0
bsprm = (pn + pn + 3).to_u32
bl.times.each { |i|
next if (sb[i >> 3] & BITMASK[i & 7]) != 0
bparr[j] = bsprm + (i + i).to_u32; j += 1 }
bparr }
 
cmpsts = SieveBuffer.malloc 128 # fake bparr for first iter...
frstbparr = sb2bparrprc.call(0_i64, 1024, cmpsts)
cull_page(0_i64, 1024, Iterator.of(frstbparr).each, cmpsts)
@baseprmarr = sb2bparrprc.call(0_i64, 1024, cmpsts)
 
# initialization of pages after the first is deferred to avoid data race...
initbpas = -> { PagedResults.new(1024_i64, 1024, sb2bparrprc).each }
# recursive LazyList generator function...
nxtbpa = uninitialized Proc(Iterator(BasePrimeArr), BasePrimeArrays)
nxtbpa = -> (bppgs : Iterator(BasePrimeArr)) {
nbparr = bppgs.next
abort "Unexpectedbase primes end!!!" if nbparr.is_a?(Iterator::Stop)
BasePrimeArrays.new(nbparr, ->{ nxtbpa.call(bppgs) }) }
@thunk = ->{ nxtbpa.call(initbpas.call) }
end
def initialize(@baseprmarr : BasePrimeArr, @thunk : Proc(BasePrimeArrays))
end
def initialize(@baseprmarr : BasePrimeArr, @thunk : Proc(Nil))
end
def initialize(@baseprmarr : BasePrimeArr, @thunk : Nil)
end
 
def tail # not thread safe without a lock/mutex...
if thnk = @thunk
@tail = thnk.call; @thunk = nil
end
@tail
end
 
private class BasePrimeArrIter # iterator over BasePrime arrays...
include Iterator(BasePrimeArr)
@dbparrs : Proc(BasePrimeArrays?)
 
def initialize(fromll : BasePrimeArrays)
@dbparrs = ->{ fromll.as(BasePrimeArrays?) }
end
 
def next
if bpas = @dbparrs.call
rslt = bpas.@baseprmarr; @dbparrs = -> { bpas.tail }; rslt
else
abort "Unexpected end of base primes array iteration!!!"
end
end
end
def each
BasePrimeArrIter.new(self)
end
end
 
# An "infinite" extensible iteration of primes,...
def primes
sb2prms = ->(pn : PrimeNdx, bitsz : Int32, sb : SieveBuffer) {
cnt = count_page_to(bitsz - 1, sb)
prmarr = PrimeArr.new(cnt, 0); j = 0
bsprm = (pn + pn + 3).to_u64
bitsz.times.each { |i|
next if (sb[i >> 3] & BITMASK[i & 7]) != 0
prmarr[j] = bsprm + (i + i).to_u64; j += 1 }
prmarr
}
(2_u64..2_u64).each
.chain PagedResults.new(0, CPUL1CACHE, sb2prms).each.flat_map { |prmspg| prmspg.each }
end
 
# Counts number of primes to given limit...
def primes_count_to(lmt : Prime)
if lmt < 3
lmt < 2 ? return 0 : return 1
end
lmtndx = ((lmt - 3) >> 1).to_i64
sb2cnt = ->(pn : PrimeNdx, bitsz : Int32, sb : SieveBuffer) {
pglmt = pn + bitsz.to_i64 - 1
if (pn + CPUL1CACHE.to_i64) > lmtndx
Tuple.new(count_page_to((lmtndx - pn).to_i32, sb).to_i64, pglmt)
else
Tuple.new(count_page_to(bitsz - 1, sb).to_i64, pglmt)
end
}
count = 1
PagedResults.new(0, CPUL1CACHE, sb2cnt).each { |(cnt, lmt)|
count += cnt; break if lmt >= lmtndx }
count
end
 
print "The primes up to 100 are: "
primes.each.take_while { |p| p <= 100_u64 }.each { |p| print " ", p }
print ".\r\nThe Number of primes up to a million is "
print primes.each.take_while { |p| p <= 1_000_000_u64 }.size
print ".\r\nThe number of primes up to a billion is "
start_time = Time.monotonic
# answr = primes.each.take_while { |p| p <= 1_000_000_000_u64 }.size # slow way
answr = primes_count_to(1_000_000_000) # fast way
elpsd = (Time.monotonic - start_time).total_milliseconds
print "#{answr} in #{elpsd} milliseconds.\r\n"</syntaxhighlight>
 
{{out}}
<pre>The primes up to 100 are: 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.
The Number of primes up to a million is 78498.
The number of primes up to a billion is 50847534 in 658.466028 milliseconds.</pre>
 
When run on the same machine as the previous version, the code is about seven and a half times as fast as even the above Odds-Only version at about 2.4 CPU clock cycles per culling operation rather than over 17, partly due to better cache associativity (about half the gain) but also due to tuning the inner culling loop for small base prime values to operate by byte pointer strides with a constant mask value to simplify the code generated for these inner loops; as there is some overhead in the eight outer loops that set this up, this technique is only applicable for smaller base primes.
 
Further gains are possible by using maximum wheel factorization rather than just factorization for odd base primes which can reduce the number of operations by a factor of about four and the number of CPU clock cycles per culling operation can be reduced by an average of a further about 25 percent for sieving to a billion by using extreme loop unrolling techniques for both the dense and sparse culling cases. As well, multi-threading by pages can reduce the wall clock time by a factor of the number of effective cores (non Hyper-Threaded cores).
 
=={{header|D}}==
===Simpler Version===
Prints all numbers less than the limit.<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.range, std.functional;
 
uint[] sieve(in uint limit) nothrow @safe {
Line 2,720 ⟶ 5,106:
void main() {
50.sieve.writeln;
}</langsyntaxhighlight>
{{out}}
<pre>[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]</pre>
Line 2,726 ⟶ 5,112:
===Faster Version===
This version uses an array of bits (instead of booleans, that are represented with one byte), and skips even numbers. The output is the same.
<langsyntaxhighlight lang="d">import std.stdio, std.math, std.array;
 
size_t[] sieve(in size_t m) pure nothrow @safe {
Line 2,764 ⟶ 5,150:
void main() {
50.sieve.writeln;
}</langsyntaxhighlight>
 
===Extensible Version===
(This version is used in the task [[Extensible prime generator#D|Extensible prime generator]].)
<langsyntaxhighlight lang="d">/// Extensible Sieve of Eratosthenes.
struct Prime {
uint[] a = [2];
Line 2,802 ⟶ 5,188:
uint.max.iota.map!prime.until!q{a > 50}.writeln;
}
}</langsyntaxhighlight>
To see the output (that is the same), compile with <code>-version=sieve_of_eratosthenes3_main</code>.
 
=={{header|Dart}}==
<langsyntaxhighlight lang="dart">// helper function to pretty print an Iterable
String iterableToString(Iterable seq) {
String str = "[";
Line 2,838 ⟶ 5,224:
print(iterableToString(sortedValues)); // expect sieve.length to be 168 up to 1000...
// Expect.equals(168, sieve.length);
}</langsyntaxhighlight>
{{out}}<pre>
Found 168 primes up to 1000 in 9 milliseconds.
Line 2,846 ⟶ 5,232:
 
===faster bit-packed array odds-only solution===
<langsyntaxhighlight lang="dart">import 'dart:typed_data';
import 'dart:math';
 
Line 2,878 ⟶ 5,264:
print("There were $answer primes found up to $range.");
print("This test bench took $elapsed milliseconds.");
}</langsyntaxhighlight>
{{output}}
<pre>( 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 )
Line 2,893 ⟶ 5,279:
The following code will have about O(n log (log n)) performance due to a hash table having O(1) average performance and is only somewhat slow due to the constant overhead of processing hashes:
 
<langsyntaxhighlight lang="dart">Iterable<int> primesMap() {
Iterable<int> oddprms() sync* {
yield(3); yield(5); // need at least 2 for initialization
Line 2,935 ⟶ 5,321:
print("There were $answer primes found up to $range.");
print("This test bench took $elapsed milliseconds.");
}</langsyntaxhighlight>
{{output}}
<pre>( 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 )
Line 2,951 ⟶ 5,337:
 
{{trans|Kotlin}}
<langsyntaxhighlight lang="dart">import 'dart:typed_data';
import 'dart:math';
import 'dart:collection';
Line 3,159 ⟶ 5,545:
print("There were $answer primes found up to $range.");
print("This test bench took $elapsed milliseconds.");
}</langsyntaxhighlight>
{{output}}
<pre>( 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 )
Line 3,171 ⟶ 5,557:
 
The algorithm can be sped up by a factor of four by extreme wheel factorization and (likely) about a factor of the effective number of CPU cores by using multi-processing isolates, but there isn't much point if one is to use the prime generator for output. For most purposes, it is better to use custom functions that directly manipulate the culled bit-packed page segments as `countPrimesTo` does here.
 
=={{header|dc}}==
 
<syntaxhighlight lang="dc">[dn[,]n dsx [d 1 r :a lx + d ln!<.] ds.x lx] ds@
[sn 2 [d;a 0=@ 1 + d ln!<#] ds#x] se
 
100 lex</syntaxhighlight>
{{out}}
<pre>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,</pre>
 
=={{header|Delphi}}==
<langsyntaxhighlight lang="delphi">program erathostenes;
 
{$APPTYPE CONSOLE}
Line 3,257 ⟶ 5,653:
Sieve.Free;
readln;
end.</langsyntaxhighlight>
Output:
<pre>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 </pre>
 
=={{header|Draco}}==
<syntaxhighlight lang="draco">/* Sieve of Eratosthenes - fill a given boolean array */
proc nonrec sieve([*] bool prime) void:
word p, c, max;
max := dim(prime,1)-1;
prime[0] := false;
prime[1] := false;
for p from 2 upto max do prime[p] := true od;
for p from 2 upto max>>1 do
if prime[p] then
for c from p*2 by p upto max do
prime[c] := false
od
fi
od
corp
 
/* Print primes up to 1000 using the sieve */
proc nonrec main() void:
word MAX = 1000;
unsigned MAX i;
byte c;
[MAX+1] bool prime;
sieve(prime);
 
c := 0;
for i from 0 upto MAX do
if prime[i] then
write(i:4);
c := c + 1;
if c=10 then c:=0; writeln() fi
fi
od
corp</syntaxhighlight>
{{out}}
<pre> 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 101 103 107 109 113
127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229
233 239 241 251 257 263 269 271 277 281
283 293 307 311 313 317 331 337 347 349
353 359 367 373 379 383 389 397 401 409
419 421 431 433 439 443 449 457 461 463
467 479 487 491 499 503 509 521 523 541
547 557 563 569 571 577 587 593 599 601
607 613 617 619 631 641 643 647 653 659
661 673 677 683 691 701 709 719 727 733
739 743 751 757 761 769 773 787 797 809
811 821 823 827 829 839 853 857 859 863
877 881 883 887 907 911 919 929 937 941
947 953 967 971 977 983 991 997</pre>
 
=={{header|DWScript}}==
 
<langsyntaxhighlight lang="delphi">function Primes(limit : Integer) : array of Integer;
var
n, k : Integer;
Line 3,284 ⟶ 5,732:
var i : Integer;
for i:=0 to r.High do
PrintLn(r[i]);</langsyntaxhighlight>
 
=={{header|Dylan}}==
With outer to sqrt and inner to p^2 optimizations:
<langsyntaxhighlight lang="dylan">define method primes(n)
let limit = floor(n ^ 0.5) + 1;
let sieve = make(limited(<simple-vector>, of: <boolean>), size: n + 1, fill: #t);
Line 3,311 ⟶ 5,759:
if (sieve[x]) format-out("Prime: %d\n", x); end;
end;
end;</langsyntaxhighlight>
 
 
=={{header|E}}==
Line 3,350 ⟶ 5,797:
 
=={{header|EasyLang}}==
<syntaxhighlight lang="text">
<lang>len prims[] 100
len is_divisible[] 100
max = round sqrt len prims[]
max = sqrt len is_divisible[]
tst = 2
whilefor tstd <= 2 to max
if primsis_divisible[tstd] = 0
for i = tstd * tstd step d to len is_divisible[]
while i < len prims is_divisible[i] = 1
prims[i] = 1.
i += tst.
.
.
tst += 1
.
for i = 2 to len is_divisible[]
i = 2
if is_divisible[i] = 0
while i < len prims[]
if prims[i] = 0 print i
print i.
.</syntaxhighlight>
.
i += 1
.</lang>
 
=={{header|eC}}==
{{incorrect|eC|It uses rem testing and so is a trial division algorithm, not a sieve of Eratosthenes.}}
Note: this is not a Sieve of Eratosthenes; it is just trial division.
<langsyntaxhighlight lang="cpp">
public class FindPrime
{
Line 3,418 ⟶ 5,860:
}
}
</syntaxhighlight>
</lang>
 
=={{header|EchoLisp}}==
===Sieve===
<langsyntaxhighlight lang="lisp">(require 'types) ;; bit-vector
 
;; converts sieve->list for integers in [nmin .. nmax[
Line 3,450 ⟶ 5,893:
→ (1000003 1000033 1000037 1000039 1000081 1000099)
(s-next-prime s-primes 9_000_000)
→ 9000011</langsyntaxhighlight>
 
===Segmented sieve===
Allow to extend the basis sieve (n) up to n^2. Memory requirement is O(√n)
<langsyntaxhighlight lang="scheme">;; ref : http://research.cs.wisc.edu/techreports/1990/TR909.pdf
;; delta multiple of sqrt(n)
;; segment is [left .. left+delta-1]
Line 3,487 ⟶ 5,930:
 
;; 8 msec using the native (prime?) function
(for/list ((p (in-range 1_000_000_000 1_000_001_000))) #:when (prime? p) p)</langsyntaxhighlight>
 
===Wheel===
A 2x3 wheel gives a 50% performance gain.
<langsyntaxhighlight lang="scheme">;; 2x3 wheel
(define (weratosthenes n)
(define primes (make-bit-vector n )) ;; everybody to #f (false)
Line 3,507 ⟶ 5,950:
(for ([j (in-range (* p p) n p)])
(bit-vector-set! primes j #f)))
primes)</langsyntaxhighlight>
 
=={{header|EDSAC order code}}==
This sieve program is based on one by Eiiti Wada, which on 2020-07-05 could be found at https://www.dcs.warwick.ac.uk/~edsac/
 
The main external change is that the program is not designed to be viewed in the monitor; it just writes as many primes as possible within the limitations imposed by Rosetta Code. Apart from the addition of comments, internal changes include the elimination of one set of masks, and a revised method of switching from one mask to another.
 
On the EdsacPC simulator (see link above) the printout starts off very slowly, and gradually gets faster.
<syntaxhighlight lang="edsac">
[Sieve of Eratosthenes]
[EDSAC program. Initial Orders 2]
 
[Memory usage:
56..87 library subroutine P6, for printing
88..222 main program
224..293 mask table: 35 long masks; each has 34 1's and a single 0
294..1023 array of bits for integers 2, 3, 4, ...,
where bit is changed from 1 to 0 when integer is crossed out.
The address of the mask table must be even, and clear of the main program.
To change it, just change the value after "T47K" below.
The address of the bit array will then be changed automatically.]
[Subroutine M3, prints header, terminated by blank row of tape.
It's an "interlude", which runs and then gets overwritten.]
PFGKIFAFRDLFUFOFE@A6FG@E8FEZPF
@&*SIEVE!OF!ERATOSTHENES!#2020
@&*BASED!ON!CODE!BY!EIITI!WADA!#2001
..PZ
 
[Subroutine P6, prints strictly positive integer.
32 locations; working locations 1, 4, 5.]
T 56 K
GKA3FT25@H29@VFT4DA3@TFH30@S6@T1FV4DU4DAFG26@TFTF
O5FA4DF4FS4FL4FT4DA1FS3@G9@EFSFO31@E20@J995FJF!F
 
[Store address of mask table in (say) location 47
(chosen because its code letter M is first letter of "Mask").
Address must be even and clear of main program.]
T 47 K
P 224 F [<-------- address of mask table]
 
[Main program]
T 88 K [Define load address for main program.
Must be even, because of long values at start.]
G K [set @ (theta) for relative addressing]
 
[Long constants]
T#Z PF TZ [clears sandwich digit between 0 and 1]
[0] PD PF [long value 1; also low word = short 1]
T2#Z PF T2Z [clears sandwich digit between 2 and 3]
[2] PF K4096F [long value 1000...000 binary;
also high word = teleprinter null]
 
[Short constants
The address in the following C order is the (exclusive) end of the bit table.
Must be even: max = 1024, min = M + 72 where M is address of mask table set up above.
Usually 1024, but may be reduced, e.g. to make the program run faster.]
[4] C1024 D [or e.g. C 326 D to make it much faster]
[5] U F ['U' = 'T' - 'C']
[6] K F ['K' = 'S' - 'C']
[7] H #M [H order for start of mask table]
[8] H 70#M [used to test for end of mask table]
[9] P 2 F [constant4, or 2 in address field]
[10] P 70 F [constant 140, or 70 in address field]
[11] @ F [carriage return]
[12] & F [line feed]
 
[Short variables]
[13] P 1 F [p = number under test
Let p = 35*q + r, where 0 <= r < 35]
[14] P F [4*q]
[15] P 4 F [4*r]
 
[Initial values of orders; required only for optional code below.]
[16] C 70#M [initial value of a variable C order]
[17] T #M [initial value of a variable T order]
[18] T 70#M [initial value of a variable T order]
 
[19]
[Enter with acc = 0]
 
[Optional code to do some initializing at run time.
This code allows the program to run again without being loaded again.]
A 7 @ [initial values of variable orders]
T 65 @
A 16 @
T 66 @
A 17 @
T 44 @
A 18 @
T 52 @
 
[Initialize variables]
A @ [load 1 (short)]
L D [shift left 1]
U 13 @ [p := 2]
L 1 F [shift left 2]
T 15 @ [4*r := 8]
T 14 @ [4*q := 0]
[End of optional code]
 
[Make table of 35 masks 111...110, 111...101, ..., 011...111
Treat the mask 011...111 separately to avoid accumulator overflow.
Assume acc = 0 here.]
S #@ [acc all 1's]
S 2 #@ [acc := 0111...111]
[35] T 68 #M [store at high end of mask table]
S #@ [acc := -1]
L D [make mask 111...1110]
G 43 @ [jump to store it
[Loop shifting the mask right and storing the result in the mask table.
Uses first entry of bit array as temporary store.]
[39] T F [clear acc]
A 70 #M [load previous mask]
L D [shift left]
A #@ [add 1]
[43] U 70 #M [update current mask]
[44] T #M [store it in table (order changed at run time)]
A 44 @ [load preceding T order]
A 9 @ [inc address by 2]
U 44 @ [store back]
S 35 @ [reached high entry yet?]
G 39 @ [loop back if not]
[Mask table is now complete]
 
[Initialize bit array: no numbers crossed out, so all bits are 1]
[50] T F [clear acc]
S #@ [subtract long 1, make top 35 bits all 1's]
[52] T 70 #M [store as long value, both words all 1's (order changed at run time)]
A 52 @ [load preceding order]
A 9 @ [add 2 to address field]
U 52 @ [and store back]
S 5 @ [convert to C order with same address (*)]
S 4 @ [test for end of bit array]
G 50 @ [loop until stored all 1's in bit table]
[(*) Done so that end of bit table can be stored at one place only
in list of constants, i.e. 'C m D' only, not 'T m D' as well.]
 
[Start of main loop.]
[Testing whether number has been crossed out]
[59] T F [acc := 0]
A 66 @ [deriving S order from C order]
A 6 @
T 64 @
S #@ [acc := -1]
[64] S F [acc := 1's complement of bit-table entry (order changed at run time)]
[65] H #M [mult reg := start of mask array (order changed at run time)]
[66] C 70#M [acc := -1 iff p (current number) is crossed out (order changed at run time)]
[The next order is to avoid accumulator overflow if acc = max positive number]
E 70 @ [if acc >= 0, jump to process new prime]
A #@ [if acc < 0, add 1 to test for -1]
E 106 @ [if acc now >= 0 number is crossed out, jump to test next]
[Here if new prime found.
Send it to the teleprinter]
[70] O 11 @ [print CR]
O 12 @ [print LF]
T F [clear acc]
A 13 @ [load prime]
T F [store in C(0) for print routine]
A 75 @ [for subroutine return]
G 56 F [print prime]
 
[Cross out its multiples by setting corresponding bits to 0]
A 65 @ [load H order above]
T 102 @ [plant in crossing-out loop]
A 66 @ [load C order above]
T1 03 @ [plant in crossing-out loop]
 
[Start of crossing-out loop. Here acc must = 0]
[81] A 102 @ [load H order below]
A 15 @ [inc address field by 2*r, where p = 35q + r]
U 102 @ [update H order]
S 8 @ [compare with 'H 70 #M']
G 93 @ [skip if not gone beyond end of mask table]
T F [wrap mask address and inc address in bit tsble]
A 102 @ [load H order below]
S 10 @ [reduce mask address by 70]
T 102 @ [update H order]
A 103 @ [load C order below]
A 9 @ [add 2 to address]
T 103 @ [update C order]
[93] T F [clear acc]
A 103 @ [load C order below]
A 14 @ [inc address field by 2*q, where p = 35q + r]
U 103 @ [update C order]
S 4 @ [test for end of bit array]
E 106 @ [if finished crossing out, loop to test next number]
A 4 @ [restore C order]
A 5 @ [make T order with same address]
T 104 @ [store below]
 
[Execute the crossing-out orders created above]
[102] X F [mult reg := mask (order created at run time)]
[103] X F [acc := logical and with bit-table entry (order created at run time)]
[104] X F [update entry (order created at run time)]
E 81 @ [loop back with acc = 0]
 
[106] T F [clear acc]
A 13 @ [load p = number under test]
A @ [add 1 (single)]
T 13 @ [update]
A 15 @ [load 4*r, where p = 35q + r]
A 9 @ [add 4]
U 15 @ [store back (r inc'd by 1)]
S 10 @ [is 4*r now >= 140?]
G 119 @ [no, skip]
T 15 @ [yes, reduce 4*r by 140]
A 14 @ [load 4*q]
A 9 @ [add 4]
T 14 @ [store back (q inc'd by 1)]
[119] T F [clear acc]
A 65 @ [load 'H ... D' order, which refers to a mask]
A 9 @ [inc mask address by 2]
U 65 @ [update order]
S 8 @ [over end of mask table?]
G 59 @ [no, skip wrapround code]
A 7 @ [yes, add constant to wrap round]
T 65 @ [update H order]
A 66 @
A 9 @ [inc address by 2]
U 66 @ [and store back]
S 4 @ [test for end, as defined by C order at start]
G 59 @ [loop back if not at end]
 
[Finished whole thing]
[132] O 3 @ [output null to flush teleprinter buffer]
Z F [stop]
E 19 Z [address to start execution]
P F [acc = 0 at start]
</syntaxhighlight>
{{out}}
<pre>
SIEVE OF ERATOSTHENES 2020
BASED ON CODE BY EIITI WADA 2001
2
3
5
7
11
13
17
[...]
12703
12713
12721
12739
12743
12757
12763
</pre>
 
=={{header|Eiffel}}==
{{works with|EiffelStudio|6.6 beta (with provisional loop syntax)}}
<langsyntaxhighlight lang="eiffel">class
APPLICATION
Line 3,545 ⟶ 6,237:
end
end
end</langsyntaxhighlight>
 
Output:
Line 3,553 ⟶ 6,245:
 
=={{header|Elixir}}==
<langsyntaxhighlight lang="elixir">defmodule Prime do
def eratosthenes(limit \\ 1000) do
sieve = [false, false | Enum.to_list(2..limit)] |> List.to_tuple
Line 3,577 ⟶ 6,269:
if x=elem(sieve, n), do: :io.format("~3w", [x]), else: :io.format(" .")
if rem(n+1, 20)==0, do: IO.puts ""
end)</langsyntaxhighlight>
 
{{out}}
Line 3,595 ⟶ 6,287:
Shorter version (but slow):
 
<langsyntaxhighlight lang="elixir">
defmodule Sieve do
def primes_to(limit), do: sieve(Enum.to_list(2..limit))
Line 3,602 ⟶ 6,294:
defp sieve([]), do: []
end
</syntaxhighlight>
</lang>
 
'''Alternate much faster odds-only version more suitable for immutable data structures using a (hash) Map'''
 
The above code has a very limited useful range due to being very slow: for example, to sieve to a million, even changing the algorithm to odds-only, requires over 800 thousand "copy-on-update" operations of the entire saved immutable tuple ("array") of 500 thousand bytes in size, making it very much a "toy" application. The following code overcomes that problem by using a (immutable/hashed) Map to store the record of the current state of the composite number chains resulting from each of the secondary streams of base primes, which are only 167 in number up to this range; it is a functional "incremental" Sieve of Eratosthenes implementation:
<langsyntaxhighlight lang="elixir">defmodule PrimesSoEMap do
@typep stt :: {integer, integer, integer, Enumerable.integer, %{integer => integer}}
 
Line 3,659 ⟶ 6,351:
|> (fn {t,ans} ->
IO.puts "There are #{ans} primes up to #{range}."
IO.puts "This test bench took #{t} microseconds." end).()</langsyntaxhighlight>
{{output}}
<pre>The first 25 primes are:
Line 3,673 ⟶ 6,365:
 
In order to save the computation time of computing the hashes, the following version uses a deferred execution Co-Inductive Stream type (constructed using Tuple's) in an infinite tree folding structure (by the `pairs` function):
<langsyntaxhighlight lang="elixir">defmodule PrimesSoETreeFolding do
@typep cis :: {integer, (() -> cis)}
@typep ciss :: {cis, (() -> ciss)}
Line 3,753 ⟶ 6,445:
|> (fn {t,ans} ->
IO.puts "There are #{ans} primes up to #{range}."
IO.puts "This test bench took #{t} microseconds." end).()</langsyntaxhighlight>
 
It's output is identical to the previous version other than the time required is less than half; however, it has a O(n (log n) (log (log n))) asymptotic computation complexity meaning that it gets slower with range faster than the above version. That said, it would take sieving to billions taking hours before the two would take about the same time.
 
=={{header|Elm}}==
 
===Elm with immutable arrays===
<syntaxhighlight lang="elm">
module PrimeArray exposing (main)
 
import Array exposing (Array, foldr, map, set)
import Html exposing (div, h1, p, text)
import Html.Attributes exposing (style)
 
 
{-
The Eratosthenes sieve task in Rosetta Code does not accept the use of modulo function (allthough Elm functions modBy and remainderBy work always correctly as they require type Int excluding type Float). Thus the solution needs an indexed work array as Elm has no indexes for lists.
 
In this method we need no division remainder calculations, as we just set the markings of non-primes into the array. We need the indexes that we know, where the marking of the non-primes shall be set.
 
Because everything is immutable in Elm, every change of array values will create a new array save the original array unchanged. That makes the program running slower or consuming more space of memory than with non-functional imperative languages. All conventional loops (for, while, until) are excluded in Elm because immutability requirement.
 
Live: https://ellie-app.com/pTHJyqXcHtpa1
-}
 
 
alist =
List.range 2 150
 
 
 
-- Work array contains integers 2 ... 149
 
 
workArray =
Array.fromList alist
 
 
n : Int
n =
List.length alist
 
 
 
-- The max index of integers used in search for primes
-- limit * limit < n
-- equal: limit <= √n
 
 
limit : Int
limit =
round (0.5 + sqrt (toFloat n))
 
-- Remove zero cells of the array
 
 
findZero : Int -> Bool
findZero =
\el -> el > 0
 
 
zeroFree : Array Int
zeroFree =
Array.filter findZero workResult
 
 
nrFoundPrimes =
Array.length zeroFree
 
 
workResult : Array Int
workResult =
loopI 2 limit workArray
 
 
 
{- As Elm has no loops (for, while, until)
we must use recursion instead!
The search of prime starts allways saving the
first found value (not setting zero) and continues setting the multiples of prime to zero.
Zero is no integer and may thus be used as marking of non-prime numbers. At the end, only the primes remain in the array and the zeroes are removed from the resulted array to be shown in Html.
-}
 
-- The recursion increasing variable i follows:
 
loopI : Int -> Int -> Array Int -> Array Int
loopI i imax arr =
if i > imax then
arr
 
else
let
arr2 =
phase i arr
in
loopI (i + 1) imax arr2
 
 
 
-- The helper function
 
 
phase : Int -> Array Int -> Array Int
phase i =
arrayMarker i (2 * i - 2) n
 
 
lastPrime =
Maybe.withDefault 0 <| Array.get (nrFoundPrimes - 1) zeroFree
 
 
outputArrayInt : Array Int -> String
outputArrayInt arr =
decorateString <|
foldr (++) "" <|
Array.map (\x -> String.fromInt x ++ " ") arr
 
 
decorateString : String -> String
decorateString str =
"[ " ++ str ++ "]"
 
 
 
-- Recursively marking the multiples of p with zero
-- This loop operates with constant p
 
 
arrayMarker : Int -> Int -> Int -> Array Int -> Array Int
arrayMarker p min max arr =
let
arr2 =
set min 0 arr
 
min2 =
min + p
in
if min < max then
arrayMarker p min2 max arr2
 
else
arr
 
 
main =
div [ style "margin" "2%" ]
[ h1 [] [ text "Sieve of Eratosthenes" ]
, text ("List of integers [2, ... ," ++ String.fromInt n ++ "]")
, p [] [ text ("Total integers " ++ String.fromInt n) ]
, p [] [ text ("Max prime of search " ++ String.fromInt limit) ]
, p [] [ text ("The largest found prime " ++ String.fromInt lastPrime) ]
, p [ style "color" "blue", style "font-size" "1.5em" ]
[ text (outputArrayInt zeroFree) ]
, p [] [ text ("Found " ++ String.fromInt nrFoundPrimes ++ " primes") ]
]
 
</syntaxhighlight>
 
{{out}}
<pre>
List of integers [2, ... ,149]
 
Total integers 149
 
Max prime of search 13
 
The largest found prime 149
 
[ 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 101 103 107 109 113 127 131 137 139 149 ]
 
Found 35 primes </pre>
 
===Concise Elm Immutable Array Version===
 
Although functional, the above code is written in quite an imperative style, so the following code is written in a more concise functional style and includes timing information for counting the number of primes to a million:
 
<syntaxhighlight lang="elm">module Main exposing (main)
 
import Browser exposing (element)
import Task exposing (Task, succeed, perform, andThen)
import Html exposing (Html, div, text)
import Time exposing (now, posixToMillis)
 
import Array exposing (repeat, get, set)
 
cLIMIT : Int
cLIMIT = 1000000
 
primesArray : Int -> List Int
primesArray n =
if n < 2 then [] else
let
sz = n + 1
loopbp bp arr =
let s = bp * bp in
if s >= sz then arr else
let tst = get bp arr |> Maybe.withDefault True in
if tst then loopbp (bp + 1) arr else
let
cullc c iarr =
if c >= sz then iarr else
cullc (c + bp) (set c True iarr)
in loopbp (bp + 1) (cullc s arr)
cmpsts = loopbp 2 (repeat sz False)
cnvt (i, t) = if t then Nothing else Just i
in cmpsts |> Array.toIndexedList
|> List.drop 2 -- skip the values for zero and one
|> List.filterMap cnvt -- primes are indexes of not composites
 
type alias Model = List String
 
type alias Msg = Model
 
test : (Int -> List Int) -> Int -> Cmd Msg
test primesf lmt =
let
to100 = primesf 100 |> List.map String.fromInt |> String.join ", "
to100str = "The primes to 100 are: " ++ to100
timemillis() = now |> andThen (succeed << posixToMillis)
in timemillis() |> andThen (\ strt ->
let cnt = primesf lmt |> List.length
in timemillis() |> andThen (\ stop ->
let answrstr = "Found " ++ (String.fromInt cnt) ++ " primes to "
++ (String.fromInt cLIMIT) ++ " in "
++ (String.fromInt (stop - strt)) ++ " milliseconds."
in succeed [to100str, answrstr] ) ) |> perform identity
 
main : Program () Model Msg
main =
element { init = \ _ -> ( [], test primesArray cLIMIT )
, update = \ msg _ -> (msg, Cmd.none)
, subscriptions = \ _ -> Sub.none
, view = div [] << List.map (div [] << List.singleton << text) }</syntaxhighlight>
{{out}}
<pre>The primes up to 100 are: 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.
Found 78498 primes to 1000000 in 958 milliseconds.</pre>
 
The above output is the contents of the HTML web page as shown with Google Chrome version 1.23 running on an AMD 7840HS CPU at 5.1 GHz (single thread boosted).
 
===Concise Elm Immutable Array Odds-Only Version===
 
The following code can replace the `primesArray` function in the above program and called from the testing and display code (two places):
 
<syntaxhighlight lang="elm">primesArrayOdds : Int -> List Int
primesArrayOdds n =
if n < 2 then [] else
let
sz = (n - 1) // 2
loopi i arr =
let s = (i + i) * (i + 3) + 3 in
if s >= sz then arr else
let tst = get i arr |> Maybe.withDefault True in
if tst then loopi (i + 1) arr else
let
bp = i + i + 3
cullc c iarr =
if c >= sz then iarr else
cullc (c + bp) (set c True iarr)
in loopi (i + 1) (cullc s arr)
cmpsts = loopi 0 (repeat sz False)
cnvt (i, t) = if t then Nothing else Just <| i + i + 3
oddprms = cmpsts |> Array.toIndexedList |> List.filterMap cnvt
in 2 :: oddprms</syntaxhighlight>
{{out}}
<pre>The primes up to 100 are: 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.
Found 78498 primes to 1000000 in 371 milliseconds.</pre>
 
The above output is the contents of the HTML web page as shown with Google Chrome version 1.23 running on an AMD 7840HS CPU at 5.1 GHz (single thread boosted).
 
===Richard Bird Tree Folding Elm Version===
 
The Elm language doesn't efficiently handle the Sieve of Eratosthenes (SoE) algorithm because it doesn't have directly accessible linear arrays (the Array module used above is based on a persistent tree of sub arrays) and also does Copy On Write (COW) for every write to every location as well as a logarithmic process of updating as a "tree" to minimize the COW operations. Thus, there is better performance implementing the Richard Bird Tree Folding functional algorithm, as follows:
{{trans|Haskell}}
<syntaxhighlight lang="elm">module Main exposing (main)
 
import Browser exposing (element)
import Task exposing (Task, succeed, perform, andThen)
import Html exposing (Html, div, text)
import Time exposing (now, posixToMillis)
 
cLIMIT : Int
cLIMIT = 1000000
 
type CIS a = CIS a (() -> CIS a)
 
uptoCIS2List : comparable -> CIS comparable -> List comparable
uptoCIS2List n cis =
let loop (CIS hd tl) lst =
if hd > n then List.reverse lst
else loop (tl()) (hd :: lst)
in loop cis []
 
countCISTo : comparable -> CIS comparable -> Int
countCISTo n cis =
let loop (CIS hd tl) cnt =
if hd > n then cnt else loop (tl()) (cnt + 1)
in loop cis 0
 
primesTreeFolding : () -> CIS Int
primesTreeFolding() =
let
merge (CIS x xtl as xs) (CIS y ytl as ys) =
case compare x y of
LT -> CIS x <| \ () -> merge (xtl()) ys
EQ -> CIS x <| \ () -> merge (xtl()) (ytl())
GT -> CIS y <| \ () -> merge xs (ytl())
pmult bp =
let adv = bp + bp
pmlt p = CIS p <| \ () -> pmlt (p + adv)
in pmlt (bp * bp)
allmlts (CIS bp bptl) =
CIS (pmult bp) <| \ () -> allmlts (bptl())
pairs (CIS frst tls) =
let (CIS scnd tlss) = tls()
in CIS (merge frst scnd) <| \ () -> pairs (tlss())
cmpsts (CIS (CIS hd tl) tls) =
CIS hd <| \ () -> merge (tl()) <| cmpsts <| pairs (tls())
testprm n (CIS hd tl as cs) =
if n < hd then CIS n <| \ () -> testprm (n + 2) cs
else testprm (n + 2) (tl())
oddprms() =
CIS 3 <| \ () -> testprm 5 <| cmpsts <| allmlts <| oddprms()
in CIS 2 <| \ () -> oddprms()
 
type alias Model = List String
 
type alias Msg = Model
 
test : (() -> CIS Int) -> Int -> Cmd Msg
test primesf lmt =
let
to100 = primesf() |> uptoCIS2List 100
|> List.map String.fromInt |> String.join ", "
to100str = "The primes to 100 are: " ++ to100
timemillis() = now |> andThen (succeed << posixToMillis)
in timemillis() |> andThen (\ strt ->
let cnt = primesf() |> countCISTo lmt
in timemillis() |> andThen (\ stop ->
let answrstr = "Found " ++ (String.fromInt cnt) ++ " primes to "
++ (String.fromInt cLIMIT) ++ " in "
++ (String.fromInt (stop - strt)) ++ " milliseconds."
in succeed [to100str, answrstr] ) ) |> perform identity
 
main : Program () Model Msg
main =
element { init = \ _ -> ( [], test primesTreeFolding cLIMIT )
, update = \ msg _ -> (msg, Cmd.none)
, subscriptions = \ _ -> Sub.none
, view = div [] << List.map (div [] << List.singleton << text) }</syntaxhighlight>
{{out}}
<pre>The primes up to 100 are: 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.
Found 78498 primes to 1000000 in 201 milliseconds.</pre>
 
The above output is the contents of the HTML web page as shown with Google Chrome version 1.23 running on an AMD 7840HS CPU at 5.1 GHz (single thread boosted).
 
===Elm Priority Queue Version===
 
Using a Binary Minimum Heap Priority Queue is a constant factor faster than the above code as the data structure is balanced rather than "heavy to the right" and requires less memory allocations/deallocation in the following code, which implements enough of the Priority Queue for the purpose. Just substitute the following code for `primesTreeFolding` and pass `primesPQ` as an argument to `test` rather than `primesTreeFolding`:
 
<syntaxhighlight lang="elm">type PriorityQ comparable v =
Mt
| Br comparable v (PriorityQ comparable v)
(PriorityQ comparable v)
 
emptyPQ : PriorityQ comparable v
emptyPQ = Mt
 
peekMinPQ : PriorityQ comparable v -> Maybe (comparable, v)
peekMinPQ pq = case pq of
(Br k v _ _) -> Just (k, v)
Mt -> Nothing
 
pushPQ : comparable -> v -> PriorityQ comparable v
-> PriorityQ comparable v
pushPQ wk wv pq =
case pq of
Mt -> Br wk wv Mt Mt
(Br vk vv pl pr) ->
if wk <= vk then Br wk wv (pushPQ vk vv pr) pl
else Br vk vv (pushPQ wk wv pr) pl
 
siftdown : comparable -> v -> PriorityQ comparable v
-> PriorityQ comparable v -> PriorityQ comparable v
siftdown wk wv pql pqr =
case pql of
Mt -> Br wk wv Mt Mt
(Br vkl vvl pll prl) ->
case pqr of
Mt -> if wk <= vkl then Br wk wv pql Mt
else Br vkl vvl (Br wk wv Mt Mt) Mt
(Br vkr vvr plr prr) ->
if wk <= vkl && wk <= vkr then Br wk wv pql pqr
else if vkl <= vkr then Br vkl vvl (siftdown wk wv pll prl) pqr
else Br vkr vvr pql (siftdown wk wv plr prr)
 
replaceMinPQ : comparable -> v -> PriorityQ comparable v
-> PriorityQ comparable v
replaceMinPQ wk wv pq = case pq of
Mt -> Mt
(Br _ _ pl pr) -> siftdown wk wv pl pr
 
primesPQ : () -> CIS Int
primesPQ() =
let
sieve n pq q (CIS bp bptl as bps) =
if n >= q then
let adv = bp + bp in let (CIS nbp _ as nbps) = bptl()
in sieve (n + 2) (pushPQ (q + adv) adv pq) (nbp * nbp) nbps
else let
(nxtc, _) = peekMinPQ pq |> Maybe.withDefault (q, 0) -- default when empty
adjust tpq =
let (c, adv) = peekMinPQ tpq |> Maybe.withDefault (0, 0)
in if c > n then tpq
else adjust (replaceMinPQ (c + adv) adv tpq)
in if n >= nxtc then sieve (n + 2) (adjust pq) q bps
else CIS n <| \ () -> sieve (n + 2) pq q bps
oddprms() = CIS 3 <| \ () -> sieve 5 emptyPQ 9 <| oddprms()
in CIS 2 <| \ () -> oddprms()</syntaxhighlight>
{{out}}
<pre>The primes up to 100 are: 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.
Found 78498 primes to 1000000 in 124 milliseconds.</pre>
 
The above output is the contents of the HTML web page as shown with Google Chrome version 1.23 running on an AMD 7840HS CPU at 5.1 GHz (single thread boosted).
 
=={{header|Emacs Lisp}}==
{{libheader|cl-lib}}
<lang lisp>
<syntaxhighlight lang="lisp">(defun sieve-set (limit)
(let ((xs (make-vector (1+ limit) 0)))
(cl-loop for i from 2 to limit
when (zerop (aref xs i))
collect i
and do (cl-loop for m from (* i i) to limit by i
do (aset xs m 1)))))</syntaxhighlight>
</lang>
 
Straightforward implementation of [http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Implementation sieve of Eratosthenes], 2 times faster:
 
<syntaxhighlight lang="lisp">(defun sieve (limit)
<lang lisp>
(defun sieve (limit)
(let ((xs (vconcat [0 0] (number-sequence 2 limit))))
(cl-loop for i from 2 to (sqrt limit)
when (aref xs i)
do (cl-loop for m from (* i i) to limit by i
do (aset xs m 0)))
(remove 0 xs)))</syntaxhighlight>
</lang>
 
=={{header|Erlang}}==
===Erlang using Dicts===
<syntaxhighlight lang="erlang">
{{incorrect|Erlang|See talk page.}}
<lang Erlang>
-module( sieve_of_eratosthenes ).
 
Line 3,800 ⟶ 6,909:
 
find_prime( error, _N, Acc ) -> Acc;
find_prime( {ok, _Value}, N, {Max, Dict} ) ->when {Max, lists:foldl(> fun dict:erase/2, Dict, lists:seq(N*N, Max, N) )}.->
{Max, lists:foldl( fun dict:erase/2, Dict, lists:seq(N*N, Max, N))};
</lang>
find_prime( {ok, _Value}, _, R) -> R.
</syntaxhighlight>
{{out}}
<pre>
Line 3,813 ⟶ 6,924:
Has the virtue of working for any -> N :)
 
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( sieve ).
-export( [main/1,primes/2] ).
Line 3,847 ⟶ 6,958:
Primes = lists:filter( fun({_,Y}) -> Y > 0 end, Tuples),
[ X || {X,_} <- Primes ].
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,861 ⟶ 6,972:
Since I had written a really odd and slow one, I thought I'd best do a better performer. Inspired by an example from https://github.com/jupp0r
 
<syntaxhighlight lang="erlang">
<lang Erlang>
 
-module(ossieve).
Line 3,887 ⟶ 6,998:
ResultSet = ordsets:add_element(2,sieve(Candidates,Candidates,ordsets:new(),N)),
io:fwrite("Sieved... ~w~n",[ResultSet]).
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,902 ⟶ 7,013:
A pure list comprehension approach.
 
<syntaxhighlight lang="erlang">
<lang Erlang>
-module(sieveof).
-export([main/1,primes/1, primes/2]).
Line 3,920 ⟶ 7,031:
remove([H | X], [H | Y]) -> remove(X, Y);
remove(X, [H | Y]) -> [H | remove(X, Y)].
</syntaxhighlight>
</lang>
{out}
<pre>
Line 3,935 ⟶ 7,046:
===Erlang ets + cpu distributed implementation ===
much faster previous erlang examples
<syntaxhighlight lang="erlang">
<lang Erlang>
#!/usr/bin/env escript
%% -*- erlang -*-
Line 4,000 ⟶ 7,111:
comp_i(J, I, N) when J =< N -> ets:insert(comp, {J, 1}), comp_i(J+I, I, N);
comp_i(J, _, N) when J > N -> ok.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 4,011 ⟶ 7,122:
 
=={{header|ERRE}}==
<syntaxhighlight lang="erre">
<lang ERRE>
PROGRAM SIEVE_ORG
! --------------------------------------------------
Line 4,041 ⟶ 7,152:
PRINT(COUNT%;" PRIMES")
END PROGRAM
</syntaxhighlight>
</lang>
{{out}}
last lines of the output screen
Line 4,052 ⟶ 7,163:
16301 16319 16333 16339 16349 16361 16363 16369 16381
1899 PRIMES
</pre>
 
=={{header|Euler}}==
The original Euler doesn't have loops built-in. Loops can easily be added by defining and calling suitable procedures with literal procedures as parameters. In this sample, a C-style "for" loop procedure is defined and used to sieve and print the primes.<br>
'''begin'''
'''new''' sieve; '''new''' for; '''new''' prime; '''new''' i;
for <- ` '''formal''' init; '''formal''' test; '''formal''' incr; '''formal''' body;
'''begin'''
'''label''' again;
init;
again: '''if''' test '''then''' '''begin''' body; incr; '''goto''' again '''end''' '''else''' 0
'''end'''
'
;
sieve <- ` '''formal''' n;
'''begin'''
'''new''' primes; '''new''' i; '''new''' i2; '''new''' j;
primes <- '''list''' n;
for( ` i <- 1 ', ` i <= n ', ` i <- i + 1 '
, ` primes[ i ] <- '''true''' '
);
primes[ 1 ] <- '''false''';
for( ` i <- 2 '
, ` [ i2 <- i * i ] <= n '
, ` i <- i + 1 '
, ` '''if''' primes[ i ] '''then'''
for( ` j <- i2 ', ` j <= n ', ` j <- j + i '
, ` primes[ j ] <- '''false''' '
)
'''else''' 0
'
);
primes
'''end'''
'
;
prime <- sieve( 30 );
for( ` i <- 1 ', ` i <= '''length''' prime ', ` i <- i + 1 '
, ` '''if''' prime[ i ] '''then''' '''out''' i '''else''' 0 '
)
'''end''' $
 
{{out}}
<pre>
NUMBER 2
NUMBER 3
NUMBER 5
NUMBER 7
NUMBER 11
NUMBER 13
NUMBER 17
NUMBER 19
NUMBER 23
NUMBER 29
</pre>
 
=={{header|Euphoria}}==
<langsyntaxhighlight lang="euphoria">constant limit = 1000
sequence flags,primes
flags = repeat(1, limit)
Line 4,072 ⟶ 7,241:
end if
end for
? primes</langsyntaxhighlight>
 
Output:
Line 4,087 ⟶ 7,256:
 
=={{header|F Sharp}}==
===Short with mutable state===
<syntaxhighlight lang="fsharp">
let primes max =
let mutable xs = [|2..max|]
let limit = max |> float |> sqrt |> int
for x in [|2..limit|] do
xs <- xs |> Array.except [|x*x..x..max|]
xs
</syntaxhighlight>
===Short Sweet Functional and Idiotmatic===
Well lists may not be lazy, but if you call it a sequence then it's a lazy list!
<langsyntaxhighlight lang="fsharp">
(*
An interesting implementation of The Sieve of Eratosthenes.
Line 4,102 ⟶ 7,280:
yield g; yield! fn (g - 1) g |> Seq.map2 (&&) ng |> Seq.cache |> fg }
Seq.initInfinite (fun x -> true) |> fg
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 4,128 ⟶ 7,306:
 
This is the idea behind Richard Bird's unbounded code presented in the Epilogue of [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf M. O'Neill's article] in Haskell. It is about twice as much code as the Haskell code because F# does not have a built-in lazy list so that the effect must be constructed using a Co-Inductive Stream (CIS) type since no memoization is required, along with the use of recursive functions in combination with sequences. The type inference needs some help with the new CIS type (including selecting the generic type for speed). Note the use of recursive functions to implement multiple non-sharing delayed generating base primes streams, which along with these being non-memoizing means that the entire primes stream is not held in memory as for the original Bird code:
<langsyntaxhighlight lang="fsharp">type 'a CIS = CIS of 'a * (unit -> 'a CIS) //'Co Inductive Stream for laziness
 
let primesBird() =
Line 4,143 ⟶ 7,321:
else minusat (n + 1u) (ctlf())
let rec baseprms() = CIS(2u, fun() -> baseprms() |> allmltps |> cmpsts |> minusat 3u)
Seq.unfold (fun (CIS(p, ptlf)) -> Some(p, ptlf())) (baseprms())</langsyntaxhighlight>
 
The above code sieves all numbers of two and up including all even numbers as per the page specification; the following code makes the very minor changes for an odds-only sieve, with a speedup of over a factor of two:
<langsyntaxhighlight lang="fsharp">type 'a CIS = CIS of 'a * (unit -> 'a CIS) //'Co Inductive Stream for laziness
 
let primesBirdOdds() =
Line 4,162 ⟶ 7,340:
else minusat (n + 2u) (ctlf())
let rec oddprms() = CIS(3u, fun() -> oddprms() |> allmltps |> cmpsts |> minusat 5u)
Seq.unfold (fun (CIS(p, ptlf)) -> Some(p, ptlf())) (CIS(2u, fun() -> oddprms()))</langsyntaxhighlight>
 
'''Tree Folding Sieve'''
 
The above code is still somewhat inefficient as it operates on a linear right extending structure that deepens linearly with increasing base primes (those up to the square root of the currently sieved number); the following code changes the structure into an infinite binary tree-like folding by combining each pair of prime composite streams before further processing as usual - this decreases the processing by approximately a factor of log n:
<langsyntaxhighlight lang="fsharp">type 'a CIS = CIS of 'a * (unit -> 'a CIS) //'Co Inductive Stream for laziness
 
let primesTreeFold() =
Line 4,185 ⟶ 7,363:
else minusat (n + 2u) (ctlf())
let rec oddprms() = CIS(3u, fun() -> oddprms() |> allmltps |> cmpsts |> minusat 5u)
Seq.unfold (fun (CIS(p, ptlf)) -> Some(p, ptlf())) (CIS(2u, fun() -> oddprms()))</langsyntaxhighlight>
 
The above code is over four times faster than the "BirdOdds" version (at least 10x faster than the first, "primesBird", producing the millionth prime) and is moderately useful for a range of the first million primes or so.
Line 4,192 ⟶ 7,370:
 
In order to investigate Priority Queue Sieves as espoused by O'Neill in the referenced article, one must find an equivalent implementation of a Min Heap Priority Queue as used by her. There is such an purely functional implementation [http://rosettacode.org/wiki/Priority_queue#Functional in RosettaCode translated from the Haskell code she used], from which the essential parts are duplicated here (Note that the key value is given an integer type in order to avoid the inefficiency of F# in generic comparison):
<langsyntaxhighlight lang="fsharp">[<RequireQualifiedAccess>]
module MinHeap =
 
Line 4,229 ⟶ 7,407:
 
let replaceMin wk wv = function | Mt -> Mt
| Br(_, ll, rr) -> siftdown wk wv ll rr</langsyntaxhighlight>
 
Except as noted for any individual code, all of the following codes need the following prefix code in order to implement the non-memoizing Co-Inductive Streams (CIS's) and to set the type of particular constants used in the codes to the same time as the "Prime" type:
<langsyntaxhighlight lang="fsharp">type CIS<'T> = struct val v: 'T val cont: unit -> CIS<'T> new(v,cont) = {v=v;cont=cont} end
type Prime = uint32
let frstprm = 2u
let frstoddprm = 3u
let inc1 = 1u
let inc = 2u</langsyntaxhighlight>
 
The F# equivalent to O'Neill's "odds-only" code is then implemented as follows, which needs the included changed prefix in order to change the primes type to a larger one to prevent overflow (as well the key type for the MinHeap needs to be changed from uint32 to uint64); it is functionally the same as the O'Neill code other than for minor changes to suit the use of CIS streams and the option output of the "peekMin" function:
<langsyntaxhighlight lang="fsharp">type CIS<'T> = struct val v: 'T val cont: unit -> CIS<'T> new(v,cont) = {v=v;cont=cont} end
type Prime = uint64
let frstprm = 2UL
Line 4,270 ⟶ 7,448:
let rec nxto i = CIS(i, fun() -> nxto (i + inc)) in nxto frstoddprm
Seq.unfold (fun (cis: CIS<Prime>) -> Some(cis.v, cis.cont()))
(CIS(frstprm, fun() -> (sieve odds)))</langsyntaxhighlight>
 
However, that algorithm suffers in speed and memory use due to over-eager adding of prime composite streams to the queue such that the queue used is much larger than it needs to be and a much larger range of primes number must be used in order to avoid numeric overflow on the square of the prime added to the queue. The following code corrects that by using a secondary (actually a multiple of) base primes streams which are constrained to be based on a prime that is no larger than the square root of the currently sieved number - this permits the use of much smaller Prime types as per the default prefix:
<langsyntaxhighlight lang="fsharp">let primesPQx() =
let rec nxtprm n pq q (bps: CIS<Prime>) =
if n >= q then let bp = bps.v in let adv = bp + bp
Line 4,292 ⟶ 7,470:
nxtprm (frstoddprm + inc) MinHeap.empty (frstoddprm * frstoddprm) (oddprms()))
Seq.unfold (fun (cis: CIS<Prime>) -> Some(cis.v, cis.cont()))
(CIS(frstprm, fun() -> (oddprms())))</langsyntaxhighlight>
 
The above code is well over five times faster than the previous translated O'Neill version for the given variety of reasons.
Line 4,310 ⟶ 7,488:
The following code is written in functional style other than it uses a mutable bit array to sieve the composites:
 
<langsyntaxhighlight lang="fsharp">let primes limit =
let buf = System.Collections.BitArray(int limit + 1, true)
let cull p = { p * p .. p .. limit } |> Seq.iter (fun c -> buf.[int c] <- false)
Line 4,320 ⟶ 7,498:
if argv = null || argv.Length = 0 then failwith "no command line argument for limit!!!"
printfn "%A" (primes (System.UInt32.Parse argv.[0]) |> Seq.length)
0 // return an integer exit code</langsyntaxhighlight>
 
Substituting the following minor changes to the code for the "primes" function will only deal with the odd prime candidates for a speed up of over a factor of two as well as a reduction of the buffer size by a factor of two:
 
<langsyntaxhighlight lang="fsharp">let primes limit =
let lmtb,lmtbsqrt = (limit - 3u) / 2u, (uint32 (sqrt (double limit)) - 3u) / 2u
let buf = System.Collections.BitArray(int lmtb + 1, true)
Line 4,332 ⟶ 7,510:
let oddprms = { 0u .. lmtb } |> Seq.map (fun i -> if buf.[int i] then i + i + 3u else 0u)
|> Seq.filter ((<>) 0u)
seq { yield 2u; yield! oddprms }</langsyntaxhighlight>
 
The following code uses other functional forms for the inner culling loops of the "primes function" to reduce the use of inefficient sequences so as to reduce the execution time by another factor of almost three:
 
<langsyntaxhighlight lang="fsharp">let primes limit =
let lmtb,lmtbsqrt = (limit - 3u) / 2u, (uint32 (sqrt (double limit)) - 3u) / 2u
let buf = System.Collections.BitArray(int lmtb + 1, true)
Line 4,343 ⟶ 7,521:
let rec cullp c = if c <= lmtb then buf.[int c] <- false; cullp (c + p)
(if buf.[int i] then cullp s); culltest (i + 1u) in culltest 0u
seq {yield 2u; for i = 0u to lmtb do if buf.[int i] then yield i + i + 3u }</langsyntaxhighlight>
 
Now much of the remaining execution time is just the time to enumerate the primes as can be seen by turning "primes" into a primes counting function by substituting the following for the last line in the above code doing the enumeration; this makes the code run about a further five times faster:
 
<langsyntaxhighlight lang="fsharp"> let rec count i acc =
if i > int lmtb then acc else if buf.[i] then count (i + 1) (acc + 1) else count (i + 1) acc
count 0 1</langsyntaxhighlight>
 
Since the final enumeration of primes is the main remaining bottleneck, it is worth using a "roll-your-own" enumeration implemented as an object expression so as to save many inefficiencies in the use of the built-in seq computational expression by substituting the following code for the last line of the previous codes, which will decrease the execution time by a factor of over three (instead of almost five for the counting-only version, making it almost as fast):
 
<langsyntaxhighlight lang="fsharp"> let nmrtr() =
let i = ref -2
let rec nxti() = i:=!i + 1;if !i <= int lmtb && not buf.[!i] then nxti() else !i <= int lmtb
Line 4,369 ⟶ 7,547:
member this.GetEnumerator() = nmrtr()
interface System.Collections.IEnumerable with
member this.GetEnumerator() = nmrtr() :> System.Collections.IEnumerator }</langsyntaxhighlight>
 
The various optimization techniques shown here can be used "jointly and severally" on any of the basic versions for various trade-offs between code complexity and performance. Not shown here are other techniques of making the sieve faster, including extending wheel factorization to much larger wheels such as 2/3/5/7, pre-culling the arrays, page segmentation, and multi-processing.
Line 4,377 ⟶ 7,555:
the following '''odds-only''' implmentations are written in an almost functional style avoiding the use of mutability except for the contents of the data structures uses to hold the state of the and any mutability necessary to implement a "roll-your-own" IEnumberable iterator interface for speed.
 
'''====Unbounded Dictionary (Mutable Hash Table) Based Sieve'''====
 
The following code uses the DotNet Dictionary class instead of the above functional Priority Queue to implement the sieve; as average (amortized) hash table access is O(1) rather than O(log n) as for the priority queue, this implementation is slightly faster than the priority queue version for the first million primes and will always be faster for any range above some low range value:
<langsyntaxhighlight lang="fsharp">type Prime = uint32
let frstprm = 2u
let frstoddprm = 3u
Line 4,405 ⟶ 7,583:
nxtprm (frstoddprm + inc) (frstoddprm * frstoddprm) (oddprms()))
Seq.unfold (fun (cis: CIS<Prime>) -> Some(cis.v, cis.cont()))
(CIS(frstprm, fun() -> (oddprms())))</langsyntaxhighlight>
 
The above code uses functional forms of code (with the imperative style commented out to show how it could be done imperatively) and also uses a recursive non-sharing secondary source of base primes just as for the Priority Queue version. As for the functional codes, the Primes type can easily be changed to "uint64" for wider range of sieving.
Line 4,411 ⟶ 7,589:
In spite of having true O(n log log n) Sieve of Eratosthenes computational complexity where n is the range of numbers to be sieved, the above code is still not particularly fast due to the time required to compute the hash values and manipulations of the hash table.
 
'''====Unbounded Page -Segmented Bit-Packed Odds-Only Mutable Array Sieve'''====
 
Note that the following code is used for the F# entry [[Extensible_prime_generator#Unbounded_Mutable_Array_Generator]] of the Extensible prime generator page.
All of the above unbounded implementations including the above Dictionary based version are quite slow due to their large constant factor computational overheads, making them more of an intellectual exercise than something practical, especially when larger sieving ranges are required. The following code implements an unbounded page segmented version of the sieve in not that many more lines of code, yet runs about 25 times faster than the Dictionary version for larger ranges of sieving such as to one billion; it uses functional forms without mutability other than for the contents of the arrays and a reference cell used to implement the "roll-your-own" IEnumerable/IEnumerator interfaces for speed:
 
<lang fsharp>let private PGSZBTS = (1 <<< 14) * 8 // sieve buffer size in bits
All of the above unbounded implementations including the above Dictionary based version are quite slow due to their large constant factor computational overheads, making them more of an intellectual exercise than something practical, especially when larger sieving ranges are required. The following code implements an unbounded page segmented version of the sieve in not that many more lines of code, yet runs about 25 times faster than the Dictionary version for larger ranges of sieving such as to one billion; it uses functional forms without mutability other than for the contents of the arrays and the `primes` enumeration generator function that must use mutability for speed:
type private PS = class
<syntaxhighlight lang="fsharp">type Prime = float // use uint64/int64 for regular 64-bit F#
val i:int val p:uint64 val cmpsts:uint32[]
type private PrimeNdx = float // they are slow in JavaScript polyfills
new(i,p,c) = { i=i; p=p; cmpsts=c } end
 
let rec primesPaged(): System.Collections.Generic.IEnumerable<_> =
let inline private prime n = float n // match these convenience conversions
let lbpse = lazy (primesPaged().GetEnumerator()) // lazy to prevent race
let inline private primendx n = float n // with the types above!
let bpa = ResizeArray() // fills from above sequence as needed
 
let makePg low =
let private cPGSZBTS = (1 <<< 14) * 8 // sieve buffer size in bits = CPUL1CACHE
let nxt = low + (uint64 PGSZBTS <<< 1)
 
let cmpsts = Array.zeroCreate (PGSZBTS >>> 5)
type private SieveBuffer = uint8[]
let inline notprm c = cmpsts.[c >>> 5] &&& (1u <<< c) <> 0u
 
let rec nxti c = if c < PGSZBTS && notprm c
/// a Co-Inductive Stream (CIS) of an "infinite" non-memoized series...
then nxti (c + 1) else c
type private CIS<'T> = CIS of 'T * (unit -> CIS<'T>) //' apostrophe formatting adjustment
let inline mrkc c = let w = c >>> 5
 
cmpsts.[w] <- cmpsts.[w] ||| (1u <<< c)
/// lazy list (memoized) series of base prime page arrays...
let rec cullf i =
type private BasePrime = uint32
if notprm i then cullf (i + 1) else
type private BasePrimeArr = BasePrime[]
let p = 3 + i + i in let sqr = p * p
type private BasePrimeArrs = BasePrimeArrs of BasePrimeArr * Option<Lazy<BasePrimeArrs>>
if uint64 sqr < nxt then
 
let rec cullp c = if c < PGSZBTS then mrkc c; cullp (c + p)
/// Masking array is faster than bit twiddle bit shifts!
else cullf (i + 1) in cullp ((sqr - 3) >>> 1)
let private cBITMASK = [| 1uy; 2uy; 4uy; 8uy; 16uy; 32uy; 64uy; 128uy |]
if low <= 3UL then cullf 0 // special culling for the first page
 
else // cull rest based on a secondary base prime stream
let private cullSieveBuffer lwi (bpas: BasePrimeArrs) (sb: SieveBuffer) =
let bpse = lbpse.Force()
let btlmt = (sb.Length <<< 3) - 1 in let lmti = lwi + primendx btlmt
if bpa.Count <= 0 then // move past 2 to 3
let rec loopbp (BasePrimeArrs(bpa, bpatl) as ibpas) i =
bpse.MoveNext() |> ignore; bpse.MoveNext() |> ignore
if i let>= rec fill np =bpa.Length then
match bpatl with
if np * np >= nxt then
| None -> let bpasz = bpa.Count()
| Some lv -> letloopbp reclv.Value cull0 i =else
let bp = prime bpa.[i] in let bpndx = primendx ((bp - prime 3) / prime 2)
if i < bpasz then
let s = (bpndx * primendx 2) * (bpndx + letprimendx p3) =+ bpa.[i] in let sqr = p *primendx p3 in let pibpint = int pbp
let strt = if sqrs ><= lowlmti then int (sqr - low) >>> 1
let s0 = // page cull start address calculation...
else let r = int (((low - sqr) >>> 1) % p)
if rs >= 0lwi then 0 else int p(s - rlwi) else
let rec cullp cr = if(lwi c- <s) PGSZBTS then mrkc c; cullp% (c +primendx pibp)
if r = primendx 0 then cullp0 strt;else cullint (ibp +- 1prime r) in cull 0
let slmt = min btlmt (s0 - 1 + (bpint <<< 3))
else bpa.Add(np); bpse.MoveNext() |> ignore
let rec loopc c = // loop fill"unpeeling" bpse.Currentis used so
if c <= slmt then // a constant mask can be used over the inner loop
fill bpse.Current // fill pba as necessary and do cull
let ni = nxti 0 in let npmsk = low + uint64 (nicBITMASK.[c <<<&&& 1)7]
let rec loopw w =
PS(ni, np, cmpsts)
if w < sb.Length then sb.[w] <- sb.[w] ||| msk; loopw (w + bpint)
let nmrtr() =
loopw (c >>> 3); loopc (c + bpint)
let ps = ref (PS(0, 0UL, Array.zeroCreate 0))
loopc s0; loopbp ibpas (i + 1) in loopbp bpas 0
{ new System.Collections.Generic.IEnumerator<_> with
 
member this.Current = (!ps).p
/// fast Counting Look Up Table (CLUT) for pop counting...
interface System.Collections.IEnumerator with
let private cCLUT =
member this.Current = box ((!ps).p)
let arr = Array.zeroCreate 65536
member this.MoveNext() =
let rec popcnt n cnt = if n let> drps0 =then !pspopcnt in(n let&&& i(n =- drps.i1)) in(cnt let+ p1) =else uint8 drps.pcnt
let rec loop i = if i < let65536 cmpsts =then drpsarr.cmpsts[i] in<- letpopcnt lmti =0; cmpsts.Lengthloop <<<(i + 51)
loop 0; arr
if p < 3UL then (if p < 2UL then ps := PS(0, 2UL, cmpsts); true
 
else ps := makePg 3UL; true) else
let countSieveBuffer ndxlmt (sb: SieveBuffer): int =
let inline notprm c = cmpsts.[c >>> 5] &&& (1u <<< c) <> 0u
let rec nxti clstw = if(ndxlmt c>>> < lmt3) &&& notprm c-2
let msk = (-2 <<< (ndxlmt &&& 15)) &&& 0xFFFF
then nxti (c + 1) else c
let inline cntem i m =
let ni = nxti (i + 1) in let np = p + uint64 ((ni - i) <<< 1)
int cCLUT.[int (((uint32 sb.[i + 1]) <<< 8) + uint32 sb.[i]) ||| m]
if ni < lmt then ps := PS(ni, np, cmpsts); true
let rec loop i cnt =
else ps := makePg np; true
if i >= lstw then cnt - cntem lstw msk else loop (i + 2) (cnt - cntem i 0)
member this.Reset() = failwith "IEnumerator.Reset() not implemented!!!"
loop 0 ((lstw <<< 3) + 16)
interface System.IDisposable with
 
member this.Dispose() = () }
/// a CIS series of pages from the given start index with the given SieveBuffer size,
{ new System.Collections.Generic.IEnumerable<_> with
/// and provided with a polymorphic converter function to produce
member this.GetEnumerator() = nmrtr()
/// and type of result from the culled page parameters...
interface System.Collections.IEnumerable with
let rec private makePrimePages strtwi btsz
member this.GetEnumerator() = nmrtr() :> System.Collections.IEnumerator }</lang>
(cnvrtrf: PrimeNdx -> SieveBuffer -> 'T): CIS<'T> =
let bpas = makeBasePrimes() in let sb = Array.zeroCreate (btsz >>> 3)
let rec nxtpg lwi =
Array.fill sb 0 sb.Length 0uy; cullSieveBuffer lwi bpas sb
CIS(cnvrtrf lwi sb, fun() -> nxtpg (lwi + primendx btsz))
nxtpg strtwi
 
/// secondary feed of lazy list of memoized pages of base primes...
and private makeBasePrimes(): BasePrimeArrs =
let sb2bpa lwi (sb: SieveBuffer) =
let bsbp = uint32 (primendx 3 + lwi + lwi)
let arr = Array.zeroCreate <| countSieveBuffer 255 sb
let rec loop i j =
if i < 256 then
if sb.[i >>> 3] &&& cBITMASK.[i &&& 7] <> 0uy then loop (i + 1) j
else arr.[j] <- bsbp + uint32 (i + i); loop (i + 1) (j + 1)
loop 0 0; arr
// finding the first page as not part of the loop and making succeeding
// pages lazy breaks the recursive data race!
let frstsb = Array.zeroCreate 32
let fkbpas = BasePrimeArrs(sb2bpa (primendx 0) frstsb, None)
cullSieveBuffer (primendx 0) fkbpas frstsb
let rec nxtbpas (CIS(bpa, tlf)) = BasePrimeArrs(bpa, Some(lazy (nxtbpas (tlf()))))
BasePrimeArrs(sb2bpa (primendx 0) frstsb,
Some(lazy (nxtbpas <| makePrimePages (primendx 256) 256 sb2bpa)))
 
/// produces a generator of primes; uses mutability for better speed...
let primes(): unit -> Prime =
let sb2prms lwi (sb: SieveBuffer) = lwi, sb in let mutable ndx = -1
let (CIS((nlwi, nsb), npgtlf)) = // use page generator function above!
makePrimePages (primendx 0) cPGSZBTS sb2prms
let mutable lwi = nlwi in let mutable sb = nsb
let mutable pgtlf = npgtlf
let mutable baseprm = prime 3 + prime (lwi + lwi)
fun() ->
if ndx < 0 then ndx <- 0; prime 2 else
let inline notprm i = sb.[i >>> 3] &&& cBITMASK.[i &&& 7] <> 0uy
while ndx < cPGSZBTS && notprm ndx do ndx <- ndx + 1
if ndx >= cPGSZBTS then // get next page if over
let (CIS((nlwi, nsb), npgtlf)) = pgtlf() in ndx <- 0
lwi <- nlwi; sb <- nsb; pgtlf <- npgtlf
baseprm <- prime 3 + prime (lwi + lwi)
while notprm ndx do ndx <- ndx + 1
let ni = ndx in ndx <- ndx + 1 // ready for next call!
baseprm + prime (ni + ni)
 
let countPrimesTo (limit: Prime): int = // much faster!
if limit < prime 3 then (if limit < prime 2 then 0 else 1) else
let topndx = (limit - prime 3) / prime 2 |> primendx
let sb2cnt lwi (sb: SieveBuffer) =
let btlmt = (sb.Length <<< 3) - 1 in let lmti = lwi + primendx btlmt
countSieveBuffer
(if lmti < topndx then btlmt else int (topndx - lwi)) sb, lmti
let rec loop (CIS((cnt, nxti), tlf)) count =
if nxti < topndx then loop (tlf()) (count + cnt)
else count + cnt
loop <| makePrimePages (primendx 0) cPGSZBTS sb2cnt <| 1
 
/// sequences are convenient but slow...
let primesSeq() = primes() |> Seq.unfold (fun gen -> Some(gen(), gen))
printfn "The first 25 primes are: %s"
( primesSeq() |> Seq.take 25
|> Seq.fold (fun s p -> s + string p + " ") "" )
printfn "There are %d primes up to a million."
( primesSeq() |> Seq.takeWhile ((>=) (prime 1000000)) |> Seq.length )
 
let rec cntto gen lmt cnt = // faster than seq's but still slow
if gen() > lmt then cnt else cntto gen lmt (cnt + 1)
 
let limit = prime 1_000_000_000
let start = System.DateTime.Now.Ticks
// let answr = cntto (primes()) limit 0 // slower way!
let answr = countPrimesTo limit // over twice as fast way!
let elpsd = (System.DateTime.Now.Ticks - start) / 10000L
printfn "Found %d primes to %A in %d milliseconds." answr limit elpsd</syntaxhighlight>
 
{{out}}
<pre>The first 25 primes are: 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
There are 78498 primes up to a million.
Found 50847534 primes to 1000000000 in 2161 milliseconds.</pre>
 
As with all of the efficient unbounded sieves, the above code uses a secondary enumerator of the base primes less than the square root of the currently culled range ("lbpse"), which is this case is a lazy (deffereddeferred memoized evaluation) binding by small pages of base primes which also uses the laziness of the deferral of subsequent pages so as to avoid a race condition.
 
The above code is written to output the "uint64" type for very large ranges of primes since there is little computational cost to doing this for this algorithm when used with 64-bit compilation; however, for the Fable transpiled to JavaScript, the largest contiguous integer that can be represented is the 64-bit floating point mantissa of 52 bits and thus the large numbers can be represented by floats in this case since a 64-bit polyfill is very slow. As written, the practical range for this sieve is about 16 billion, however, it can be extended to about 10^14 (a week or two of execution time) by setting the "PGSZBTS" constant to the size of the CPU L2 cache rather than the L1 cache (L2 is up to about two Megabytes for modern high end desktop CPU's) at a slight loss of efficiency (a factor of up to two or so) per composite number culling operation due to the slower memory access time. When the Fable compilation option is used, execution speed is roughly the same as using F# with DotNet Core.
 
Even with the custom IEnumerable/IEnumerator`primes` interfacesenumerator using an object expressiongenerator (the F#/Fable built-in sequence operators are terribly inefficient), the time to enumerate the resulting primes takes longer than the time to actually cull the composite numbers from the sieving arrays. The time to do the actual culling is thus over 50 times faster than done using the Dictionary version. The slowness of enumeration, no matter what further tweaks are done to improve it (each value enumerated will always take a function calls and a scan loop that will always take something in the order of 100 CPU clock cycles per value), means that further gains in speed using extreme wheel factorization and multi-processing have little point unless the actual work on the resulting primes is done through use of auxiliary functions not using iteration. Such a function is provided here to count the primes by pages using a "pop count" look up table to reduce the counting time to only a small fraction of a second.
 
=={{header|Factor}}==
Line 4,491 ⟶ 7,749:
 
Factor is pleasantly multiparadigm. Usually, it's natural to write more functional or declarative code in Factor, but this is an instance where it is more natural to write imperative code. Lexical variables are useful here for expressing the necessary mutations in a clean way.
<langsyntaxhighlight lang="factor">USING: bit-arrays io kernel locals math math.functions
math.ranges prettyprint sequences ;
IN: rosetta-code.sieve-of-erato
Line 4,522 ⟶ 7,780:
120 sieve . ;
 
MAIN: sieve-demo</langsyntaxhighlight>
 
=={{header|FōrmulæFOCAL}}==
<syntaxhighlight lang="focal">1.1 T "PLEASE ENTER LIMIT"
1.2 A N
1.3 I (2047-N)5.1
1.4 D 2
1.5 Q
 
2.1 F X=2,FSQT(N); D 3
2.2 F W=2,N; I (SIEVE(W)-2)4.1
 
3.1 I (-SIEVE(X))3.3
In [http://wiki.formulae.org/Sieve_of_Eratosthenes this] page you can see the solution of this task.
3.2 F Y=X*X,X,N; S SIEVE(Y)=2
3.3 R
 
4.1 T %4.0,W,!
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text ([http://wiki.formulae.org/Editing_F%C5%8Drmul%C3%A6_expressions more info]). Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for transportation effects more than visualization and edition.
 
5.1 T "PLEASE ENTER A NUMBER LESS THAN 2048."!; G 1.1</syntaxhighlight>
The option to show Fōrmulæ programs and their results is showing images. Unfortunately images cannot be uploaded in Rosetta Code.
Note that with the 4k paper tape version of FOCAL, the program will run out of memory for N>190 or so.
 
=={{header|Forth}}==
Line 4,553 ⟶ 7,822:
100 sieve
 
{{out}}
<pre>Primes: 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 </pre>
 
===Alternate Odds-Only, Better Style===
 
The above code is not really very good Forth style as the main initialization, sieving, and output, are all in one `sieve` routine which makes it difficult to understand and refactor; Forth code is normally written in a series of very small routines which makes it easier to understand what is happening on the data stack, since Forth does not have named local re-entrant variable names as most other languages do for local variables (which other languages also normally store local variables on the stack). Also, it uses the `HERE` pointer to user space which points to the next available memory after all compilation is done as a unsized buffer pointer, but as it does not reserve that space for the sieving buffer, it can be changed by other concatenated routines in unexpected ways; better is to allocate the sieving buffer as required from the available space at the time the routines are run and pass that address between concatenated functions until a finalization function frees the memory and clears the stack; this is equivalent to allocating from the "heap" in other languages. The below code demonstrates these ideas:
 
<syntaxhighlight lang="forth">: prime? ( addr -- ? ) C@ 0= ; \ test composites array for prime
 
\ given square index and prime index, u0, sieve the multiples of said prime...
: cullpi! ( u addr u u0 -- u addr u0 )
DUP DUP + 3 + ROT 4 PICK SWAP \ -- numv addr i prm numv sqri
DO 2 PICK I + TRUE SWAP C! DUP +LOOP DROP ;
 
\ process for required prime limit; allocate and initialize returned buffer...
: initsieve ( u -- u a-addr)
3 - DUP 0< IF 0 ELSE
1 RSHIFT 1+ DUP ALLOCATE 0<> IF ABORT" Memory allocation error!!!"
ELSE 2DUP SWAP ERASE THEN
THEN ;
 
\ pass through sieving to given index in given buffer address as side effect...
: sieve ( u a-addr -- u a-addr )
0 \ initialize test index i -- numv bufa i
BEGIN \ test prime square index < limit
DUP DUP DUP + SWAP 3 + * 3 + TUCK 4 PICK SWAP > \ sqri = 2*i * (I+3) + 3
WHILE \ -- numv bufa sqri i
2 PICK OVER + prime? IF cullpi! \ -- numv bufa i
ELSE SWAP DROP THEN 1+ \ -- numv bufa ni
REPEAT 2DROP ; \ -- numv bufa; drop sqri i
 
\ print primes to given limit...
: .primes ( u a-addr -- )
OVER 0< IF DROP 2 - 0< IF ( ." No primes!" ) ELSE ( ." Prime: 2" ) THEN
ELSE ." Primes: 2 " SWAP 0
DO DUP I + prime? IF I I + 3 + . THEN LOOP FREE DROP THEN ;
 
\ count number of primes found for number odd numbers within
\ given presumed sieved buffer starting at address...
: countprimes@ ( u a-addr -- )
SWAP DUP 0< IF 1+ 0< IF DROP 0 ELSE 1 THEN
ELSE 1 SWAP \ -- bufa cnt numv
0 DO OVER I + prime? IF 1+ THEN LOOP SWAP FREE DROP
THEN ;
 
\ shows counted number of primes to the given limit...
: .countprimesto ( u -- )
DUP initsieve sieve countprimes@
CR ." Found " . ." primes Up to the " . ." limit." ;
 
\ testing the code...
100 initsieve sieve .primes
1000000 .countprimesto</syntaxhighlight>
 
{{out}}
 
<pre>Primes: 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
Found 78498 primes Up to the 1000000 limit.</pre>
 
As well as solving the stated problems making it much easier to understand and refactor, an odds-only sieve takes half the space and less than half the time.
 
===Bit-Packing the Sieve Buffer (Odds-Only)===
 
Although the above version resolves many problems of the first version, it is wasteful of memory as each composite number in the sieve buffer is a byte of eight bits representing a boolean value. The memory required can be reduced eight-fold by bit packing the sieve buffer; this will take more "bit-twiddling" to read and write the bits, but reducing the memory used will give better cache assiciativity to larger ranges such that there will be a net gain in performance. This will make the code more complex and the stack manipulations will be harder to write, debug, and maintain, so ANS Forth 1994 provides a local variable naming facility to make this much easier. The following code implements bit-packing of the sieve buffer using local named variables when required:
 
<syntaxhighlight lang="text">\ produces number of one bits in given word...
: numbts ( u -- u ) \ pop count number of bits...
0 SWAP BEGIN DUP 0<> WHILE SWAP 1+ SWAP DUP 1- AND REPEAT DROP ;
 
\ constants for variable 32/64 etc. CELL size...
1 CELLS 3 LSHIFT 1- CONSTANT CellMsk
CellMsk numbts CONSTANT CellShft
 
CREATE bits 8 ALLOT \ bit position Look Up Table...
: mkbts 8 0 DO 1 I LSHIFT I bits + c! LOOP ; mkbts
 
\ test bit index composites array for prime...
: prime? ( u addr -- ? )
OVER 3 RSHIFT + C@ SWAP 7 AND bits + C@ AND 0= ;
 
\ given square index and prime index, u0, sieve the multiples of said prime...
: cullpi! ( u addr u u0 -- u addr u0 )
DUP DUP + 3 + ROT 4 PICK SWAP \ -- numv addr i prm numv sqri
DO I 3 RSHIFT 3 PICK + DUP C@ I 7 AND bits + C@ OR SWAP C! DUP +LOOP
DROP ;
 
\ initializes sieve storage and parameters
\ given sieve limit, returns bit limit and buffer address ..
: initsieve ( u -- u a-addr )
3 - \ test limit...
DUP 0< IF 0 ELSE \ return if number of bits is <= 0!
1 RSHIFT 1+ \ finish conbersion to number of bits
DUP 1- CellShft RSHIFT 1+ \ round up to even number of cells
CELLS DUP ALLOCATE 0= IF DUP ROT ERASE \ set cells0. to zero
ELSE ABORT" Memory allocation error!!!"
THEN
THEN ;
 
\ pass through sieving to given index in given buffer address as side effect...
: sieve ( u a-addr -- u a-addr )
0 \ initialize test index i -- numv bufa i
BEGIN \ test prime square index < limit
DUP DUP DUP + SWAP 3 + * 3 + TUCK 4 PICK SWAP > \ sqri = 2*i * (I+3) + 3
WHILE \ -- numv bufa sqri i
DUP 3 PICK prime? IF cullpi! \ -- numv bufa i
ELSE SWAP DROP THEN 1+ \ -- numv bufa ni
REPEAT 2DROP ; \ -- numv bufa; drop sqri i
 
\ prints already found primes from sieved array...
: .primes ( u a-addr -- )
SWAP CR ." Primes to " DUP DUP + 2 + 2 MAX . ." are: "
DUP 0< IF 1+ 0< IF ." none." ELSE 2 . THEN DROP \ case no primes or just 2
ELSE 2 . 0 DO I OVER prime? IF I I + 3 + . THEN LOOP FREE DROP
THEN ;
 
\ pop count style Look Up Table by 16 bits entry;
\ is a 65536 byte array containing number of zero bits for each index...
CREATE cntLUT16 65536 ALLOT
: mkpop ( u -- u ) numbts 16 SWAP - ;
: initLUT ( -- ) cntLUT16 65536 0 DO I mkpop OVER I + C! LOOP DROP ; initLUT
: popcount@ ( u -- u )
0 1 CELlS 1 RSHIFT 0
DO OVER 65535 AND cntLUT16 + C@ + SWAP 16 RSHIFT SWAP LOOP SWAP DROP ;
 
\ count number of zero bits up to given bits index-1 in array address;
\ params are number of bits used - bits, negative indicates <2/2 out: 0/1,
\ given address is of the allocated bit buffer - bufa;
\ values used: bmsk is bit mask to limit bit in last cell,
\ lci is cell index of last cell used, cnt is the return value...
\ NOTE. this is for little-endian; big-endian needs a byte swap
\ before the last mask and popcount operation!!!
: primecount@ ( u a-addr -- u )
LOCALS| bufa numb |
numb 0< IF numb 1+ 0< IF 0 ELSE 1 THEN \ < 3 -> <2/2 -> 0/1!
ELSE
numb 1- TO numb \ numb -= 1
1 \ initial count
numb CellShft RSHIFT CELLS TUCK \ lci = byte index of CELL including numv
0 ?DO bufa I + @ popcount@ + 1 CELLS +LOOP \ -- lci cnt
SWAP bufa + @ \ -- cnt lstCELL
-2 numb CellMsk AND LSHIFT OR \ bmsk for last CELL -- cnt mskdCELL
popcount@ + \ add popcount of last masked CELL -- cnt
bufa FREE DROP \ free bufa -- bmsk cnt lastcell@
THEN ;
 
: .countprimesto ( u -- u )
dup initsieve sieve primecount@
CR ." There are " . ." primes Up to the " . ." limit." ;
 
100 initsieve sieve .primes
1000000000 .countprimesto</syntaxhighlight>
 
The output of the above code is the same as the previous version, but it takes about two thirds the time while using eight times less memory; it takes about 6.5 seconds on my Intel Skylake i5-6500 at 3.6 GHz (turbo) using swiftForth (32-bit) and about 3.5 seconds on VFX Forth (64-bit), both of which compile to machine code but with the latter much more optimized; gforth-fast is about twice as slow as swiftForth and five times slower then VFX Forth as it just compiles to threaded execution tokens (more like an interpreter).
 
===Page-Segmented Bit-Packed Odds-Only Version===
 
While the above version does greatly reduce the amount of memory used for a given sieving range and thereby also somewhat reduces execution time; any sieve intended for sieving to limits of a hundred million or more should use a page-segmented implementation; page-segmentation means that only storage for a representation of the base primes up to the square root of the limit plus a sieve buffer that should also be at least proportional to the same square root is required; this will again make the execution faster as ranges go up due to better cache associativity with most memory accesses being within the CPU cache sizes. The following Forth code implements a basic version that does this:
 
<syntaxhighlight lang="forth">\ CPU L1 and L2 cache sizes in bits; power of 2...
1 17 LSHIFT CONSTANT L1CacheBits
L1CacheBits 8 * CONSTANT L2CacheBits
 
\ produces number of one bits in given word...
: numbts ( u -- u ) \ pop count number of bits...
0 SWAP BEGIN DUP 0<> WHILE SWAP 1+ SWAP DUP 1- AND REPEAT DROP ;
 
\ constants for variable 32/64 etc. CELL size...
1 CELLS 3 LSHIFT 1- CONSTANT CellMsk
CellMsk numbts CONSTANT CellShft
 
CREATE bits 8 ALLOT \ bit position Look Up Table...
: mkbts 8 0 DO 1 I LSHIFT I bits + c! LOOP ; mkbts
 
\ initializes sieve buffer storage and parameters
\ given sieve buffer bit size (even number of CELLS), returns buffer address ..
: initSieveBuffer ( u -- a-addr )
CellShft RSHIFT \ even number of cells
CELLS ALLOCATE 0<> IF ABORT" Memory allocation error!!!" THEN ;
 
\ test bit index composites array for prime...
: prime? ( u addr -- ? )
OVER 3 RSHIFT + C@ SWAP 7 AND bits + C@ AND 0= ;
 
\ given square index and prime index, u0, as sell as bitsz,
\ sieve the multiples of said prime leaving prime index on the stack...
: cullpi! ( u u0 u u addr -- u0 )
LOCALS| sba bitsz lwi | DUP DUP + 3 + ROT \ -- i prm sqri
\ culling start incdx address calculation...
lwi 2DUP > IF - ELSE SWAP - OVER MOD DUP 0<> IF OVER SWAP - THEN
THEN bitsz SWAP \ -- i prm bitsz strti
DO I 3 RSHIFT sba + DUP C@ I 7 AND bits + C@ OR SWAP C! DUP +LOOP
DROP ;
 
\ cull sieve buffer given base wheel index, bit size,
\ address base prime sieved buffer and
\ the address of the sieve buffer to be culled of composite bits...
: cullSieveBuffer ( u u a-addr a-addr -- )
>R >R 2DUP + R> R> \ -- lwi bitsz rngi bpba sba
LOCALS| sba bpba rngi bitsz lwi |
bitsz 1- CellShft RSHIFT 1+ CELLS sba SWAP ERASE \ clear sieve buffer
0 \ initialize base prime index i -- i
BEGIN \ test prime square index < limit
DUP DUP DUP + SWAP 3 + * 3 + TUCK rngi < \ sqri = 2*i * (I+3) + 3
WHILE \ -- sqri i
DUP bpba prime? IF lwi bitsz sba cullpi! ELSE SWAP DROP THEN \ -- i
1+ REPEAT 2DROP ; \ --
 
\ pop count style Look Up Table by 16 bits entry;
\ is a 65536 byte array containing number of zero bits for each index...
CREATE cntLUT16 65536 ALLOT
: mkpop ( u -- u ) numbts 16 SWAP - ;
: initLUT ( -- ) cntLUT16 65536 0 DO I mkpop OVER I + C! LOOP DROP ; initLUT
: popcount@ ( u -- u )
0 1 CELlS 1 RSHIFT 0
DO OVER 65535 AND cntLUT16 + C@ + SWAP 16 RSHIFT SWAP LOOP SWAP DROP ;
 
\ count number of zero bits up to given bits index in array address...
: countSieveBuffer@ ( u a-addr -- u )
LOCALS| bufa lmti |
0 \ initial count -- cnt
lmti CellShft RSHIFT CELLS TUCK \ lci = byte index of CELL including numv
0 ?DO bufa I + @ popcount@ + 1 CELLS +LOOP \ -- lci cnt
SWAP bufa + @ \ -- cnt lstCELL
-2 lmti CellMsk AND LSHIFT OR \ bmsk for last CELL -- cnt mskdCELL
popcount@ + ; \ add popcount of last masked CELL -- cnt
 
\ prints found primes from series of culled sieve buffers...
: .primes ( u -- )
DUP CR ." Primes to " . ." are: "
DUP 3 - 0< IF DUP 2 - 0< IF ." none." ELSE 2 . THEN \ <2/2 -> 0/1
ELSE 2 .
3 - 1 RSHIFT 1+ \ -- rngi
DUP 1- L2CacheBits / L2CacheBits * 3 RSHIFT \ -- rng rngi pglmtbytes
L1CacheBits initSieveBuffer \ address of base prime sieve buffer
L2CacheBits initSieveBuffer \ address of main sieve buffer
LOCALS| sba bpsba pglmt | \ local variables -- rngi
0 OVER L1CacheBits MIN bpsba bpsba cullSieveBuffer
pglmt 0 ?DO
I L2CacheBits bpsba sba cullSieveBuffer
I L2CacheBits 0 DO I sba prime? IF DUP I + DUP + 3 + . THEN LOOP DROP
L2CacheBits +LOOP \ rngi
L2CacheBits mod DUP 0> IF \ one more page!
pglmt DUP L2CacheBits bpsba sba cullSieveBuffer
SWAP 0 DO I sba prime? IF DUP I + DUP + 3 + . THEN LOOP DROP
THEN bpsba FREE DROP sba FREE DROP
THEN ; \ --
 
\ prints count of found primes from series of culled sieve buffers...
: .countPrimesTo ( u -- )
DUP 3 - 0< IF 2 - 0< IF 0 ELSE 1 THEN \ < 3 -> <2/2 -> 0/1!
ELSE
DUP 3 - 1 RSHIFT 1+
DUP 1- L2CacheBits / L2CacheBits * \ -- rng rngi pglmtbytes
L1CacheBits initSieveBuffer \ address of base prime sieve buffer
L2CacheBits initSieveBuffer \ address of main sieve buffer
LOCALS| sba bpsba pglmt | \ local variables -- rng rngi
0 OVER L1CacheBits MIN bpsba bpsba cullSieveBuffer
1 pglmt 0 ?DO
I L2CacheBits bpsba sba cullSieveBuffer
L2CacheBits 1- sba countSieveBuffer@ +
L2CacheBits +LOOP \ rng rngi cnt
SWAP L2CacheBits mod DUP 0> IF \ one more page!
pglmt OVER bpsba sba cullSieveBuffer
1- sba countSieveBuffer@ + \ partial count!
THEN
bpsba FREE DROP sba FREE DROP \ -- range cnt
THEN CR ." There are " . ." primes Up to the " . ." limit." ;
 
100 .primes
1000000000 .countPrimesTo</syntaxhighlight>
 
{{out}}
 
<pre>Primes to 100 are: 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
There are 50847534 primes Up to the 1000000000 limit.</pre>
 
For simplicity, the base primes array is left as a sieved bit packed array (which takes minimum space) at the cost of having to scan the bit array for base primes on every page-segment culling pass. The page-segment sieve buffer is set as a fixed multiple of this (intended to fit within the CPU L2 cache size) in order to reduce the base prime start index address calculation overhead by this factor at the cost of slightly increased memory access times, which access times are still only about the same as the fastest inner culling time or less anyway. When the cache sizes are set to the 32 Kilobyte/256 Kilobyte size for L1/L2, respectively, by changing <code forth>1 18 LSHIFT CONSTANT L1CacheBits</code>) as for my Intel Skylake i5-6500 at 3.6 GHz (single-threaded turbo), it runs in about 1.25 seconds on 64-bit VFX Forth, 3.75 seconds on 32-bit swiftForth, and 12.4 seconds on 64-bit gforth-fast, obviously with the tuned in-lined machine language compiling of VFX Forth much faster than the threaded execution token interpreting of gforth and with swiftForth lacking the machine code inlining of VFX Forth.
 
VFX Forth is only about 25 % slower than the algorithm as written in the fastest of languages, just as they advertise.
 
As written, the algorithm works efficiently up to over ten billion (1e10) with 64-bit systems, but could easily be refactored to use floating point or double precision for inputs and outputs [https://stackoverflow.com/a/55761023/549617 as I have done in a StackOverflow answer in JavaScript] without costing much in execution time so 32-bit systems would have the much higher limit.
 
The implementation is efficient up to this range, but with a change so that the base primes array can grow with increasing limit, can sieve to much higher ranges with a loss of efficiency in unused base prime start address calculations that can't be used as the culling spans exceed the fixed sieve buffer size. Again, this can be solved by also making the page-segmentation sieve buffer grow as the square root of the limit.
 
Further improvements by a factor of almost four in overall execution speed would be gained by implementing maximum wheel-factorization [https://stackoverflow.com/a/57108107/549617 as per my other StackOverflow JavaScript answer], which also effectively increases sieve buffer sizes by a factor of 48 in sieving by modulo residual bit planes.
 
Finally, multi-processing could be applied to increase the execution speed by about the number of effective cores (non SMT - Hyper Threads) as in four on my Skylake machine; however, neither the 1994 ANS Forth standard nor the 2012 standard has a standard Forth way of implementing this so each of the implementations use their own custom WORDS; since the resulting code would not be cross-implementation, I am not going to do this.
 
I likely won't even add the Maximum Wheel-Factorized version as in the above linked JavaScript code, since this code is enough to demonstrate what I was going to show: that Forth can be an efficient language, albeit a little hard to code, read, and maintain due to the reliance on anonymous data stack operations; it is a language whose best use is likely in cross-compiling to embedded systems where it can easily be customized and extended as required, and because it doesn't actually require a base operating system, can use its core facilities, functions, and extensions in place of such an OS to result in a minimum memory footprint.
 
=={{header|Fortran}}==
{{works with|Fortran|77}}
<syntaxhighlight lang="fortran">
PROGRAM MAIN
INTEGER LI
WRITE (6,100)
READ (5,110) LI
call SOE(LI)
100 FORMAT( 'Limit:' )
110 FORMAT( I4 )
STOP
END
C --- SIEVE OF ERATOSTHENES ----------
SUBROUTINE SOE( LI )
INTEGER LI
LOGICAL A(LI)
INTEGER SL,P,I
DO 10 I=1,LI
A(I) = .TRUE.
10 CONTINUE
SL = INT(SQRT(REAL(LI)))
A(1) = .FALSE.
DO 30 P=2,SL
IF ( .NOT. A(P) ) GOTO 30
DO 20 I=P*P,LI,P
A(I)=.FALSE.
20 CONTINUE
30 CONTINUE
 
DO 40 I=2,LI
IF ( A(I) ) WRITE(6,100) I
40 CONTINUE
 
100 FORMAT(I3)
RETURN
END
</syntaxhighlight>
 
{{works with|Fortran|90 and later}}
<langsyntaxhighlight lang="fortran">program sieve
 
implicit none
Line 4,573 ⟶ 8,172:
write (*, *)
 
end program sieve</langsyntaxhighlight>
Output:
<syntaxhighlight lang="text">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</langsyntaxhighlight>
 
Optimised using a pre-computed wheel based on 2:
Because it uses four byte logical's (default size) as elements of the sieve buffer, the above code uses 400 bytes of memory for this trivial task of sieving to 100; it also has 49 + 31 + 16 + 8 = 104 (for the culling by the primes of two, three, five, and seven) culling operations.
<lang fortran>program sieve_wheel_2
 
'''Optimised using a pre-computed wheel based on 2:'''
 
<syntaxhighlight lang="fortran">program sieve_wheel_2
 
implicit none
Line 4,595 ⟶ 8,198:
write (*, *)
 
end program sieve_wheel_2</langsyntaxhighlight>
Output:
<syntaxhighlight lang="text">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</langsyntaxhighlight>
 
This so-called "optimized" version still uses 400 bytes of memory but slightly reduces to 74 operations from 104 operations including the initialization of marking all of the even representations as composite due to skipping the re-culling of the even representation, so isn't really much of an optimization at all!
=={{header|FreeBASIC}}==
<lang freebasic>' FB 1.05.0
 
'''Optimized using a proper implementation of a wheel 2:'''
Sub sieve(n As Integer)
If n < 2 Then Return
Dim a(2 To n) As Integer
For i As Integer = 2 To n : a(i) = i : Next
Dim As Integer p = 2, q
' mark non-prime numbers by setting the corresponding array element to 0
Do
For j As Integer = p * p To n Step p
a(j) = 0
Next j
' look for next non-zero element in array after 'p'
q = 0
For j As Integer = p + 1 To Sqr(n)
If a(j) <> 0 Then
q = j
Exit For
End If
Next j
If q = 0 Then Exit Do
p = q
Loop
 
The above implementations, especially the second odds-only code, are some of the most inefficient versions of the Sieve of Eratosthenes in any language here as to time and space efficiency, only worse by some naive JavaScript implementations that use eight-byte Number's as logical values; the second claims to be wheel factorized but still uses all the same memory as the first and still culls by the even numbers in the initialization of the sieve buffer. As well, using four bytes (default logical size) to store a boolean value is terribly wasteful if these implementations were to be extended to non-toy ranges. The following code implements proper wheel factorization by two, reducing the space used by a factor of about eight to 49 bytes by using `byte` as the sieve buffer array elements and not requiring the evens initialization, thus reducing the number of operations to 16 + 8 + 4 = 28 (for the culling primes of three, five, and seven) culling operations:
' print the non-zero numbers remaining i.e. the primes
For i As Integer = 2 To n
If a(i) <> 0 Then
Print Using "####"; a(i);
End If
Next
Print
End Sub
 
<syntaxhighlight lang="fortran">program sieve_wheel_2
Print "The primes up to 1000 are :"
Print
implicit none
sieve(1000)
integer, parameter :: i_max = 100
Print
integer, parameter :: i_limit = (i_max - 3) / 2
Print "Press any key to quit"
integer :: i
Sleep</lang>
byte, dimension (0:i_limit) :: composites
composites = 0
do i = 0, (int (sqrt (real (i_max))) - 3) / 2
if (composites(i) == 0) composites ((i + i) * (i + 3) + 3 : i_limit : i + i + 3) = 1.
end do
write (*, '(i0, 1x)', advance = 'no') 2
do i = 0, i_limit
if (composites (i) == 0) write (*, '(i0, 1x)', advance = 'no') (i + i + 3)
end do
write (*, *)
end program sieve_wheel_2</syntaxhighlight>
 
The output is the same as the earlier version.
 
'''Optimized using bit packing to reduce the memory use by a further factor of eight:'''
 
The above implementation is still space inefficient in effectively only using one bit out of eight; the following version implements bit packing to reduce memory use by a factor of eight by using bits to represent composite numbers rather than bytes:
 
<syntaxhighlight lang="fortran">program sieve_wheel_2
implicit none
integer, parameter :: i_max = 10000000
integer, parameter :: i_range = (i_max - 3) / 2
integer :: i, j, k, cnt
byte, dimension (0:i_range / 8) :: composites
composites = 0 ! pre-initialized?
do i = 0, (int (sqrt (real (i_max))) - 3) / 2
if (iand(composites(shiftr(i, 3)), shiftl(1, iand(i, 7))) == 0) then
do j = (i + i) * (i + 3) + 3, i_range, i + i + 3
k = shiftr(j, 3)
composites(k) = ior(composites(k), shiftl(1, iand(j, 7)))
end do
end if
end do
! write (*, '(i0, 1x)', advance = 'no') 2
cnt = 1
do i = 0, i_range
if (iand(composites(shiftr(i, 3)), shiftl(1, iand(i, 7))) == 0) then
! write (*, '(i0, 1x)', advance = 'no') (i + i + 3)
cnt = cnt + 1
end if
end do
! write (*, *)
print '(a, i0, a, i0, a, f0.0, a)', &
'There are ', cnt, ' primes up to ', i_max, '.'
end program sieve_wheel_2</syntaxhighlight>
 
{{out}}
<pre>There are 664579 primes up to 10000000.</pre>
<pre>
The primes up to 1000 are :
 
When the lines to print the results are enabled, the output to a maximum value of 100 is still exactly the same as the other versions, and it has exactly the same number of culling operations as the immediately above optimized version for the same range; the only difference is that less memory is used. Although the culling operations are somewhat more complex, for larger ranges the time saved in better cache associativity due to more effective use of the cache more than makes up for it so average culling time is actually reduced, so that this version can count the number of primes to several million (it takes a lot of time to list hundreds of thousands of primes, but counting is faster) in a few tens of milliseconds. For ranges above a few tens of millions, a page-segmented sieve is much more efficient due to further improved use of the CPU caches.
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 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173
===Multi-Threaded Page-Segmented Bit-Packed Odds-Only Version===
179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281
 
283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409
As well as adding page-segmentation, the following code adds multi-processing which is onc of the capabilities for which modern Fortran is known:
419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541
 
547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659
<syntaxhighlight lang="fortran">subroutine cullSieveBuffer(lwi, size, bpa, sba)
661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809
 
811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941
implicit none
947 953 967 971 977 983 991 997
integer, intent(in) :: lwi, size
</pre>
byte, intent(in) :: bpa(0:size - 1)
byte, intent(out) :: sba(0:size - 1)
integer :: i_limit, i_bitlmt, i_bplmt, i, sqri, bp, si, olmt, msk, j
byte, dimension (0:7) :: bits
common /twiddling/ bits
i_bitlmt = size * 8 - 1
i_limit = lwi + i_bitlmt
i_bplmt = size / 4
sba = 0
i = 0
sqri = (i + i) * (i + 3) + 3
do while (sqri <= i_limit)
if (iand(int(bpa(shiftr(i, 3))), shiftl(1, iand(i, 7))) == 0) then
! start index address calculation...
bp = i + i + 3
if (lwi <= sqri) then
si = sqri - lwi
else
si = mod((lwi - sqri), bp)
if (si /= 0) si = bp - si
end if
if (bp <= i_bplmt) then
olmt = min(i_bitlmt, si + bp * 8 - 1)
do while (si <= olmt)
msk = bits(iand(si, 7))
do j = shiftr(si, 3), size - 1, bp
sba(j) = ior(int(sba(j)), msk)
end do
si = si + bp
end do
else
do while (si <= i_bitlmt)
j = shiftr(si, 3)
sba(j) = ior(sba(j), bits(iand(si, 7)))
si = si + bp
end do
end if
end if
i = i + 1
sqri = (i + i) * (i + 3) + 3
end do
end subroutine cullSieveBuffer
integer function countSieveBuffer(lmti, almti, sba)
implicit none
integer, intent(in) :: lmti, almti
byte, intent(in) :: sba(0:almti)
integer :: bmsk, lsti, i, cnt
byte, dimension (0:65535) :: clut
common /counting/ clut
cnt = 0
bmsk = iand(shiftl(-2, iand(lmti, 15)), 65535)
lsti = iand(shiftr(lmti, 3), -2)
do i = 0, lsti - 1, 2
cnt = cnt + clut(shiftl(iand(int(sba(i)), 255), 8) + iand(int(sba(i + 1)), 255))
end do
countSieveBuffer = cnt + clut(ior(shiftl(iand(int(sba(lsti)), 255), 8) + iand(int(sba(lsti + 1)), 255), bmsk))
end function countSieveBuffer
program sieve_paged
use OMP_LIB
implicit none
integer, parameter :: i_max = 1000000000, i_range = (i_max - 3) / 2
integer, parameter :: i_l1cache_size = 16384, i_l1cache_bitsz = i_l1cache_size * 8
integer, parameter :: i_l2cache_size = i_l1cache_size * 8, i_l2cache_bitsz = i_l2cache_size * 8
integer :: cr, c0, c1, i, j, k, cnt
integer, save :: scnt
integer :: countSieveBuffer
integer :: numthrds
byte, dimension (0:i_l1cache_size - 1) :: bpa
byte, save, allocatable, dimension (:) :: sba
byte, dimension (0:7) :: bits = (/ 1, 2, 4, 8, 16, 32, 64, -128 /)
byte, dimension (0:65535) :: clut
common /twiddling/ bits
common /counting/ clut
type heaparr
byte, allocatable, dimension(:) :: thrdsba
end type heaparr
type(heaparr), allocatable, dimension (:) :: sbaa
!$OMP THREADPRIVATE(scnt, sba)
numthrds = 1
!$ numthrds = OMP_get_max_threads()
allocate(sbaa(0:numthrds - 1))
do i = 0, numthrds - 1
allocate(sbaa(i)%thrdsba(0:i_l2cache_size - 1))
end do
CALL SYSTEM_CLOCK(count_rate=cr)
CALL SYSTEM_CLOCK(c0)
do k = 0, 65535 ! initialize counting Look Up Table
j = k
i = 16
do while (j > 0)
i = i - 1
j = iand(j, j - 1)
end do
clut(k) = i
end do
bpa = 0 ! pre-initialization not guaranteed!
call cullSieveBuffer(0, i_l1cache_size, bpa, bpa)
cnt = 1
!$OMP PARALLEL DO ORDERED
do i = i_l2cache_bitsz, i_range, i_l2cache_bitsz * 8
scnt = 0
sba = sbaa(mod(i, numthrds))%thrdsba
do j = i, min(i_range, i + 8 * i_l2cache_bitsz - 1), i_l2cache_bitsz
call cullSieveBuffer(j - i_l2cache_bitsz, i_l2cache_size, bpa, sba)
scnt = scnt + countSieveBuffer(i_l2cache_bitsz - 1, i_l2cache_size, sba)
end do
!$OMP ATOMIC
cnt = cnt + scnt
end do
!$OMP END PARALLEL DO
j = i_range / i_l2cache_bitsz * i_l2cache_bitsz
k = i_range - j
if (k /= i_l2cache_bitsz - 1) then
call cullSieveBuffer(j, i_l2cache_size, bpa, sbaa(0)%thrdsba)
cnt = cnt + countSieveBuffer(k, i_l2cache_size, sbaa(0)%thrdsba)
end if
! write (*, '(i0, 1x)', advance = 'no') 2
! do i = 0, i_range
! if (iand(sba(shiftr(i, 3)), bits(iand(i, 7))) == 0) write (*, '(i0, 1x)', advance='no') (i + i + 3)
! end do
! write (*, *)
CALL SYSTEM_CLOCK(c1)
print '(a, i0, a, i0, a, f0.0, a)', 'Found ', cnt, ' primes up to ', i_max, &
' in ', ((c1 - c0) / real(cr) * 1000), ' milliseconds.'
do i = 0, numthrds - 1
deallocate(sbaa(i)%thrdsba)
end do
deallocate(sbaa)
end program sieve_paged</syntaxhighlight>
 
{{out}}
<pre>Found 50847534 primes up to 1000000000 in 219. milliseconds.</pre>
 
The above output was as compiled with gfortran -O3 -fopenmp using version 11.1.1-1 on my Intel Skylake i5-6500 CPU at 3.2 GHz multithreaded with four cores. There are a few more optimizations that could be made in applying Maximum Wheel-Factorization [https://stackoverflow.com/a/57108107/549617 as per my StackOverflow answer in JavaScript], which will make this almost four times faster yet again. If that optimization were done, sieving to a billion as here is really too trivial to measure and one should sieve at least up to ten billion to start to get a long enough time to be measured accurately. As explained in that answer, the Maximum Wheel-Factorized code will work efficiently up to about a trillion (1e12), when it needs yet another "bucket sieve" optimization to allow it to continue to scale efficiently for increasing range. The final optimization which can speed up the code by almost a factor of two is a very low level loop unrolling technique that I'm not sure will work with the compiler, but as it works in C/C++ and other similar languages including those that compile through LLVM, it ought to.
 
=={{header|Free Pascal}}==
===Basic version===
function Sieve returns a list of primes less than or equal to the given aLimit
<langsyntaxhighlight lang="pascal">
program prime_sieve;
{$mode objfpc}{$coperators on}
Line 4,709 ⟶ 8,482:
procedure PrintUsage;
begin
WriteLn('Usage: prime_sieve0prime_sieve Limit');
WriteLn(' where Limit in the range [0, ', High(DWord), ']');
Halt;
Line 4,717 ⟶ 8,490:
I: DWord;
begin
for I := 0 toif aList.Size -<> 0 2then dobegin
Write(if aList[I],.Size > ',1 ');then
WriteLn(aList[ for I := 0 to aList.Size - 1]);2 do
Write(aList[I], ', ');
WriteLn(aList[aList.Size - 1]);
end;
aList.Free;
end;
Line 4,732 ⟶ 8,508:
end;
end.
</syntaxhighlight>
</lang>
===Alternative segmented(odds only) version===
function OddSegmentSieve returns a list of primes less than or equal to the given aLimit
<langsyntaxhighlight lang="pascal">
program prime_sieve;
{$mode objfpc}{$coperators on}
Line 4,848 ⟶ 8,624:
procedure PrintUsage;
begin
WriteLn('Usage: prime_sieve3prime_sieve Limit');
WriteLn(' where Limit in the range [20, ', High(DWord), ']');
Halt;
end;
Line 4,858 ⟶ 8,634:
for I := 0 to Length(aList) - 2 do
Write(aList[I], ', ');
WriteLn(if aList[High(aList)]); <> nil then
WriteLn(aList[High(aList)]);
end;
begin
Line 4,865 ⟶ 8,642:
PrintPrimes(OddSegmentSieve(Limit));
end.
</syntaxhighlight>
</lang>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">' FB 1.05.0
 
Sub sieve(n As Integer)
If n < 2 Then Return
Dim a(2 To n) As Integer
For i As Integer = 2 To n : a(i) = i : Next
Dim As Integer p = 2, q
' mark non-prime numbers by setting the corresponding array element to 0
Do
For j As Integer = p * p To n Step p
a(j) = 0
Next j
' look for next non-zero element in array after 'p'
q = 0
For j As Integer = p + 1 To Sqr(n)
If a(j) <> 0 Then
q = j
Exit For
End If
Next j
If q = 0 Then Exit Do
p = q
Loop
 
' print the non-zero numbers remaining i.e. the primes
For i As Integer = 2 To n
If a(i) <> 0 Then
Print Using "####"; a(i);
End If
Next
Print
End Sub
 
Print "The primes up to 1000 are :"
Print
sieve(1000)
Print
Print "Press any key to quit"
Sleep</syntaxhighlight>
 
{{out}}
<pre>
The primes up to 1000 are :
 
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 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281
283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409
419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541
547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659
661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809
811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941
947 953 967 971 977 983 991 997
</pre>
 
=={{header|Frink}}==
<syntaxhighlight lang="frink">
n = eval[input["Enter highest number: "]]
results = array[sieve[n]]
println[results]
println[length[results] + " prime numbers less than or equal to " + n]
 
sieve[n] :=
{
// Initialize array
array = array[0 to n]
array@1 = 0
 
for i = 2 to ceil[sqrt[n]]
if array@i != 0
for j = i^2 to n step i
array@j = 0
 
return select[array, { |x| x != 0 }]
}
</syntaxhighlight>
 
=={{header|Furor}}==
''Note: With benchmark function''
 
<syntaxhighlight lang="furor">
tick sto startingtick
#g 100000 sto MAX
@MAX mem !maximize sto primeNumbers
one count
@primeNumbers 0 2 [^]
2 @MAX külső: {||
@count {|
{}§külső {} []@primeNumbers !/ else{<}§külső
|} // @count vége
@primeNumbers @count++ {} [^]
|} // @MAX vége
@primeNumbers free
."Time : " tick @startingtick - print ." tick\n"
."Prímek száma = " @count printnl
end
{ „MAX” } { „startingtick” } { „primeNumbers” } { „count” }
</syntaxhighlight>
 
=={{header|Peri}}==
''Note: With benchmark function''
 
<syntaxhighlight lang="peri">
###sysinclude standard.uh
tick sto startingtick
#g 100000 sto MAX
@MAX mem !maximize sto primeNumbers
one count
2 0 sto#s primeNumbers
2 @MAX külső: {{ ,
@count {{
{{}}§külső primeNumbers[{{}}] !/ else {{<}}§külső
}} // @count vége
//{{}} gprintnl // A talált prímszám kiiratásához kommentezzük ki e sort
{{}} @count++ sto#s primeNumbers
}} // @MAX vége
@primeNumbers inv mem
//."Time : " tick @startingtick - print ." tick\n"
."Prímek száma = " @count printnl
end
{ „MAX” } { „startingtick” } { „primeNumbers” } { „count” }
 
</syntaxhighlight>
 
=={{header|FutureBasic}}==
===Basic sieve of array of booleans===
<syntaxhighlight lang="futurebasic">window 1, @"Sieve of Eratosthenes", (0,0,720,300)
<lang futurebasic>
include "ConsoleWindow"
 
begin globals
dim dynamic gPrimes(1) as Boolean
end globals
 
local fn SieveOfEratosthenes( n as long )
dim as long i, j
 
for i = 2 to n
for j = i * i to n step i
gPrimes(j) = _true
next
if gPrimes(i) = 0 then print i;,
next i
kill gPrimes
end fn
 
fn SieveOfEratosthenes( 100 )
 
</lang>
HandleEvents</syntaxhighlight>
Output:
<pre>
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
</pre>
 
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Sieve_of_Eratosthenes}}
 
'''Solution'''
 
[[File:Fōrmulæ - Sieve of Eratosthenes 01.png]]
 
'''Test case'''
 
[[File:Fōrmulæ - Sieve of Eratosthenes 02.png]]
 
[[File:Fōrmulæ - Sieve of Eratosthenes 03.png]]
 
=={{header|GAP}}==
<langsyntaxhighlight lang="gap">Eratosthenes := function(n)
local a, i, j;
a := ListWithIdenticalEntries(n, true);
Line 4,920 ⟶ 8,836:
Eratosthenes(100);
 
[ 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 ]</langsyntaxhighlight>
 
=={{header|GLBasic}}==
<langsyntaxhighlight GLBasiclang="glbasic">// Sieve of Eratosthenes (find primes)
// GLBasic implementation
 
Line 4,947 ⟶ 8,863:
 
KEYWAIT
</syntaxhighlight>
</lang>
 
=={{header|Go}}==
===Basic sieve of array of booleans===
<langsyntaxhighlight lang="go">package main
import "fmt"
 
Line 4,992 ⟶ 8,908:
}
}
}</langsyntaxhighlight>
Output:
<pre>
Line 5,011 ⟶ 8,927:
The above version's output is rather specialized; the following version uses a closure function to enumerate over the culled composite number array, which is bit packed. By using this scheme for output, no extra memory is required above that required for the culling array:
 
<langsyntaxhighlight lang="go">package main
 
import (
Line 5,058 ⟶ 8,974:
}
fmt.Printf("\r\n%v\r\n", count)
}</langsyntaxhighlight>
{{output}}
<pre>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
Line 5,065 ⟶ 8,981:
===Sieve Tree===
A fairly odd sieve tree method:
<langsyntaxhighlight lang="go">package main
import "fmt"
 
Line 5,124 ⟶ 9,040:
fmt.Println(p())
}
}</langsyntaxhighlight>
 
===Concurrent Daisy-chain sieve===
A concurrent prime sieve adopted from the example in the "Go Playground" window at http://golang.org/
<langsyntaxhighlight lang="go">package main
import "fmt"
Line 5,179 ⟶ 9,095:
}
}
}</langsyntaxhighlight>
The output:
<pre>
Line 5,189 ⟶ 9,105:
===Postponed Concurrent Daisy-chain sieve===
Here we postpone the ''creation'' of filters until the prime's square is seen in the input, to radically reduce the amount of filter channels in the sieve chain.
<langsyntaxhighlight lang="go">package main
import "fmt"
Line 5,256 ⟶ 9,172:
}
}
}</langsyntaxhighlight>
 
The output:
Line 5,266 ⟶ 9,182:
===Incremental Odds-only Sieve===
Uses Go's built-in hash tables to store odd composites, and defers adding new known composites until the square is seen.
<syntaxhighlight lang="go">
<lang go>
package main
 
Line 5,292 ⟶ 9,208:
 
var p int
p = <-primes
p = <-primes
 
Line 5,325 ⟶ 9,241:
}
}
</syntaxhighlight>
</lang>
The output:
<pre>
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
</pre>
 
=={{header|Groovy}}==
This solution uses a BitSet for compactness and speed, but in [[Groovy]], BitSet has full List semantics. It also uses both the "square root of the boundary" shortcut and the "square of the prime" shortcut.
<langsyntaxhighlight lang="groovy">def sievePrimes = { bound ->
def isPrime = new BitSet(bound)
isPrime[0..1] = false
Line 5,342 ⟶ 9,259:
}
(0..bound).findAll { isPrime[it] }
}</langsyntaxhighlight>
 
Test:
<syntaxhighlight lang ="groovy">println sievePrimes(100)</langsyntaxhighlight>
 
Output:
Line 5,352 ⟶ 9,269:
=={{header|GW-BASIC}}==
 
<langsyntaxhighlight lang="qbasic">10 INPUT "ENTER NUMBER TO SEARCH TO: ";LIMIT
20 DIM FLAGS(LIMIT)
30 FOR N = 2 TO SQR (LIMIT)
Line 5,363 ⟶ 9,280:
100 FOR N = 2 TO LIMIT
110 IF FLAGS(N) = 0 THEN PRINT N;", ";
120 NEXT N</langsyntaxhighlight>
 
=={{header|Haskell}}==
 
===Mutable unboxed arrays===
Mutable array of unboxed <code>Bool</code>s indexed by <code>Int</code>s:
 
<syntaxhighlight lang="haskell">{-# LANGUAGE FlexibleContexts #-} -- too lazy to write contexts...
{-# OPTIONS_GHC -O2 #-}
 
import Control.Monad.ST ( runST, ST )
import Data.Array.Base ( MArray(newArray, unsafeRead, unsafeWrite),
IArray(unsafeAt),
STUArray, unsafeFreezeSTUArray, assocs )
import Data.Time.Clock.POSIX ( getPOSIXTime ) -- for timing...
 
primesTo :: Int -> [Int] -- generate a list of primes to given limit...
primesTo limit = runST $ do
let lmt = limit - 2-- raw index of limit!
cmpsts <- newArray (2, limit) False -- when indexed is true is composite
cmpstsf <- unsafeFreezeSTUArray cmpsts -- frozen in place!
let getbpndx bp = (bp, bp * bp - 2) -- bp -> bp, raw index of start cull
cullcmpst i = unsafeWrite cmpsts i True -- cull composite by raw ndx
cull4bpndx (bp, si0) = mapM_ cullcmpst [ si0, si0 + bp .. lmt ]
mapM_ cull4bpndx
$ takeWhile ((>=) lmt . snd) -- for bp's <= square root limit
[ getbpndx bp | (bp, False) <- assocs cmpstsf ]
return [ p | (p, False) <- assocs cmpstsf ] -- non-raw ndx is prime
 
-- testing...
main :: IO ()
main = do
putStrLn $ "The primes up to 100 are " ++ show (primesTo 100)
putStrLn $ "The number of primes up to a million is " ++
show (length $ primesTo 1000000)
let top = 1000000000
start <- getPOSIXTime
let answr = length $ primesTo top
stop <- answr `seq` getPOSIXTime -- force result for timing!
let elpsd = round $ 1e3 * (stop - start) :: Int
 
putStrLn $ "Found " ++ show answr ++ " to " ++ show top ++
" in " ++ show elpsd ++ " milliseconds."</syntaxhighlight>
 
The above code chooses conciseness and elegance over speed, but it isn't too slow:
{{out}}
<pre>The primes up to 100 are [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]
The number of primes up to a million is 78498
Found 50847534 to 1000000000 in 12435 milliseconds.</pre>
 
Run on an Intel Sky Lake i5-2500 at 3.6 GHZ (single threaded boost). As per the comments in the below, this is greatly sped up by a constant factor by using the raw `unsafeWrite`; use of the "unsafe" versions that avoid run time array bounds checks on every operation is entirely safe here as the indexing is inherently limited to be within the bounds by their use in the loops. There is an additional benefit of about 20 per cent in speed if run with the LLVM back end compiler option (add the "-fllvm" flag) if the right version of LLVM is available to the GHC Haskell compiler. We see the relatively small benefit of using LLVM in that this program spends a relatively small percentage of time in the tight inner culling loop where LLVM can help the most and a high part of the time is spent just enumerating the result list.
 
===Mutable unboxed arrays, odds only===
Mutable array of unboxed <code>Bool</code>s indexed by <code>Int</code>s, representing odds only:
 
<langsyntaxhighlight lang="haskell">import Control.Monad (forM_, when)
import Control.Monad.ST
import Data.Array.ST
Line 5,389 ⟶ 9,354:
primesToUO :: Int -> [Int]
primesToUO top | top > 1 = 2 : [2*i + 1 | (i,True) <- assocs $ sieveUO top]
| otherwise = []</langsyntaxhighlight>
 
This represents ''odds only'' in the array. [http://ideone.com/KwZNc Empirical orders of growth] is ~ <i>n<sup>1.2</sup></i> in ''n'' primes produced, and improving for bigger ''n''&zwj;&thinsp;&zwj;s. Memory consumption is low (array seems to be packed) and growing about linearly with ''n''. Can further be [http://ideone.com/j24jxV significantly sped up] by re-writing the <code>forM_</code> loops with direct recursion, and using <code>unsafeRead</code> and <code>unsafeWrite</code> operations.
 
In light of the performance of the previous and following submissions results, the IDEOne results seem somewhat slow at about 10 seconds over a range of about a third of a billion, likely due to some lazily deferred operations in the processing. See the next submission for expected speeds for odds only.
 
The measured empirical orders of growth as per the table in the IDEOne link are easily understood if one considers that these slowish run times are primarily limited by the time to lazily enumerate the results and that the number of found primes to enumerate varies as (top / log top) by the Euler relationship. Since the prime density decreases by this relationship, the enumeration has the inverse relationship as it takes longer per prime to find the primes in the sieved buffer. Log of a million is 1.2 times larger than log of a hundred thousand and of course this ratio gets smaller with range: the ratio of the log of a billion as compared to log of a hundred million is 1.125, etc.
 
===Alternate Version of Mutable unboxed arrays, odds only===
 
The reason for this alternate version is to have an accessible version of "odds only" that uses the same optimizations and is written in the same coding style as the basic version. This can be used by just substituting the following code for the function of the same name in the first base example above. Mutable array of unboxed <code>Bool</code>s indexed by <code>Int</code>s, representing odds only:
 
<syntaxhighlight lang="haskell">primesTo :: Int -> [Int] -- generate a list of primes to given limit...
primesTo limit
| limit < 2 = []
| otherwise = runST $ do
let lmt = (limit - 3) `div` 2 - 1 -- limit index!
oddcmpsts <- newArray (0, lmt) False -- when indexed is true is composite
oddcmpstsf <- unsafeFreezeSTUArray oddcmpsts -- frozen in place!
let getbpndx i = (i + i + 3, (i + i) * (i + 3) + 3) -- index -> bp, si0
cullcmpst i = unsafeWrite oddcmpsts i True -- cull composite by index
cull4bpndx (bp, si0) = mapM_ cullcmpst [ si0, si0 + bp .. lmt ]
mapM_ cull4bpndx
$ takeWhile ((>=) lmt . snd) -- for bp's <= square root limit
[ getbpndx i | (i, False) <- assocs oddcmpstsf ]
return $ 2 : [ i + i + 3 | (i, False) <- assocs oddcmpstsf ]</syntaxhighlight>
 
{{out}}
<pre>The primes up to 100 are [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]
The number of primes up to a million is 78498
Found 50847534 to 1000000000 in 6085 milliseconds.</pre>
 
A "monolithic buffer" odds only sieve uses half the memory as compared to the basic version.
 
This is not the expected about 2.5 times faster as the basic version because there are other factors to execution time cost than just the number of culling operations, as follows:
 
1) Since the amount of memory used to sieve to a billion has been dropped from 125 million bytes to 62.5 million bytes, the cache associativity is slightly better, which should make it faster; however
 
2) We have eliminated the culling by the very small span of the base prime of two, which means a lesser percentage of the culling span operations will be within a given CPU cache size, which will make it slower, but
 
3) The primary reason we observe only about a factor of two difference in run times is that we have increased the prime density in the sieving buffer by a factor of two, which means that we have half the work to enumerate the primes. Since enumeration of the found primes is a major contribution of the execution time, the execution time will tend to change more by its cost than any other.
 
As to "empirical orders of growth", the comments made in the above are valid, but there is a further observation. For smaller ranges of primes up to a few million where the sieving buffer fits within the CPU L2 cache size (generally 256 Kilobytes/2 million bits, representing a range of about four million for this version), the cull times are their fastest and enumeration is a bigger percentage of the time; as ranges increase above that, more and more time is spent waiting on memory at the access times of the next level memory (CPU L3 cache, if present, followed by main memory) so that the controlling factor is a little less that of the enumeration time as range gets larger.
 
'''Because of the greatly increasing memory demands and the high execution cost of memory access as ranges exceed the span of the CPU caches, it is not recommended that these simple "monolithic buffer" sieves be used for sieving of ranges above about a hundred million.''' Rather, one should use a "Paged-Segmented" sieve as per the examples near the end of this Haskell section.
 
===Immutable arrays===
Monolithic sieving array. ''Even'' numbers above 2 are pre-marked as composite, and sieving is done only by ''odd'' multiples of ''odd'' primes:
<langsyntaxhighlight lang="haskell">import Data.Array.Unboxed
primesToA m = sieve 3 (array (3,m) [(i,odd i) | i<-[3..m]] :: UArray Int Bool)
Line 5,402 ⟶ 9,409:
| p*p > m = 2 : [i | (i,True) <- assocs a]
| a!p = sieve (p+2) $ a//[(i,False) | i <- [p*p, p*p+2*p..m]]
| otherwise = sieve (p+2) a</langsyntaxhighlight>
 
Its performance sharply depends on compiler optimizations. Compiled with -O2 flag in the presence of the explicit type signature, it is very fast in producing first few million primes. <code>(//)</code> is an array update operator.
Line 5,409 ⟶ 9,416:
 
Works by segments between consecutive primes' squares. Should be the fastest of non-monadic code. ''Evens'' are entirely ignored:
<langsyntaxhighlight lang="haskell">import Data.Array.Unboxed
 
primesSA = 2 : prs ()
Line 5,421 ⟶ 9,428:
a :: UArray Int Bool
a = accumArray (\ b c -> False) True (1,q-1)
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]]</langsyntaxhighlight>
 
====As list comprehension====
 
<syntaxhighlight lang="haskell">import Data.Array.Unboxed
import Data.List (tails, inits)
 
primes = 2 : [ n |
(r:q:_, px) <- zip (tails (2 : [p*p | p <- primes]))
(inits primes),
(n, True) <- assocs ( accumArray (\_ _ -> False) True
(r+1,q-1)
[ (m,()) | p <- px
, s <- [ div (r+p) p * p]
, m <- [s,s+p..q-1] ] :: UArray Int Bool
) ]</syntaxhighlight>
 
===Basic list-based sieve===
Straightforward implementation of the sieve of Eratosthenes in its original bounded form. This finds primes in gaps between the composites, and composites as an enumeration of each prime's multiples.
<langsyntaxhighlight lang="haskell">primesTo m = eratos [2..m] where
eratos (p : xs)
| p*p > m = p : xs
Line 5,436 ⟶ 9,458:
EQ -> minus xs ys
GT -> minus a ys
minus a b = a </langsyntaxhighlight>
Its time complexity is similar to that of optimal [[Primality_by_trial_division#Haskell|trial division]] because of limitations of Haskell linked lists, where <code>(minus a b)</code> takes time proportional to <code>length(union a b)</code> and not <code>(length b)</code>, as achieved in imperative setting with direct-access memory. Uses ordered list representation of sets.
 
Line 5,443 ⟶ 9,465:
===Unbounded list based sieve===
Unbounded, "naive", too eager to subtract (see above for the definition of <code>minus</code>):
<langsyntaxhighlight lang="haskell">primesE = sieve [2..]
where
sieve (p:xs) = p : sieve (minus xs [p, p+p..])
-- unfoldr (\(p:xs)-> Just (p, minus xs [p, p+p..])) [2..]</langsyntaxhighlight>
This is slow, with complexity increasing as a square law or worse so that it is only moderately useful for the first few thousand primes or so.
 
The number of active streams can be limited to what's strictly necessary by postponement until the square of a prime is seen, getting a massive complexity improvement to better than <i>~ n<sup>1.5</sup></i> so it can get first million primes or so in a tolerable time:
<langsyntaxhighlight lang="haskell">primesPE = 2 : sieve [3..] 4 primesPE
where
sieve (x:xs) q (p:t)
Line 5,457 ⟶ 9,479:
-- fix $ (2:) . concat
-- . unfoldr (\(p:ps,xs)-> Just . second ((ps,) . (`minus` [p*p, p*p+p..]))
-- . span (< p*p) $ xs) . (,[3..]) </langsyntaxhighlight>
 
Transposing the workflow, going by segments between the consecutive squares of primes:
<langsyntaxhighlight lang="haskell">import Data.List (inits)
 
primesSE = 2 : sieve 3 4 (tail primesSE) (inits primesSE)
Line 5,469 ⟶ 9,491:
-- True (x,q-1) [(i,()) | f <- fs, let n=div(x+f-1)f*f,
-- i <- [n, n+f..q-1]] :: UArray Int Bool )]
++ sieve q (head ps^2) (tail ps) ft</langsyntaxhighlight>
 
The basic gradually-deepening left-leaning <code>(((a-b)-c)- ... )</code> workflow of <code>foldl minus a bs</code> above can be rearranged into the right-leaning <code>(a-(b+(c+ ... )))</code> workflow of <code>minus a (foldr union [] bs)</code>. This is the idea behind Richard Bird's unbounded code presented in [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf M. O'Neill's article], equivalent to:
 
<langsyntaxhighlight lang="haskell">primesB = _Y ( (2:) . minus [3..] . foldr (\p-> (p*p :) . union [p*p+p, p*p+2*p..]) [] )
 
-- = _Y ( (2:) . minus [3..] . _LU . map(\p-> [p*p, p*p+p..]) )
Line 5,486 ⟶ 9,508:
LT -> x : union xs b
EQ -> x : union xs ys
GT -> y : union a ys</langsyntaxhighlight>
 
Using <code>_Y</code> is meant to guarantee the separate supply of primes to be independently calculated, recursively, instead of the same one being reused, corecursively; thus the memory footprint is drastically reduced. This idea was introduced by M. ONeill as a double-staged production, with a separate primes feed.
Line 5,492 ⟶ 9,514:
The above code is also useful to a range of the first million primes or so. The code can be further optimized by fusing <code>minus [3..]</code> into one function, preventing a space leak with the newer GHC versions, getting the function <code>gaps</code> defined below.
 
====Tree-merging incremental sieve====
Linear merging structure can further be replaced with an wiki.haskell.org/Prime_numbers#Tree_merging indefinitely deepening to the right tree-like structure, <code>(a-(b+((c+d)+( ((e+f)+(g+h)) + ... ))))</code>.
 
This merges primes' multiples streams in a ''tree''-like fashion, as a sequence of balanced trees of <code>union</code> nodes, likely achieving theoretical time complexity only a ''log n'' factor above the optimal ''n log n log (log n)'', for ''n'' primes produced. Indeed, empirically it runs at about ''~ n<sup>1.2</sup>'' (for producing first few million primes), similarly to priority-queue&ndash;based version of M. O'Neill's, and with very low space complexity too (not counting the produced sequence of course):
<langsyntaxhighlight lang="haskell">primes :: () -> [Int]
primes() = 2 : _Y ( (3:) . gaps 5 . _U . map(\p-> [p*p, p*p+2*p..]) ) where
_Y g = g (_Y g) -- = g (g (g ( ... ))) non-sharing multistage fixpoint combinator
 
gaps k s@(c:cs) | k < c = k : gaps (k+2) s -- ~= ([k,k+2..] \\ s)
| otherwise = gaps (k+2) cs -- when null(s\\[k,k+2..])
_U ((x:xs):t) = x : (merge xs . _U . pairs) t -- tree-shaped folding big union
 
_U pairs ((x:xs):ys:t) = x : (unionmerge xs .ys _U .: pairs) t -- tree-shaped folding big union
merge xs@(x:xt) ys@(y:yt) | x < y = x : merge xt ys
where -- ~= nub . sort . concat
| y < x = y : merge xs yt
pairs (xs:ys:t) = union xs ys : pairs t</lang>
| otherwise = x : merge xt yt</syntaxhighlight>
 
Works with odds only, the simplest kind of wheel. Here's the [http://ideone.com/qpnqe test entry] on Ideone.com, and a [http://ideone.com/p0e81 comparison with more versions].
Line 5,510 ⟶ 9,533:
====With Wheel====
Using <code>_U</code> defined above,
<langsyntaxhighlight lang="haskell">primesW :: [Int]
primesW = [2,3,5,7] ++ _Y ( (11:) . gapsW 13 (tail wheel) . _U .
map (\p->
Line 5,521 ⟶ 9,544:
wheel = 2:4:2:4:6:2:6:4:2:4:6:6:2:6:4:2:6:4:6:8:4:2:4:2: -- gaps = (`gapsW` cycle [2])
4:8:6:4:6:2:4:6:2:6:6:4:2:4:6:2:6:4:2:4:2:10:2:10:wheel
-- cycle $ zipWith (-) =<< tail $ [i | i <- [11..221], gcd i 210 == 1]</langsyntaxhighlight>
 
Used [[Emirp_primes#List-based|here]] and [[Extensible_prime_generator#List_based|here]].
 
====Improved efficiency Wheels====
 
1. The generation of large wheels such as the 2/3/5/7/11/13/17 wheel, which has 92160 cyclic elements, needs to be done based on sieve culling which is much better as to performance and can be used without inserting the generated table.
 
2. Improving the means to re-generate the position on the wheel for the recursive base primes without the use of `dropWhile`, etc. The below improved code uses a copy of the place in the wheel for each found base prime for ease of use in generating the composite number to-be-culled chains.
 
<syntaxhighlight lang="haskell">-- autogenerates wheel primes, first sieve prime, and gaps
wheelGen :: Int -> ([Int],Int,[Int])
wheelGen n = loop 1 3 [2] [2] where
loop i frst wps gps =
if i >= n then (wps, frst, gps) else
let nfrst = frst + head gps
nhts = (length gps) * (frst - 1)
cmpsts = scanl (\ c g -> c + frst * g) (frst * frst) (cycle gps)
cull n (g:gs') cs@(c:cs') og
| nn >= c = cull nn gs' cs' (og + g) -- n == c; never greater!
| otherwise = (og + g) : cull nn gs' cs 0 where nn = n + g
in nfrst `seq` nhts `seq` loop (i + 1) nfrst (wps ++ [frst]) $ take nhts
$ cull nfrst (tail $ cycle gps) cmpsts 0
 
(wheelPrimes, firstSievePrime, gaps) = wheelGen 7
 
primesTreeFoldingWheeled :: () -> [Int]
primesTreeFoldingWheeled() =
wheelPrimes ++ map fst (
_Y ( ((firstSievePrime, wheel) :) .
gapsW (firstSievePrime + head wheel, tail wheel) . _U .
map (\ (p,w) ->
scanl (\ c m -> c + m * p) (p * p) w ) ) ) where
 
_Y g = g (_Y g) -- non-sharing multi-stage fixpoint Y-combinator
 
wheel = cycle gaps
 
gapsW k@(n,d:w) s@(c:cs) | n < c = k : gapsW (n + d, w) s -- set diff
| otherwise = gapsW (n + d, w) cs -- n == c
_U ((x:xs):t) = -- exactly the same as for odds-only!
x : (union xs . _U . pairs) t where -- tree-shaped folding big union
pairs (xs:ys:t) = union xs ys : pairs t -- ~= nub . sort . concat
union xs@(x:xs') ys@(y:ys')
| x < y = x : union xs' ys
| y < x = y : union xs ys'
| otherwise = x : union xs' ys' -- x and y must be equal!</syntaxhighlight>
 
When compiled with -O2 optimization and -fllvm (the LLVM back end), the above code is over twice as fast as the Odds-Only version as it should be as that is about the ratio of reduced operations minus some slightly increased operation complexity, sieving the primes to a hundred million in about seven seconds on a modern middle range desktop computer. It is almost twice as fast as the "primesW" version due to the increased algorithmic efficiency!
 
Note that the "wheelGen" code could be used to not need to do further culling at all by continuously generating wheels until the square of the "firstSievePrime" is greater than the range as there are no composites left up to that limit, but this is always slower than a SoE due to the high overhead in generating the wheels - this would take a wheel generation of 1229 (number of primes to the square root of a hundred thousand is ten thousand) to create the required wheel sieved to a hundred million; however, the theoretical (if the time to advance through the lists per element were zero, which of course it is not) asymptotic performance would be O(n) instead of O(n log (log n)) where n is the range sieved. Just another case where theory supports (slightly) reduced number of operations, but practicality means that the overheads to do this are so big as to make it useless for any reasonable range ;-) !
 
===Priority Queue based incremental sieve===
Line 5,529 ⟶ 9,601:
The above work is derived from the Epilogue of the Melissa E. O'Neill paper which is much referenced with respect to incremental functional sieves; however, that paper is now dated and her comments comparing list based sieves to her original work leading up to a Priority Queue based implementation is no longer current given more recent work such as the above Tree Merging version. Accordingly, a modern "odd's-only" Priority Queue version is developed here for more current comparisons between the above list based incremental sieves and a continuation of O'Neill's work.
 
In order to implement a Priority Queue version with Haskell, an efficient Priority Queue, which is not part of the standard Haskell libraries, is required. A Min Heap implementation is likely best suited for this task in providing the most efficient frequently used peeks of the next item in the queue and replacement of the first item in the queue (not using a "pop" followed by a "push) with "pop" operations then not used at all, and "push" operations used relatively infrequently. Judging by O'Neill's use of an efficient "deleteMinAndInsert" operation which she states "(We provide deleteMinAndInsert becausea heap-based implementation can support this operation with considerably less rearrangement than a deleteMin followed by an insert.)", which statement is true for a Min Heap Priority Queue and not others, and her reference to a priority queue by (Paulson, 1996), the queue she used is likely the one as provided as a simple true functional [http://rosettacode.org/wiki/Priority_queue#Haskell Min Heap implementation on RosettaCode], from which the essential functions are reproduced here:
<langsyntaxhighlight lang="haskell">data PriorityQ k v = Mt
| Br !k v !(PriorityQ k v) !(PriorityQ k v)
deriving (Eq, Ord, Read, Show)
Line 5,559 ⟶ 9,631:
replaceMinPQ :: Ord k => k -> v -> PriorityQ k v -> PriorityQ k v
replaceMinPQ wk wv Mt = Mt
replaceMinPQ wk wv (Br _ _ pl pr) = siftdown wk wv pl pr</langsyntaxhighlight>
 
The "peekMin" function retrieves both of the key and value in a tuple so processing is required to access whichever is required for further processing. As well, the output of the peekMin function is a Maybe with the case of an empty queue providing a Nothing output.
 
The following code is O'Neill's original odds-only code (without wheel factorization) from her paper slightly adjusted as per the requirements of this Min Heap implementation as laid out above; note the `seq` adjustments to the "adjust" function to make the evaluation of the entry tuple more strict for better efficiency:
<langsyntaxhighlight lang="haskell">-- (c) 2006-2007 Melissa O'Neill. Code may be used freely so long as
-- this copyright message is retained and changed versions of the file
-- are clearly marked.
Line 5,587 ⟶ 9,659:
| otherwise = table
where (n, n':ns) = case peekMinPQ table of
Just tpl -> tpl</langsyntaxhighlight>
 
The above code is almost four times slower than the version of the Tree Merging sieve above for the first million primes although it is about the same speed as the original Richard Bird sieve with the "odds-only" adaptation as above. It is slow and uses a huge amount of memory for primarily one reason: over eagerness in adding prime composite streams to the queue, which are added as the primes are listed rather than when they are required as the output primes stream reaches the square of a given base prime; this over eagerness also means that the processed numbers must have a large range in order to not overflow when squared (as in the default Integer = infinite precision integers as used here and by O'Neill, but Int64's or Word64's would give a practical range) which processing of wide range numbers adds processing and memory requirement overhead. Although O'Neill's code is elegant, it also loses some efficiency due to the extensive use of lazy list processing, not all of which is required even for a wheel factorization implementation.
 
The following code is adjusted to reduce the amount of lazy list processing and to add a secondary base primes stream (or a succession of streams when the combinator is used) so as to overcome the above problems and reduce memory consumption to only that required for the primes below the square root of the currently sieved number; using this means that 32-bit Int's are sufficient for a reasonable range and memory requirements become relatively negligible:
<langsyntaxhighlight lang="haskell">primesPQx :: () -> [Int]
primesPQx() = 2 : _Y ((3 :) . sieve 5 emptyPQ 9) -- initBasePrms
where
_Y g = g (_Y g) -- non-sharing multi-stage fixpoint combinator OR
 
-- initBasePrms = 3 : sieve 5 emptyPQ 9 initBasePrms -- single stage
insertprime p table = let adv = 2 * p in let nv = p * p + adv in
nv `seq` pushPQ nv adv table
sieve n table q bps@(bp:bps')
| n >= q = let nbp = head bps' in let ntbl = insertprime bp table in
ntbl `seq` sieve (n + 2) (insertprime bp table)ntbl (nbp * nbp) bps'
| n >= nextComposite = sievelet (nntbl += 2) (adjust table) q bpsin
ntbl `seq` sieve (n + 2) ntbl q bps
| otherwise = n : sieve (n + 2) table q bps
where
insertprime p table = let adv = 2 * p in let nv = p * p + adv
in nv `seq` pushPQ nv adv table
nextComposite = case peekMinPQ table of
Nothing -> q -- at beginning when queue empty!
Just (c, _) -> c
adjust table
| c <= n = let ncntbl = replaceMinPQ (c + adv) adv intable
ncin ntbl `seq` adjust (replaceMinPQ nc adv table)ntbl
| otherwise = table
where (c, adv) = case peekMinPQ table of Just ct -> ct `seq` ct</syntaxhighlight>
Just ct -> ct</lang>
 
The above code is over five times faster than the previous (O'Neill) Priority Queue code and about half again faster than the Tree -Merging Odds-Only code for a range of a hundred million primes, and; willit alwaysis belikely faster as the Min Heap is slightly more efficient than Tree Merging due to better tree balancing.
 
Since the Tree-Folding version above includes the minor changes to work with a factorization wheel, this should have the same minor modifications for comparison purposes, with the code as follows:
All of these codes including the list based ones would enjoy about the same constant factor improvement of up to about four times the speed with the application of maximum wheel factorization.
 
<syntaxhighlight lang="haskell">-- Note: this code segment uses the same wheelGen as the Tree-Folding version...
 
primesPQWheeled :: () -> [Int]
primesPQWheeled() =
wheelPrimes ++ map fst (
_Y (((firstSievePrime, wheel) :) .
sieve (firstSievePrime + head wheel, tail wheel)
emptyPQ (firstSievePrime * firstSievePrime)) )
where
_Y g = g (_Y g) -- non-sharing multi-stage fixpoint combinator OR
 
wheel = cycle gaps
 
sieve npr@(n,(g:gs')) table q bpprs@(bppr:bpprs')
| n >= q =
let (nbp,_) = head bpprs' in let ntbl = insertprime bppr table in
nbp `seq` ntbl `seq` sieve (n + g, gs') ntbl (nbp * nbp) bpprs'
| n >= nextComposite = let ntbl = adjust table in
ntbl `seq` sieve (n + g, gs') ntbl q bpprs
| otherwise = npr : sieve (n + g, gs') table q bpprs
where
insertprime (p,(pg:pgs')) table =
let nv = p * (p + pg) in nv `seq` pushPQ nv (map (* p) pgs') table
nextComposite = case peekMinPQ table of
Nothing -> q -- at beginning when queue empty!
Just (c, _) -> c
adjust table
| c <= n = let ntbl = replaceMinPQ (c + a) as' table
in ntbl `seq` adjust ntbl
| otherwise = table
where (c, (a:as')) = case peekMinPQ table of Just ct -> ct `seq` ct</syntaxhighlight>
 
Compiled with -O2 optimization and -fllvm (the LLVM back end), this code gains about the expected ratio in performance in sieving to a range of a hundred million, sieving to this range in about five seconds on a modern medium range desktop computer. This is likely the fastest purely functional incremental type SoE useful for moderate ranges up to about a hundred million to a billion.
 
===Page Segmented Sieve using a mutable unboxed array===
 
All of the above unbounded sieves are quite limited in practical sieving range due to the large constant factor overheads in computation, making them mostly just interesting intellectual exercises other than for small ranges of up to about the first million to ten million primes; the following '''"odds-only"''' page-segmented version using (bit-packed internally) mutable unboxed arrays is about 50 times faster than the fastest of the above algorithms for ranges of about that and higher, making it practical for the first several hundred million primes:
<syntaxhighlight lang="haskell">{-# OPTIONS_GHC -O2 -fllvm #-} -- use LLVM for about double speed!
<lang haskell>import Data.Bits
 
import Data.Array.Base
import ControlData.Monad.STInt ( Int64 )
import Data.Array.STWord (runSTUArray, STUArray(..)Word64 )
import Data.Bits ( Bits(shiftR) )
import Data.Array.Base ( IArray(unsafeAt), UArray(UArray),
MArray(unsafeWrite), unsafeFreezeSTUArray )
import Control.Monad ( forM_ )
import Data.Array.ST ( MArray(newArray), runSTUArray )
 
type Prime = Word64
 
cSieveBufferRange :: Int
type PrimeType = Int
szPGBTScSieveBufferRange = (2^14)17 * 8 :: PrimeType -- CPU L1L2 cache in bits
 
primesPagedprimes :: () -> [PrimeTypePrime]
primesPagedprimes() = 2 : _Y (listPagePrms . pagesFrom 0) where
_Y g = g (_Y g) -- non-sharing multi-stage fixpoint combinator
szblmt = cSieveBufferRange - 1
listPagePrms (hdpg @ (UArray lowi _ rng _) : tlpgs) =
listPagePrms pgs@(hdpg@(UArray lwi _ rng _) : tlpgs) =
let loop i = if i >= rng then listPagePrms tlpgs
let loop i | i >= fromIntegral rng = listPagePrms tlpgs
else if unsafeAt hdpg i then loop (i + 1)
| unsafeAt hdpg i = loop else let ii = lowi(i + fromIntegral i in1)
| otherwise = let ii = case 3lwi + iifromIntegral + iii ofin
pcase ->fromIntegral p$ `seq`3 p+ : loop (iii + 1) in loopii 0of
p -> p `seq` p : loop (i + 1) in loop 0
makePg lowi bps = runSTUArray $ do
makePg lwi let limibps = lowi + szPGBTSrunSTUArray -$ 1do
let nxtlimi = 3lwi + limi + limi -- last candidate infromIntegral rangeszblmt
bplmt = floor $ sqrt $ fromIntegral $ limi + limi + 3
cmpsts <- newArray (lowi, limi) False
strta bp = let pbtssi = fromIntegral szPGBTS$ (bp * bp - 3) `shiftR` 1
in if si >= lwi then fromIntegral $ si - lwi else
let cull (p:ps) =
let sqrr = pfromIntegral (lwi - *si) p`mod` inbp
in if sqrr >== nxt0 then return0 else fromIntegral $ bp - cmpstsr
cmpsts <- newArray (lwi, limi) False
else let pi = fromIntegral p in
fcmpsts <- unsafeFreezeSTUArray cmpsts
let cullp c = if c > pbts then return ()
let cbps = if lwi == 0 then listPagePrms [fcmpsts] else dobps
forM_ (takeWhile (<= bplmt) cbps) $ \ bp ->
unsafeWrite cmpsts c True
forM_ (let sp = fromIntegral $ strta bp
cullp (c + pi) in
in [ letsp, asp =+ (sqrfromIntegral -bp 3.. szblmt ]) `shiftR`$ 1\c in->
unsafeWrite cmpsts c True
let s = if a >= lowi then fromIntegral (a - lowi)
return cmpsts
else let r = fromIntegral ((lowi - a) `rem` p) in
pagesFrom lwi bps = map (`makePg` bps)
if r == 0 then 0 else pi - r in
do { cullp s; cull ps} [ lwi, lwi + fromIntegral szblmt + 1 .. ]</syntaxhighlight>
if lowi == 0 then do
pg0 <- unsafeFreezeSTUArray cmpsts
cull $ listPagePrms [pg0]
else cull bps
pagesFrom lowi bps =
let cf lwi = case makePg lwi bps of
pg -> pg `seq` pg : cf (lwi + szPGBTS) in cf lowi</lang>
 
The above code as written has a maximum practical range of about 10^12 or so in about an hour.
The above code is currently implemented to use "Int" as the prime type but one can change the "PrimeType" to "Int64" (importing Data.Int) or "Word64" (importing Data.Word) to extend the range to its maximum practical range of above 10^14 or so. Note that for larger ranges that one will want to set the "szPGBTS" to something close to the CPU L2 or even L3 cache size (up to 8 Megabytes = 2^23 for an Intel i7) for a slight cost in speed (about a factor of 1.5) but so that it still computes fairly efficiently as to memory access up to those large ranges. It would be quite easy to modify the above code to make the page array size automatically increase in size with increasing range.
 
The above code takes only a few tens of milliseconds to compute the first million primes and a few seconds to calculate the first 50 million primes up to a billion, with over half of those times expended in just enumerating the result lazy list, with even worse times when using 64-bit list processing (especially with 32-bit versions of GHC). A further improvement to reduce the computational cost of repeated list processing across the base pages for every page segment would be to store the required base primes (or base prime gaps) in ana arraylazy that gets extended in size by factors of two (by copying the old array to the new extended array) as the numberlist of base primesprime increasesarrays; in that way the scans across base primes per page segment would just mostly be array accesses which are much faster than list enumeration.
 
Unlike many other other unbounded examples, this algorithm has the true Sieve of Eratosthenes computational time complexity of O(n log log n) where n is the sieving range with no extra "log n" factor while having a very low computational time cost per composite number cull of less than ten CPU clock cycles per cull (well under as in under 4 clock cycles for the Intel i7 using a page buffer size of the CPU L1 cache size).
Line 5,673 ⟶ 9,779:
There are other ways to make the algorithm faster including high degrees of wheel factorization, which can reduce the number of composite culling operations by a factor of about four for practical ranges, and multi-processing which can reduce the computation time proportionally to the number of available independent CPU cores, but there is little point to these optimizations as long as the lazy list enumeration is the bottleneck as it is starting to be in the above code. To take advantage of those optimizations, functions need to be provided that can compute the desired results without using list processing.
 
For ranges above about 10^14 where culling spans begin to exceed even an expanded size page array, other techniques need to be adapted such as thesuch useas ofautomatically a "bucket sieve" which tracksextending the nextsieving pagebuffer thatsize largerto basethe primesquare cullingroot sequencesof willthe "hit"maximum torange avoidcurrently redundantsieved (and timesieving expensive)by startCPU addressL1/L2 calculations for base primes that don't "hit" thecache currentsized pagesegments/sections.
 
However, even with the above code and its limitations for large sieving ranges, the speeds will never come close to as slow as the other "incremental" sieve algorithms, as the time will never exceed about 10020 CPU clock cycles per composite number cull, where the fastest of those other algorithms takes many hundreds of CPU clock cycles per cull.
 
'''A faster method of counting primes with a similar algorithm'''
 
To show the limitations of the individual prime enumeration, the following code has been refactored from the above to provide an alternate very fast method of counting the unset bits in the culled array (the primes = none composite) using a CPU native pop count instruction:
 
<syntaxhighlight lang="haskell">{-# LANGUAGE FlexibleContexts #-}
{-# OPTIONS_GHC -O2 -fllvm #-} -- use LLVM for about double speed!
 
import Data.Time.Clock.POSIX ( getPOSIXTime ) -- for timing
 
import Data.Int ( Int64 )
import Data.Word ( Word64 )
import Data.Bits ( Bits((.&.), (.|.), shiftL, shiftR, popCount) )
import Control.Monad.ST ( ST, runST )
import Data.Array.Base ( IArray(unsafeAt), UArray(UArray), STUArray,
MArray(unsafeRead, unsafeWrite), castSTUArray,
unsafeThawSTUArray, unsafeFreezeSTUArray )
import Control.Monad ( forM_ )
import Data.Array.ST ( MArray(newArray), runSTUArray )
 
type Prime = Word64
 
cSieveBufferRange :: Int
cSieveBufferRange = 2^17 * 8 -- CPU L2 cache in bits
 
type PrimeNdx = Int64
type SieveBuffer = UArray PrimeNdx Bool
cWHLPRMS :: [Prime]
cWHLPRMS = [ 2 ]
cFRSTSVPRM :: Prime
cFRSTSVPRM = 3
primesPages :: () -> [SieveBuffer]
primesPages() = _Y (pagesFrom 0 . listPagePrms) where
_Y g = g (_Y g) -- non-sharing multi-stage fixpoint Y-combinator
szblmt = fromIntegral (cSieveBufferRange `shiftR` 1) - 1
makePg lwi bps = runSTUArray $ do
let limi = lwi + fromIntegral szblmt
mxprm = cFRSTSVPRM + fromIntegral (limi + limi)
bplmt = floor $ sqrt $ fromIntegral mxprm
strta bp = let si = fromIntegral $ (bp * bp - cFRSTSVPRM) `shiftR` 1
in if si >= lwi then fromIntegral $ si - lwi else
let r = fromIntegral (lwi - si) `mod` bp
in if r == 0 then 0 else fromIntegral $ bp - r
cmpsts <- newArray (lwi, limi) False
fcmpsts <- unsafeFreezeSTUArray cmpsts
let cbps = if lwi == 0 then listPagePrms [fcmpsts] else bps
forM_ (takeWhile (<= bplmt) cbps) $ \ bp ->
forM_ (let sp = fromIntegral $ strta bp
in [ sp, sp + fromIntegral bp .. szblmt ]) $ \c ->
unsafeWrite cmpsts c True
return cmpsts
pagesFrom lwi bps = map (`makePg` bps)
[ lwi, lwi + fromIntegral szblmt + 1 .. ]
 
-- convert a list of sieve buffers to a list of primes...
listPagePrms :: [SieveBuffer] -> [Prime]
listPagePrms pgs@(pg@(UArray lwi _ rng _) : pgstl) = bsprm `seq` loop 0 where
bsprm = cFRSTSVPRM + fromIntegral (lwi + lwi)
loop i | i >= rng = listPagePrms pgstl
| unsafeAt pg i = loop (i + 1)
| otherwise = case bsprm + fromIntegral (i + i) of
p -> p `seq` p : loop (i + 1)
primes :: () -> [Prime]
primes() = cWHLPRMS ++ listPagePrms (primesPages())
 
-- very fast using popCount by words technique...
countSieveBuffer :: Int -> UArray PrimeNdx Bool -> Int64
countSieveBuffer lstndx sb = fromIntegral $ runST $ do
cmpsts <- unsafeThawSTUArray sb :: ST s (STUArray s PrimeNdx Bool)
wrdcmpsts <-
(castSTUArray :: STUArray s PrimeNdx Bool ->
ST s (STUArray s PrimeNdx Word64)) cmpsts
let lstwrd = lstndx `shiftR` 6
lstmsk = 0xFFFFFFFFFFFFFFFE `shiftL` (lstndx .&. 63) :: Word64
loop wi cnt
| wi < lstwrd = do
v <- unsafeRead wrdcmpsts wi
case cnt - popCount v of ncnt -> ncnt `seq` loop (wi + 1) ncnt
| otherwise = do
v <- unsafeRead wrdcmpsts lstwrd
return $ fromIntegral (cnt - popCount (v .|. lstmsk))
loop 0 (lstwrd * 64 + 64)
 
-- count the remaining un-marked composite bits using very fast popcount...
countPrimesTo :: Prime -> Int64
countPrimesTo limit =
let lmtndx = fromIntegral $ (limit - 3) `shiftR` 1
loop (pg@(UArray lwi lmti rng _) : pgstl) cnt
| lmti >= lmtndx =
(cnt + countSieveBuffer (fromIntegral $ lmtndx - lwi) pg)
| otherwise = loop pgstl (cnt + countSieveBuffer (rng - 1) pg)
in if limit < 3 then if limit < 2 then 0 else 1
else loop (primesPages()) 1
 
-- test it...
main :: IO ()
main = do
let limit = 10^9 :: Prime
 
strt <- getPOSIXTime
-- let answr = length $ takeWhile (<= limit) $ primes()-- slow way
let answr = countPrimesTo limit -- fast way
stop <- answr `seq` getPOSIXTime -- force evaluation of answr b4 stop time!
let elpsd = round $ 1e3 * (stop - strt) :: Int64
putStr $ "Found " ++ show answr
putStr $ " primes up to " ++ show limit
putStrLn $ " in " ++ show elpsd ++ " milliseconds."</syntaxhighlight>
 
When compiled with the "fast way" commented out and the "slow way enabled, the time to find the number of primes up to one billion is about 3.65 seconds on an Intel Sandy Bridge i3-2100 at 3.1 Ghz; with the "fast way" enabled instead, the time is only about 1.45 seconds for the same range, both compiled with the LLVM back end. This shows that more than half of the time for the "slow way" is spent just producing and enumerating the list of primes!
 
On a Intel Sky Lake i5-2500 CPU @ 3.6 GHz (turbo boost for single threaded as here) compiled with LLVM and 256 Kilobyte buffer size (CPU L2 sized), using the fast counting method:
* takes 1.085 seconds to sieve to 10^9: about 3.81 CPU clocks per cull
* takes 126 seconds to sieve to 10^11: about 4.0 CPU clocks per cull
 
This shows a slight loss of efficiency in clocks per cull due to the average culling span size coming closer to the cull buffer span size, meaning that the loop overhead in address calculation and CPU L1 cache overflows increases just a bit for these relative ranges.
 
This an extra about 20% faster than using the Sandy Bridge i5-2100 above by more than the ratio of CPU clock speeds likely due to the better Instructions Per Clock of the newer Sky Lake architecture due to improved branch prediction and elision of a correctly predicted branch down to close to zero time.
 
This is about 25 to 30 per cent faster than not using LLVM for this Sky Lake processor due to the poor register allocation and optimizations by the Native Code Gnerator compared to LLVM.
 
===APL-style===
Rolling set subtraction over the rolling element-wise addition on integers. Basic, slow, worse than quadratic in the number of primes produced, empirically:
<langsyntaxhighlight lang="haskell">zipWith (flip (!!)) [0..] -- or: take n . last . take n ...
. scanl1 minus
. scanl1 (zipWith (+)) $ repeat [2..]</langsyntaxhighlight>
Or, a wee bit faster:
<langsyntaxhighlight lang="haskell">unfoldr (\(a:b:t) -> Just . (head &&& (:t) . (`minus` b)
. tail) $ a)
. scanl1 (zipWith (+)) $ repeat [2..]</langsyntaxhighlight>
A bit optimized, much faster, with better complexity,
<langsyntaxhighlight lang="haskell">tail . concat
. unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))
. span (< head b) $ a)
. scanl1 (zipWith (+) . tail) $ tails [1..]
-- $ [ [n*n, n*n+n..] | n <- [1..] ]</langsyntaxhighlight>
 
getting nearer to the functional equivalent of the <code>primesPE</code> above, i.e.
<langsyntaxhighlight lang="haskell">fix ( (2:) . concat
. unfoldr (\(a:b:t) -> Just . second ((:t) . (`minus` b))
. span (< head b) $ a)
. ([3..] :) . map (\p-> [p*p, p*p+p..]) )</langsyntaxhighlight>
 
An illustration:
<langsyntaxhighlight lang="haskell">> mapM_ (print . take 15) $ take 10 $ scanl1 (zipWith(+)) $ repeat [2..]
[ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
[ 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]
Line 5,722 ⟶ 9,949:
[ 64, 72, 80, 88, 96,104,112,120,128,136,144,152,160,168,176]
[ 81, 90, 99,108,117,126,135,144,153,162,171,180,189,198,207]
[100,110,120,130,140,150,160,170,180,190,200,210,220,230,240]</langsyntaxhighlight>
 
=={{header|HicEst}}==
<langsyntaxhighlight lang="hicest">REAL :: N=100, sieve(N)
 
sieve = $ > 1 ! = 0 1 1 1 1 ...
Line 5,738 ⟶ 9,965:
DO i = 1, N
IF( sieve(i) ) WRITE() i
ENDDO </langsyntaxhighlight>
 
=={{header|Hoon}}==
<syntaxhighlight lang="hoon">:: Find primes by the sieve of Eratosthenes
!:
|= end=@ud
=/ index 2
=/ primes `(list @ud)`(gulf 1 end)
|- ^- (list @ud)
?: (gte index (lent primes)) primes
$(index +(index), primes +:(skid primes |=([a=@ud] &((gth a index) =(0 (mod a index))))))
</syntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight Iconlang="icon"> procedure main()
sieve(100)
end
Line 5,751 ⟶ 9,989:
do p[j] := 0
every write(i:=2 to n & p[i] == 1 & i)
end</langsyntaxhighlight>
 
Alternatively using sets
<langsyntaxhighlight Iconlang="icon"> procedure main()
sieve(100)
end
Line 5,765 ⟶ 10,003:
delete(primes,1)
every write(!sort(primes))
end</langsyntaxhighlight>
 
=={{header|J}}==
{{eff note|J|i.&.(p:inv) }}
 
Implementation:<syntaxhighlight lang="j">sieve=: {{
This problem is a classic example of how J can be used to represent mathematical concepts.
r=. 0#t=. y# j=.1
 
while. y>j=.j+1 do.
J uses x|y ([http://www.jsoftware.com/help/dictionary/d230.htm residue]) to represent the operation of finding the remainder during integer division of y divided by x
if. j{t do.
 
t=. t > y$j{.1
<lang J> 10|13
r=. r, j
3</lang>
end.
 
And x|/y gives us a [http://www.jsoftware.com/help/dictionary/d420.htm table] with all possibilities from x and all possibilities from y.
 
<lang J> 2 3 4 |/ 2 3 4
0 1 0
2 0 1
2 3 0</lang>
 
Meanwhile, |/~y ([http://www.jsoftware.com/help/dictionary/d220v.htm reflex]) copies the right argument and uses it as the left argment.
 
<lang J> |/~ 0 1 2 3 4
0 1 2 3 4
0 0 0 0 0
0 1 0 1 0
0 1 2 0 1
0 1 2 3 0</lang>
 
(Bigger examples might make the patterns more obvious but they also take up more space.)
 
By the way, we can ask J to count out the first N integers for us using i. ([http://www.jsoftware.com/help/dictionary/didot.htm integers]):
 
<lang J> i. 5
0 1 2 3 4</lang>
 
Anyways, the 0s in that last table represent the Sieve of Eratosthenes (in a symbolic or mathematical sense), and we can use = ([http://www.jsoftware.com/help/dictionary/d000.htm equal]) to find them.
 
<lang J> 0=|/~ i.5
1 0 0 0 0
1 1 1 1 1
1 0 1 0 1
1 0 0 1 0
1 0 0 0 1</lang>
 
Now all we need to do is add them up, using / ([http://www.jsoftware.com/help/dictionary/d420.htm insert]) in its single argument role to insert + between each row of that last table.
 
<lang J> +/0=|/~ i.5
5 1 2 2 3</lang>
 
The sieve wants the cases where we have two divisors:
 
<lang J> 2=+/0=|/~ i.5
0 0 1 1 0</lang>
 
And we just want to know the positions of the 1s in that list, which we can find using I. ([http://www.jsoftware.com/help/dictionary/dicapdot.htm indices]):
 
<lang J> I.2=+/0=|/~ i.5
2 3
I.2=+/0=|/~ i.100
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</lang>
 
And we might want to express this sentence as a definition of a word that lets us use it with an arbitrary argument. There are a variety of ways of doing this. For example:
 
<lang J>sieve0=: verb def 'I.2=+/0=|/~ i.y'</lang>
 
That said, this fails with an argument of 2 (instead of giving an empty list of the primes smaller than 2, it gives a list with one element: 0). Working through why this is and why this matters can be an informative exercise. But, assuming this matters, we need to add some guard logic to prevent that problem:
 
<lang J>sieve0a=: verb def 'I.(y>2)*2=+/0=|/~ i.y'</lang>
 
Of course, we can also express this in an even more elaborate fashion. The elaboration makes more efficient use of resources for large arguments, at the expense of less efficient use of resources for small arguments:
 
<lang J>sieve1=: 3 : 0
m=. <.%:y
z=. $0
b=. y{.1
while. m>:j=. 1+b i. 0 do.
b=. b+.y$(-j){.1
z=. z,j
end.
}}</syntaxhighlight>
z,1+I.-.b
)</lang>
 
Example:
"Wheels" may be implemented as follows:
 
<syntaxhighlight lang="j"> sieve 100
<lang J>sieve2=: 3 : 0
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</syntaxhighlight>
m=. <.%:y
z=. y (>:#]) 2 3 5 7
b=. 1,}.y$+./(*/z)$&>(-z){.&.>1
while. m>:j=. 1+b i. 0 do.
b=. b+.y$(-j){.1
z=. z,j
end.
z,1+I.-.b
)</lang>
 
To see into how this works, we can change the definition:
The use of<tt> 2 3 5 7 </tt>as wheels provides a
20% time improvement for<tt> n=1000 </tt>and 2% for<tt> n=1e6</tt> but note that sieve2 is still 25 times slower than i.&.(p:inv) for <tt>n=1e6</tt>. Then again, the value of the sieve of eratosthenes was not efficiency but simplicity. So perhaps we should ignore resource consumption issues and instead focus on intermediate results for reasonably sized example problems?
 
<syntaxhighlight lang J="j"> 0sieve=|/~: i.8{{
1 0 0r=. 0#t=. 0y# 0 0 0j=.1
while. y>j=.j+1 do.
1 1 1 1 1 1 1 1
1 0 1 0 1if. 0j{t 1 0do.
echo j;(y$j{.1);t=. t > y$j{.1
1 0 0 1 0 0 1 0
1 0 0 0 1 0 0r=. 0r, j
1 0 0 0 0 1 0 0end.
1 0 0 0 0 0 1 0
1 0 0 0 0 0 0 1</lang>
 
Columns with two "1" values correspond to prime numbers.
 
'''Alternate Implementation'''
 
If you feel that the intermediate results, above, are not enough "sieve-like" another approach could be:
 
<lang J>sieve=:verb define
seq=: 2+i.y-1 NB. 2 thru y
n=. 2
l=. #seq
whilst. -.seq-:prev do.
prev=. seq
mask=. l{.1-(0{.~n-1),1}.l$n{.1
seq=. seq * mask
n=. {.((n-1)}.seq)-.0
end.
}}</syntaxhighlight>
seq -. 0
)</lang>
 
And go:<syntaxhighlight lang="j"> sieve 10
Example use:
┌─┬───────────────────┬───────────────────┐
│2│1 0 1 0 1 0 1 0 1 0│0 1 0 1 0 1 0 1 0 1│
└─┴───────────────────┴───────────────────┘
┌─┬───────────────────┬───────────────────┐
│3│1 0 0 1 0 0 1 0 0 1│0 1 0 0 0 1 0 1 0 0│
└─┴───────────────────┴───────────────────┘
┌─┬───────────────────┬───────────────────┐
│5│1 0 0 0 0 1 0 0 0 0│0 1 0 0 0 0 0 1 0 0│
└─┴───────────────────┴───────────────────┘
┌─┬───────────────────┬───────────────────┐
│7│1 0 0 0 0 0 0 1 0 0│0 1 0 0 0 0 0 0 0 0│
└─┴───────────────────┴───────────────────┘
2 3 5 7</syntaxhighlight>
 
Thus, here, <code>t</code> would select numbers which have not yet been determined to be a multiple of a prime number.
<lang J> sieve 100
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</lang>
 
=={{header|Janet}}==
To see intermediate results, let's show them:
 
===Simple, all primes below a limit===
<lang J>label=:dyad def 'echo x,":y'
Janet has a builtin [https://janet-lang.org/docs/data_structures/buffers.html "buffer" type] which is used as a mutable byte string. It has builtin utility methods to handle bit strings (see [https://janet-lang.org/api/buffer.html here] :)
 
This is based off the Python version.
sieve=:verb define
'seq ' label seq=: 2+i.y-1 NB. 2 thru y
'n ' label n=. 2
'l ' label l=. #seq
whilst. -.seq-:prev do.
prev=. seq
'mask ' label mask=. l{.1-(0{.~n-1),1}.l$n{.1
'seq ' label seq=. seq * mask
'n ' label n=. {.((n-1)}.seq)-.0
end.
seq -. 0
)
 
<syntaxhighlight lang="janet">(defn primes-before
seq 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
"Gives all the primes < limit"
n 2
[limit]
l 59
(assert (int? limit))
mask 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
# Janet has a buffer type (mutable string) which has easy methods for use as bitset
seq 2 3 0 5 0 7 0 9 0 11 0 13 0 15 0 17 0 19 0 21 0 23 0 25 0 27 0 29 0 31 0 33 0 35 0 37 0 39 0 41 0 43 0 45 0 47 0 49 0 51 0 53 0 55 0 57 0 59 0
(def buf-size (math/ceil (/ limit 8)))
n 3
(def is-prime (buffer/new-filled buf-size (bnot 0)))
mask 1 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0
(print "Size" buf-size "is-prime: " is-prime)
seq 2 3 0 5 0 7 0 0 0 11 0 13 0 0 0 17 0 19 0 0 0 23 0 25 0 0 0 29 0 31 0 0 0 35 0 37 0 0 0 41 0 43 0 0 0 47 0 49 0 0 0 53 0 55 0 0 0 59 0
(buffer/bit-clear is-prime 0)
n 5
(buffer/bit-clear is-prime 1)
mask 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0
(for n 0 (math/ceil (math/sqrt limit))
seq 2 3 0 5 0 7 0 0 0 11 0 13 0 0 0 17 0 19 0 0 0 23 0 0 0 0 0 29 0 31 0 0 0 0 0 37 0 0 0 41 0 43 0 0 0 47 0 49 0 0 0 53 0 0 0 0 0 59 0
(if (buffer/bit is-prime n) (loop [i :range-to [(* n n) limit n]]
n 7
(buffer/bit-clear is-prime i))))
mask 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1
(def res @[]) # Result: Mutable array
seq 2 3 0 5 0 7 0 0 0 11 0 13 0 0 0 17 0 19 0 0 0 23 0 0 0 0 0 29 0 31 0 0 0 0 0 37 0 0 0 41 0 43 0 0 0 47 0 0 0 0 0 53 0 0 0 0 0 59 0
n (for i 0 11limit
(if (buffer/bit is-prime i)
mask 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
(array/push res i)))
seq 2 3 0 5 0 7 0 0 0 11 0 13 0 0 0 17 0 19 0 0 0 23 0 0 0 0 0 29 0 31 0 0 0 0 0 37 0 0 0 41 0 43 0 0 0 47 0 0 0 0 0 53 0 0 0 0 0 59 0
(def res (array/new limit))
n 13
(for i 0 limit
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59</lang>
(if (buffer/bit is-prime i)
 
(array/push res i)))
Another variation on this theme would be:
res)</syntaxhighlight>
 
<lang J>sieve=:verb define
seq=: 2+i.y-1 NB. 2 thru y
n=. 1
l=. #seq
whilst. -.seq-:prev do.
prev=. seq
n=. 1+n+1 i.~ * (n-1)}.seq
inds=. (2*n)+n*i.(<.l%n)-1
seq=. 0 inds} seq
end.
seq -. 0
)</lang>
 
Intermediate results for this variant are left as an exercise for the reader
 
=={{header|Java}}==
{{works with|Java|1.5+}}
<langsyntaxhighlight lang="java5">import java.util.LinkedList;
 
public class Sieve{
Line 5,974 ⟶ 10,106:
return primes;
}
}</langsyntaxhighlight>
 
To optimize by testing only odd numbers, replace the loop marked "unoptimized" with these lines:
<langsyntaxhighlight lang="java5">nums.add(2);
for(int i = 3;i <= n;i += 2){
nums.add(i);
}</langsyntaxhighlight>
 
Version using List:
<syntaxhighlight lang="java5">
import java.util.ArrayList;
import java.util.List;
 
public class Eratosthenes {
public List<Integer> sieve(Integer n) {
List<Integer> primes = new ArrayList<Integer>(n);
boolean[] isComposite = new boolean[n + 1];
for(int i = 2; i <= n; i++) {
if(!isComposite[i]) {
primes.add(i);
for(int j = i * i; j <= n; j += i) {
isComposite[j] = true;
}
}
}
return primes;
}
}
</syntaxhighlight>
Version using a BitSet:
<langsyntaxhighlight lang="java5">import java.util.LinkedList;
import java.util.BitSet;
 
Line 5,998 ⟶ 10,151:
return primes;
}
}</langsyntaxhighlight>
 
 
Version using a TreeSet:
<syntaxhighlight lang="java5">import java.util.Set;
import java.util.TreeSet;
 
public class Sieve{
public static Set<Integer> findPrimeNumbers(int limit) {
int last = 2;
TreeSet<Integer> nums = new TreeSet<>();
 
if(limit < last) return nums;
 
for(int i = last; i <= limit; i++){
nums.add(i);
}
 
return filterList(nums, last, limit);
}
 
private static TreeSet<Integer> filterList(TreeSet<Integer> list, int last, int limit) {
int squared = last*last;
if(squared < limit) {
for(int i=squared; i <= limit; i += last) {
list.remove(i);
}
return filterList(list, list.higher(last), limit);
}
return list;
}
}</syntaxhighlight>
 
===Infinite iterator===
Line 6,004 ⟶ 10,188:
{{trans|Python}}
{{works with|Java|1.5+}}
<langsyntaxhighlight lang="java5">import java.util.Iterator;
import java.util.PriorityQueue;
import java.math.BigInteger;
Line 6,057 ⟶ 10,241:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 6,076 ⟶ 10,260:
{{trans|Python}}
{{works with|Java|1.5+}}
<langsyntaxhighlight lang="java5">import java.util.Iterator;
import java.util.HashMap;
Line 6,134 ⟶ 10,318:
}
}</langsyntaxhighlight>
 
{{out}}<pre>Found 5761455 primes up to 100000000 in 4297 milliseconds.</pre>
Line 6,144 ⟶ 10,328:
{{trans|JavaScript}}
{{works with|Java|1.5+}}
<langsyntaxhighlight lang="java5">import java.util.Iterator;
import java.util.ArrayList;
 
Line 6,221 ⟶ 10,405:
}
}</langsyntaxhighlight>
 
{{out}}<pre>Found 50847534 primes up to 1000000000 in 3201 milliseconds.</pre>
 
=={{header|JavaScript}}==
<langsyntaxhighlight lang="javascript">function eratosthenes(limit) {
var primes = [];
if (limit >= 2) {
Line 6,252 ⟶ 10,436:
if (typeof print == "undefined")
print = (typeof WScript != "undefined") ? WScript.Echo : alert;
print(primes);</langsyntaxhighlight>
outputs:
<pre>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</pre>
Line 6,258 ⟶ 10,442:
Substituting the following code for the function for '''an odds-only algorithm using bit packing''' for the array produces code that is many times faster than the above:
 
<langsyntaxhighlight lang="javascript">function eratosthenes(limit) {
var prms = [];
if (limit >= 2) prms = [2];
Line 6,279 ⟶ 10,463:
}
return prms;
}</langsyntaxhighlight>
 
While the above code is quite fast especially using an efficient JavaScript engine such as Google Chrome's V8, it isn't as elegant as it could be using the features of the new EcmaScript6 specification when it comes out about the end of 2014 and when JavaScript engines including those of browsers implement that standard in that we might choose to implement an incremental algorithm iterators or generators similar to as implemented in Python or F# (yield). Meanwhile, we can emulate some of those features by using a simulation of an iterator class (which is easier than using a call-back function) for an '''"infinite" generator based on an Object dictionary''' as in the following odds-only code written as a JavaScript class:
 
<langsyntaxhighlight lang="javascript">var SoEIncClass = (function () {
function SoEIncClass() {
this.n = 0;
Line 6,324 ⟶ 10,508:
};
return SoEIncClass;
})();</langsyntaxhighlight>
 
The above code can be used to find the nth prime (which would require estimating the required range limit using the previous fixed range code) by using the following code:
 
<langsyntaxhighlight lang="javascript">var gen = new SoEIncClass();
for (var i = 1; i < 1000000; i++, gen.next());
var prime = gen.next();
Line 6,334 ⟶ 10,518:
if (typeof print == "undefined")
print = (typeof WScript != "undefined") ? WScript.Echo : alert;
print(prime);</langsyntaxhighlight>
 
to produce the following output (about five seconds using Google Chrome's V8 JavaScript engine):
Line 6,344 ⟶ 10,528:
This can be implemented as '''an "infinite" odds-only generator using page segmentation''' for a considerable speed-up with the alternate JavaScript class code as follows:
 
<langsyntaxhighlight lang="javascript">var SoEPgClass = (function () {
function SoEPgClass() {
this.bi = -1; // constructor resets the enumeration to start...
Line 6,400 ⟶ 10,584:
};
return SoEPgClass;
})();</langsyntaxhighlight>
 
The above code is about fifty times faster (about five seconds to calculate 50 million primes to about a billion on the Google Chrome V8 JavaScript engine) than the above dictionary based code.
 
The speed for both of these "infinite" solutions will also respond to further wheel factorization techniques, especially for the dictionary based version where any added overhead to deal with the factorization wheel will be negligible compared to the dictionary overhead. The dictionary version would likely speed up about a factor of three or a little more with maximum wheel factorization applied; the page segmented version probably won't gain more than a factor of two and perhaps less due to the overheads of array look-up operations.
 
function is copy-pasted from above to produce a webpage version for beginners:
<syntaxhighlight lang="javascript">
<script>
function eratosthenes(limit) {
var primes = [];
if (limit >= 2) {
var sqrtlmt = Math.sqrt(limit) - 2;
var nums = new Array(); // start with an empty Array...
for (var i = 2; i <= limit; i++) // and
nums.push(i); // only initialize the Array once...
for (var i = 0; i <= sqrtlmt; i++) {
var p = nums[i]
if (p)
for (var j = p * p - 2; j < nums.length; j += p)
nums[j] = 0;
}
for (var i = 0; i < nums.length; i++) {
var p = nums[i];
if (p)
primes.push(p);
}
}
return primes;
}
var primes = eratosthenes(100);
output='';
for (var i = 0; i < primes.length; i++) {
output+=primes[i];
if (i < primes.length-1) output+=',';
}
document.write(output);
</script>
</syntaxhighlight>
 
=={{header|JOVIAL}}==
<syntaxhighlight lang="jovial">
<lang JOVIAL>
START
FILE MYOUTPUT ... $ ''Insufficient information to complete this declaration''
Line 6,461 ⟶ 10,679:
END
TERM$
</syntaxhighlight>
</lang>
 
=={{header|jq}}==
{{works with|jq|1.4}}
==Bare Bones==
 
Short and sweet ...
 
<langsyntaxhighlight lang="jq"># Denoting the input by $n, which is assumed to be a positive integer,
# eratosthenes/0 produces an array of primes less than or equal to $n:
def eratosthenes:
 
# erase(i) sets .[i*j] to false for integral j > 1
def erase(i):
if .[i] then reduce range(2; (1 + length) / i) as $j (.; .[i * $j] = false)
reduce (range(2*i; length; i)) as $j (.; .[$j] = false)
else .
end;
Line 6,482 ⟶ 10,700:
| [null, null, range(2; $n)]
| reduce (2, 1 + (2 * range(1; $s))) as $i (.; erase($i))
| map(select(.));</langsyntaxhighlight>
'''Examples''':
<syntaxhighlight lang ="jq">100 | eratosthenes</langsyntaxhighlight>
{{out}}
 
[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]
<syntaxhighlight lang ="jq">1e7 | eratosthenes | length</langsyntaxhighlight>
{{out}}
664579
 
===Enhanced Sieve===
Here is a more economical variant that:
 
* produces a stream of primes less than or equal to a given integer;
* only records the status of odd integers greater than 3 during the sieving process;
* optimizes the inner loop as described in the task description.
 
<syntaxhighlight lang=jq>
def primes:
# The array we use for the sieve only stores information for the odd integers greater than 1:
# index integer
# 0 3
# k 2*k + 3
# So if we wish to mark m = 2*k + 3, the relevant index is: m - 3 / 2
def ix:
if . % 2 == 0 then null
else ((. - 3) / 2)
end;
# erase(i) sets .[i*j] to false for odd integral j > i, and assumes i is odd
def erase(i):
((i - 3) / 2) as $k
# Consider relevant multiples:
then (((length * 2 + 3) / i)) as $upper
# ... only consider odd multiples from i onwards
| reduce range(i; $upper; 2) as $j (.;
(((i * $j) - 3) / 2) as $m
| if .[$m] then .[$m] = false else . end);
 
if . < 2 then []
else (. + 1) as $n
| (($n|sqrt) / 2) as $s
| [range(3; $n; 2)|true]
| reduce (1 + (2 * range(1; $s)) ) as $i (.; erase($i))
| . as $sieve
| 2, (range(3; $n; 2) | select($sieve[ix]))
end ;
 
def count(s): reduce s as $_ (0; .+1);
 
count(1e6 | primes)
</syntaxhighlight>
{{output}}
<pre>
78498
</pre>
 
=={{header|Julia}}==
 
Started with 2 already in the array, and then test only for odd numbers and push the prime ones onto the array.
<langsyntaxhighlight lang="julia"># Returns an array of positive prime numbers less than or equal to lim
function sieve(lim :: Int)
if lim < 2 return [] end
Line 6,514 ⟶ 10,779:
end
return result
end</langsyntaxhighlight>
 
Alternate version using <code>findall</code> to get all primes at once in the end
 
<syntaxhighlight lang ="julia">function sieve(n :: IntInteger)
isprimeprimes = truesfill(true, n)
isprimeprimes[1] = false
for p in 2:n
if isprimeprimes[p] || continue
primes[p .* (2:n÷p)] j .= p * pfalse
if j > n
return findall(isprime)
else
for k in j:p:n
isprime[k] = false
end
end
end
end
findall(primes)
end</lang>
end</syntaxhighlight>
 
At about 35 seconds for a range of a billion on my Intel Atom i5-Z8350 CPU at 1.92 GHz (single threaded) or about 70 CPU clock cycles per culling operation, the above examples are two of the very slowest ways to compute the Sieve of Eratosthenes over any kind of a reasonable range due to a couple of factors:
Line 6,546 ⟶ 10,804:
If one is going to "crib" the MatLab algorithm as above, one may as well do it using odds-only as per the MatLab built-in. The following alternate code improves on the "Alternate" example above by making it sieve odds-only and adjusting the result array contents after to suit:
 
<langsyntaxhighlight lang="julia">function sieve2(n :: Int)
ni = (n - 1) ÷ 2
isprime = trues(ni)
Line 6,565 ⟶ 10,823:
end
end
end</langsyntaxhighlight>
 
This takes less about 18.5 seconds or 36 CPU cycles per culling operation to find the primes to a billion, but that is still quite slow compared to what can be done below. Note that the result array needs to be created then copied, created by the <code>findall</code> function, then modified in place by the <code>map!</code> function to transform the indices to primes, and finally copied by the <code>pushfirst!</code> function to add the only even prime of two to the beginning, but these operations are quire fast. However, this still consumes a lot of memory, as in about 64 Megabytes for the sieve buffer and over 400 Megabytes for the result (8-byte Int's for 64 bit execution) to sieve to a billion, and culling the huge culling buffer that doesn't fit the CPU cache sizes is what makes it slow.
Line 6,573 ⟶ 10,831:
The creation of an output results array is not necessary if the purpose is just to scan across the resulting primes once, they can be output using an iterator (from a `BitArray`) as in the following odds-only code:
 
<langsyntaxhighlight lang="julia">const Prime = UInt64
 
struct Primes
Line 6,621 ⟶ 10,879:
return (i + i + 1, i + 1)
end
end</langsyntaxhighlight>
 
for which using the following code:
 
<langsyntaxhighlight lang="julia">function bench()
@time length(Primes(100)) # warm up JIT
# println(@time count(x->true, Primes(1000000000))) # about 1.5 seconds slower counting over iteration
println(@time length(Primes(1000000000)))
end
bench()</langsyntaxhighlight>
 
results in the following output:
Line 6,644 ⟶ 10,902:
For any kind of reasonably large range such as a billion, a page segmented version should be used with the pages sized to the CPU caches for much better memory access times. As well, the following odds-only example uses a custom bit packing algorithm for a further two times speed-up, also reducing the memory allocation delays by reusing the sieve buffers when possible (usually possible):
 
<langsyntaxhighlight lang="julia">const Prime = UInt64
const BasePrime = UInt32
const BasePrimesArray = Array{BasePrime,1}
Line 6,841 ⟶ 11,099:
end
low + state + state, state + 1
end</langsyntaxhighlight>
 
When tested with the following code:
 
<langsyntaxhighlight lang="julia">function bench()
print("( ")
for p in PrimesPaged() p > 100 && break; print(p, " ") end
Line 6,859 ⟶ 11,117:
println(@time countPrimesTo(Prime(1000000000)))
end
bench()</langsyntaxhighlight>
 
it produces the following:
Line 6,879 ⟶ 11,137:
One of the best simple purely functional Sieve of Eratosthenes algorithms is the infinite tree folding sequence algorithm as implemented in Haskell. As Julia does not have a standard LazyList implementation or library and as a full memoizing lazy list is not required for this algorithm, the following odds-only code implements the rudiments of a Co-Inductive Stream (CIS) in its implementation:
 
<langsyntaxhighlight lang="julia">const Thunk = Function # can't define other than as a generalized Function
 
struct CIS{T}
Line 6,921 ⟶ 11,179:
|> allmultiples |> composites))
CIS{Int}(2, () -> oddprimes())
end</langsyntaxhighlight>
 
when tested with the following:
 
<langsyntaxhighlight lang="julia">@time let count = 0; for p in treefoldingprimes() p > 1000000 && break; count += 1 end; count end</langsyntaxhighlight>
 
it outputs the following:
Line 6,940 ⟶ 11,198:
To gain some extra speed above the purely functional algorithm above, the Python'ish version as a mutable iterator embedding a mutable standard base Dictionary can be used. The following version uses a secondary delayed injection stream of "base" primes defined recursively to provide the successions of composite values in the Dictionary to be used for sieving:
 
<langsyntaxhighlight Julialang="julia">const Prime = UInt64
abstract type PrimesDictAbstract end # used for forward reference
mutable struct PrimesDict <: PrimesDictAbstract
Line 6,978 ⟶ 11,236:
end
end
end</langsyntaxhighlight>
 
The above version can be used and tested with similar code as for the functional version, but is about ten times faster at about 400 CPU clock cycles per culling operation, meaning it has a practical range ten times larger although it still has a O(n (log n) (log log n)) asymptotic performance complexity; for larger ranges such as sieving to a billion or more, this is still over a hundred times slower than the page segmented version using a page segmented sieving array.
 
=={{header|KotlinKlingphix}}==
<syntaxhighlight lang="klingphix">include ..\Utilitys.tlhy
<lang kotlin>fun sieve(limit: Int): List<Int> {
val primes = mutableListOf<Int>()
 
if (%limit >= 2) {%i
1000 !limit
val numbers = Array(limit + 1) { true }
( 1 $limit ) sequence
val sqrtLimit = Math.sqrt(limit.toDouble()).toInt()
 
( 2 $limit sqrt int ) [ !i $i get [ ( 2 $limit 1 - $i / int ) [ $i * false swap set ] for ] if ] for
for (factor in 2..sqrtLimit) {
( 1 $limit false ) remove
if (numbers[factor]) {
pstack
for (multiple in (factor * factor)..limit step factor) {
numbers[multiple] = false
}
}
}
 
"Press ENTER to end " input</syntaxhighlight>
numbers.forEachIndexed { number, isPrime ->
if (number >= 2) {
if (isPrime) {
primes.add(number)
}
}
}
}
 
=={{header|Kotlin}}==
return primes
<syntaxhighlight lang="kotlin">import kotlin.math.sqrt
 
fun sieve(max: Int): List<Int> {
val xs = (2..max).toMutableList()
val limit = sqrt(max.toDouble()).toInt()
for (x in 2..limit) xs -= x * x..max step x
return xs
}
 
fun main(args: Array<String>) {
println(sieve(100))
}</langsyntaxhighlight>
 
{{out}}
Line 7,023 ⟶ 11,276:
The following code overcomes most of those problems: It only culls odd composites; it culls a bit-packed primitive array (also saving memory); It uses tailcall recursive functions for the loops, which are compiled into simple loops. It also outputs the results as an enumeration, which isn't fast but does not consume any more memory than the culling array. In this way, the program is only limited in sieving range by the maximum size limit of the culling array, although as it grows larger than the CPU cache sizes, it loses greatly in speed; however, that doesn't matter so much if just enumerating the results.
 
<langsyntaxhighlight lang="kotlin">fun primesOdds(rng: Int): Iterable<Int> {
val topi = (rng - 3) shr 1
val lstw = topi shr 5
Line 7,071 ⟶ 11,324:
println()
println(primesOdds(1000000).count())
}</langsyntaxhighlight>
{{output}}
<pre>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
Line 7,080 ⟶ 11,333:
Ah, one might say, for such a trivial range one writes for conciseness and not for speed. Well, I say, one can still save memory and some time using odds-only and a bit-packed array, but write very clear and concise (but slower) code using nothing but higher order functions and function calling. The following code using such techniques can use the same "main" function for the same output but is about two times slower, mostly due to the extra time spent making (nested) function calls, including the function calls necessary for enumeration. Note that the effect of using the "(l .. h).forEach { .. }" is the same as the "for i in l .. h { .. }" as both use an iteration across the range but the second is just syntax sugar to make it look more imperative:
 
<langsyntaxhighlight lang="kotlin">fun primesOdds(rng: Int): Iterable<Int> {
val topi = (rng - 3) / 2 //convert to nearest index
val size = topi / 32 + 1 //word size to include index
Line 7,092 ⟶ 11,345:
val orng = (-1 .. topi).filter { it < 0 || is_p(it) }.map { i2p(it) }
return Iterable { -> orng.iterator() }
}</langsyntaxhighlight>
 
The trouble with the above version is that, at least for Kotlin version 1.0, the ".filter" and ".map" extension functions for Iterable<Int> create Java "ArrayList"'s as their output (which are wrapped to return the Kotlin "List<Int>" interface), thus take a considerable amount of memory worse than the first version (using an ArrayList to store the resulting primes), since as the calculations are chained to ".map", require a second ArrayList of up to the same size while the mapping is being done. The following version uses Sequences , which aren't backed by any permanent structure, but it is another small factor slower due to the nested function calls:
 
<langsyntaxhighlight lang="kotlin">fun primesOdds(rng: Int): Iterable<Int> {
val topi = (rng - 3) / 2 //convert to nearest index
val size = topi / 32 + 1 //word size to include index
Line 7,110 ⟶ 11,363:
val oseq = iseq(topi, -1).filter { it < 0 || is_p(it) }.map { i2p(it) }
return Iterable { -> oseq.iterator() }
}</langsyntaxhighlight>
 
===Unbounded Versions===
Line 7,117 ⟶ 11,370:
 
The following Sieve of Eratosthenes is not purely functional in that it uses a Mutable HashMap to store the state of succeeding composite numbers to be skipped over, but embodies the principles of an incremental implementation of the Sieve of Eratosthenes sieving odds-only and is faster than most incremental sieves due to using mutability. As with the fastest of this kind of sieve, it uses a delayed secondary primes feed as a source of base primes to generate the composite number progressions. The code as follows:
<langsyntaxhighlight lang="kotlin">fun primesHM(): Sequence<Int> = sequence {
yield(2)
fun oddprms(): Sequence<Int> = sequence {
Line 7,149 ⟶ 11,402:
}
yieldAll(oddprms())
}</langsyntaxhighlight>
 
At about 370 clock cycles per culling operation (about 3,800 cycles per prime) on my tablet class Intel CPU, this is not blazing fast but adequate for ranges of a few millions to a hundred million and thus fine for doing things like solving Euler problems. For instance, Euler Problem 10 of summing the primes to two million can be done with the following "one-liner":
<langsyntaxhighlight lang="kotlin">primesHM().takeWhile { it <= 2_000_000 }.map { it.toLong() }.sum()</langsyntaxhighlight>
 
to output the correct answer of the following in about 270 milliseconds for my Intel x5-Z8350 at 1.92 Gigahertz:
Line 7,164 ⟶ 11,417:
{{trans|Haskell}}
 
<langsyntaxhighlight lang="kotlin">data class CIS<T>(val head: T, val tailf: () -> CIS<T>) {
fun toSequence() = generateSequence(this) { it.tailf() } .map { it.head }
}
Line 7,201 ⟶ 11,454:
val stop = System.currentTimeMillis()
println("Took ${stop - strt} milliseconds.")
}</langsyntaxhighlight>
 
The code is about five times slower than the more imperative hash table based version immediately above due to the costs of the extra levels of function calls in the functional style. The Haskell version from which this is derived is much faster due to the extensive optimizations it does to do with function/closure "lifting" as well as a Garbage Collector specifically tuned for functional code.
Line 7,208 ⟶ 11,461:
 
The very fastest implementations of a primes sieve are all based on bit-packed mutable arrays which can be made unbounded by setting them up so that they are a succession of sieved bit-packed arrays that have been culled of composites. The following code is an odds=only implementation that, again, uses a secondary feed of base primes that is only expanded as necessary (in this case memoized by a rudimentary lazy list structure to avoid recalculation for every base primes sweep per page segment):
<langsyntaxhighlight lang="kotlin">internal typealias Prime = Long
internal typealias BasePrime = Int
internal typealias BasePrimeArray = IntArray
Line 7,381 ⟶ 11,634:
}
}
}</langsyntaxhighlight>
 
For this implementation, counting the primes to a million is trivial at about 15 milliseconds on the same CPU as above, or almost too short to count.
Line 7,394 ⟶ 11,647:
 
Kotlin isn't really fast even as compared to other virtual machine languages such as C# and F# on CLI but that is mostly due to limitations of the Java Virtual Machine (JVM) as to speed of generated Just In Time (JIT) compilation, handling of primitive number operations, enforced array bounds checks, etc. It will always be much slower than native code producing compilers and the (experimental) native compiler for Kotlin still isn't up to speed (pun intended), producing code that is many times slower than the code run on the JVM (December 2018).
 
=={{header|Lambdatalk}}==
<syntaxhighlight lang="scheme">
 
• 1) create an array of natural numbers, [0,1,2,3, ... ,n-1]
• 2) the 3rd number is 2, we set to dots all its composites by steps of 2,
• 3) the 4th number is 3, we set to dots all its composites by steps of 3,
• 4) the 6th number is 5, we set to dots all its composites by steps of 5,
• 5) the remaining numbers are primes and we clean all dots.
 
For instance:
 
1: 0 0 0 0 0 0 0 0 0 9 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
2: 0 1 2 3 . 5 . 7 . 9 . 1 . 3 . 5 . 7 . 9 . 1 . 3 . 5 . 7 . 9 .
3: 0 1 2 3 . 5 . 7 . . . 1 . 3 . . . 7 . 9 . . . 3 . 5 . . . 9 .
4: 0 1 2 3 . 5 . 7 . . . 1 . 3 . . . 7 . 9 . . . 3 . . . . . 9 .
| | | | | | | | | |
5: 0 0 0 0 1 1 1 1 2 2
2 3 5 7 1 3 7 9 3 9
 
 
1) recursive version {rsieve n}
 
{def rsieve
 
{def rsieve.mark
{lambda {:n :a :i :j}
{if {< :j :n}
then {rsieve.mark :n
{A.set! :j . :a}
:i
{+ :i :j}}
else :a}}}
 
{def rsieve.loop
{lambda {:n :a :i}
{if {< {* :i :i} :n}
then {rsieve.loop :n
{if {W.equal? {A.get :i :a} .}
then :a
else {rsieve.mark :n :a :i {* :i :i}}}
{+ :i 1}}
else :a}}}
 
{lambda {:n}
{S.replace \s by space in
{S.replace (\[|\]|\.|,) by space in
{A.disp
{A.slice 2 -1
{rsieve.loop :n
{A.new {S.serie 0 :n}} 2}}}}}}}
-> rsieve
 
{rsieve 1000}
-> 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 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997
 
Note: this version doesn't avoid stackoverflow.
 
2) iterative version {isieve n}
 
{def isieve
 
{def isieve.mark
{lambda {:n :a :i}
{S.map {{lambda {:a :j} {A.set! :j . :a}
} :a}
{S.serie {* :i :i} :n :i} }}}
 
{lambda {:n}
{S.replace \s by space in
{S.replace (\[|\]|\.|,) by space in
{A.disp
{A.slice 2 -1
{S.last
{S.map {{lambda {:n :a :i} {if {W.equal? {A.get :i :a} .}
then
else {isieve.mark :n :a :i}}
} :n {A.new {S.serie 0 :n}}}
{S.serie 2 {sqrt :n} 1}}}}}}}}}
-> isieve
 
{isieve 1000}
-> 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 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997
 
Notes:
- this version avoids stackoverflow.
- From 1 to 1000000 there are 78500 primes (computed in ~15000ms) and the last is 999983.
 
</syntaxhighlight>
 
=={{header|langur}}==
{{trans|D}}
<syntaxhighlight lang="langur">val .sieve = fn(.limit) {
if .limit < 2: return []
 
var .composite = .limit * [false]
.composite[1] = true
 
for .n in 2 .. trunc(.limit ^/ 2) + 1 {
if not .composite[.n] {
for .k = .n^2 ; .k < .limit ; .k += .n {
.composite[.k] = true
}
}
}
 
filter fn(.n) { not .composite[.n] }, series .limit-1
}
 
writeln .sieve(100)
</syntaxhighlight>
 
{{out}}
<pre>[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]</pre>
 
=={{header|LFE}}==
<syntaxhighlight lang="lisp">
(defmodule eratosthenes
(export (sieve 1)))
 
(defun sieve (limit)
(sieve limit (lists:seq 2 limit)))
 
(defun sieve
((limit (= l (cons p _))) (when (> (* p p) limit))
l)
((limit (cons p ns))
(cons p (sieve limit (remove-multiples p (* p p) ns)))))
 
(defun remove-multiples (p q l)
(lists:reverse (remove-multiples p q l '())))
 
(defun remove-multiples
((_ _ '() s) s)
((p q (cons q ns) s)
(remove-multiples p q ns s))
((p q (= r (cons a _)) s) (when (> a q))
(remove-multiples p (+ q p) r s))
((p q (cons n ns) s)
(remove-multiples p q ns (cons n s))))
</syntaxhighlight>
{{Out}}
<pre>
lfe> (slurp "sieve.lfe")
#(ok eratosthenes)
lfe> (sieve 100)
(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)
</pre>
 
=={{header|Liberty BASIC}}==
<langsyntaxhighlight lang="lb"> 'Notice that arrays are globally visible to functions.
'The sieve() function uses the flags() array.
'This is a Sieve benchmark adapted from BYTE 1985
Line 7,420 ⟶ 11,822:
end if
next i
end function</langsyntaxhighlight>
 
=={{header|Limbo}}==
<langsyntaxhighlight Golang="go">implement Sieve;
 
include "sys.m";
Line 7,463 ⟶ 11,865:
}
}
</syntaxhighlight>
</lang>
 
=={{header|Lingo}}==
<langsyntaxhighlight Lingolang="lingo">-- parent script "sieve"
property _sieve
 
Line 7,506 ⟶ 11,908:
end repeat
end repeat
end</langsyntaxhighlight>
 
<langsyntaxhighlight Lingolang="lingo">sieve = script("sieve").new()
put sieve.getPrimes(100)</langsyntaxhighlight>
 
{{out}}
Line 7,517 ⟶ 11,919:
 
=={{header|LiveCode}}==
<langsyntaxhighlight LiveCodelang="livecode">function sieveE int
set itemdel to comma
local sieve
Line 7,538 ⟶ 11,940:
sort items of sieve ascending numeric
return sieve
end sieveE</langsyntaxhighlight>
Example<langsyntaxhighlight LiveCodelang="livecode">put sieveE(121)
-- 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,101,103,107,109,113</langsyntaxhighlight>
 
 
 
<syntaxhighlight lang="livecode"># Sieve of Eratosthenes
# calculates prime numbers up to a given number
on mouseUp
put field "maximum" into limit
put the ticks into startTicks # start a timer
repeat with i = 2 to limit step 1 # load array with zeros
put 0 into prime_array[i]
end repeat
repeat with i = 2 to trunc(sqrt(limit)) # truncate square root
if prime_array[i] = 0 then
repeat with k = (i * i) to limit step i
delete variable prime_array[k] # remove non-primes
end repeat
end if
end repeat
put the ticks - startTicks into elapsedTicks # stop timer
put elapsedTicks / 60 into field "elapsed" # calculate time
put the keys of prime_array into prime_numbers # array to variable
put the number of lines of keys of prime_array into field "count"
sort lines of prime_numbers ascending numeric
put prime_numbers into field "primeList" # show prime numbers
end mouseUp
 
</syntaxhighlight>
 
[http://www.melellington.com/sieve/livecode-sieve-output.png LiveCode output example]
 
===Comments===
LiveCode uses a mouse graphical drag and drop.
No text code was used to create a button and fields;
The user enters a number into the 'maximum' field
and then clicks a button to run the code.
It runs identically whether in the LiveCode IDE or
when compiled to a executable on Mac, Windows, and Linux.
 
The example was run on an Intel i5 CPU @ 3.29 GHz;
all primes found up to 1,000,000 in 3 seconds.
 
=={{header|Logo}}==
Line 7,560 ⟶ 12,005:
due to the use of mod (modulo = division) in the filter function.
A coinduction based solution just for fun:
<langsyntaxhighlight lang="logtalk">
:- object(sieve).
 
Line 7,599 ⟶ 12,044:
 
:- end_object.
</syntaxhighlight>
</lang>
Example query:
<langsyntaxhighlight lang="logtalk">
?- sieve::primes(20, P).
P = [2, 3|_S1], % where
_S1 = [5, 7, 11, 13, 17, 19, 2, 3|_S1] .
</syntaxhighlight>
</lang>
 
=={{header|LOLCODE}}==
<syntaxhighlight lang="lolcode">HAI 1.2
CAN HAS STDIO?
 
HOW IZ I Eratosumthin YR Max
I HAS A Siv ITZ A BUKKIT
Siv HAS A SRS 1 ITZ 0
I HAS A Index ITZ 2
IM IN YR Inishul UPPIN YR Dummy WILE DIFFRINT Index AN SUM OF Max AN 1
Siv HAS A SRS Index ITZ 1
Index R SUM OF Index AN 1
IM OUTTA YR Inishul
 
I HAS A Prime ITZ 2
IM IN YR MainLoop UPPIN YR Dummy WILE BOTH SAEM Max AN BIGGR OF Max AN PRODUKT OF Prime AN Prime
BOTH SAEM Siv'Z SRS Prime AN 1
O RLY?
YA RLY
Index R SUM OF Prime AN Prime
IM IN YR MarkMultipulz UPPIN YR Dummy WILE BOTH SAEM Max AN BIGGR OF Max AN Index
Siv'Z SRS Index R 0
Index R SUM OF Index AN Prime
IM OUTTA YR MarkMultipulz
OIC
Prime R SUM OF Prime AN 1
IM OUTTA YR MainLoop
 
Index R 1
I HAS A First ITZ WIN
IM IN YR PrintPrimes UPPIN YR Dummy WILE BOTH SAEM Max AN BIGGR OF Max AN Index
BOTH SAEM Siv'Z SRS Index AN 1
O RLY?
YA RLY
First
O RLY?
YA RLY
First R FAIL
NO WAI
VISIBLE ", "!
OIC
VISIBLE Index!
OIC
Index R SUM OF Index AN 1
IM OUTTA YR PrintPrimes
VISIBLE ""
IF U SAY SO
 
I IZ Eratosumthin YR 100 MKAY
 
KTHXBYE</syntaxhighlight>
 
{{Out}}
<pre>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</pre>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">function erato(n)
if n < 2 then return {} end
local t = {0} -- clears '1'
Line 7,617 ⟶ 12,116:
for i = 2, n do if t[i] ~= 0 then table.insert(primes, i) end end
return primes
end</langsyntaxhighlight>
 
The following changes the code to '''odds-only''' using the same large array-based algorithm:
<langsyntaxhighlight lang="lua">function erato2(n)
if n < 2 then return {} end
if n < 3 then return {2} end
Line 7,633 ⟶ 12,132:
for i = 0, lmt do if t[i] ~= 0 then table.insert(primes, i + i + 3) end end
return primes
end</langsyntaxhighlight>
 
The following code implements '''an odds-only "infinite" generator style using a table as a hash table''', including postponing adding base primes to the table:
 
<langsyntaxhighlight lang="lua">function newEratoInf()
local _cand = 0; local _lstbp = 3; local _lstsqr = 9
local _composites = {}; local _bps = nil
Line 7,670 ⟶ 12,169:
while gen.next() <= 10000000 do count = count + 1 end -- sieves to 10 million
print(count)
</syntaxhighlight>
</lang>
 
which outputs "664579" in about three seconds. As this code uses much less memory for a given range than the previous ones and retains efficiency better with range, it is likely more appropriate for larger sieve ranges.
 
=={{header|Lucid}}==
{{incorrect|Lucid|Not a true Sieve of Eratosthenes but rather a Trial Division Sieve}}
Line 7,695 ⟶ 12,195:
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module EratosthenesSieve (x) {
\\ Κόσκινο του Ερατοσθένη
If x>200000 Then ExitProfiler
DimIf i(x+1)>2000000 Then Exit
Dim i(x+1): k=2: k2=sqrt(x)
While k<=k2{if i(k) else for m=k*k to x step k{i(m)=1}
k2=x div 2
While k<=k2 {++}
Print str$(timecount/1000,"####0.##")+" s"
m=k+k
Input "Press enter skip print or a non zero to get results:", a%
While m<=x {
if a% then For i=2to x{If i(mi)=10 Then Print i,
m+=k
}
k++
}
ForPrint:Print i=2 to x {"Done"
If i(i)=0 Then Print i,
}
Print
}
EratosthenesSieve 1000
</syntaxhighlight>
</lang>
 
 
=={{header|M4}}==
<langsyntaxhighlight M4lang="m4">define(`lim',100)dnl
define(`for',
`ifelse($#,0,
Line 7,731 ⟶ 12,224:
`j for(`k',eval(j*j),lim,j,
`define(a[k],1)')')')
</syntaxhighlight>
</lang>
 
Output:
Line 7,737 ⟶ 12,230:
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
</pre>
 
=={{header|MAD}}==
 
<syntaxhighlight lang="mad"> NORMAL MODE IS INTEGER
R TO GENERATE MORE PRIMES, CHANGE BOTH THESE NUMBERS
BOOLEAN PRIME
DIMENSION PRIME(10000)
MAXVAL = 10000
PRINT FORMAT BEGIN,MAXVAL
R ASSUME ALL ARE PRIMES AT BEGINNING
THROUGH SET, FOR I=2, 1, I.G.MAXVAL
SET PRIME(I) = 1B
 
R REMOVE ALL PROVEN COMPOSITES
SQMAX = SQRT.(MAXVAL)
THROUGH NEXT, FOR P=2, 1, P.G.SQMAX
WHENEVER PRIME(P)
THROUGH MARK, FOR I=P*P, P, I.G.MAXVAL
MARK PRIME(I) = 0B
NEXT END OF CONDITIONAL
 
R PRINT PRIMES
THROUGH SHOW, FOR P=2, 1, P.G.MAXVAL
SHOW WHENEVER PRIME(P), PRINT FORMAT NUMFMT, P
VECTOR VALUES BEGIN = $13HPRIMES UP TO ,I9*$
VECTOR VALUES NUMFMT = $I9*$
END OF PROGRAM</syntaxhighlight>
 
{{out}}
 
<pre>PRIMES UP TO 10000
2
3
5
7
11
13
17
...
9979
9983
9985
9989
9991
9995
9997</pre>
 
=={{header|Maple}}==
<langsyntaxhighlight Maplelang="maple">Eratosthenes := Procproc(n::posint),
local numbers_to_check, i, k;
numbers_to_check := [seq(2 .. n)];
for i from 2 to floor(sqrt(n)) do
for k from i by i while k <= n do
numbers_to_check :=remove(x -> (irem(x, i) = 0 and x <>i ), numbers_to_check)
end do; if evalb(k <> i) then
return numbers_to_check[k - 1] := 0;
end proc:if;
end do;
end do;
numbers_to_check := remove(x -> evalb(x = 0), numbers_to_check);
return numbers_to_check;
end proc:
</syntaxhighlight>
{{out}}
<pre>
Line 7,752 ⟶ 12,300:
[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]
</pre>
</lang>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">Eratosthenes[n_] := Module[{numbers = Range[n]},
Do[If[numbers[[i]] != 0, Do[numbers[[i j]] = 0, {j, 2, n/i}]], {i,
2, Sqrt[n]}];
Select[numbers, # > 1 &]]
 
Eratosthenes[100]</langsyntaxhighlight>
===Slightly Optimized Version===
The below has been improved to not require so many operations per composite number cull for about two thirds the execution time:
<langsyntaxhighlight Mathematicalang="mathematica">Eratosthenes[n_] := Module[{numbers = Range[n]},
Do[If[numbers[[i]] != 0, Do[numbers[[j]] = 0, {j,i i,n,i}]],{i,2,Sqrt[n]}];
Select[numbers, # > 1 &]]
 
Eratosthenes[100]</langsyntaxhighlight>
===Sieving Odds-Only Version===
The below has been further improved to only sieve odd numbers for a further reduction in execution time by a factor of over two:
<langsyntaxhighlight Mathematicalang="mathematica">Eratosthenes2[n_] := Module[{numbers = Range[3, n, 2], limit = (n - 1)/2},
Do[c = numbers[[i]]; If[c != 0,
Do[numbers[[j]] = 0, {j,(c c - 1)/2,limit,c}]], {i,1,(Sqrt[n] - 1)/2}];
Prepend[Select[numbers, # > 1 &], 2]]
 
Eratosthenes2[100]</langsyntaxhighlight>
 
=={{header|MATLAB}}==
=={{header|MATLAB}} / {{header|Octave}}==
===Somewhat optimized true Sieve of Eratosthenes===
<langsyntaxhighlight MATLABlang="matlab">function P = erato(x) % Sieve of Eratosthenes: returns all primes between 2 and x
P = [0 2:x]; % Create vector with all ints between 2 and x where
Line 7,790 ⟶ 12,338:
 
P = P(P ~= 0); % Remove all zeroes from P, leaving only the primes.
end</langsyntaxhighlight>The optimization lies in fewer steps in the for loop, use of MATLAB's built-in array operations and no modulo calculation.
 
'''Limitation:''' your machine has to be able to allocate enough memory for an array of length x.
Line 7,797 ⟶ 12,345:
A more efficient Sieve avoids creating a large double precision vector P, instead using a logical array (which consumes 1/8 the memory of a double array of the same size) and only converting to double those values corresponding to primes.
 
<langsyntaxhighlight MATLABlang="matlab">function P = sieveOfEratosthenes(x)
ISP = [false true(1, x-1)]; % 1 is not prime, but we start off assuming all numbers between 2 and x are
for n = 2:sqrt(x)
Line 7,807 ⟶ 12,355:
P = find(ISP); % Convert the ISPRIME output to the values of the primes by finding the locations
% of the TRUE values in S.
end</langsyntaxhighlight>
 
You can compare the output of this function against the PRIMES function included in MATLAB, which performs a somewhat more memory-efficient Sieve (by not storing even numbers, at the expense of a more complicated indexing expression inside the IF statement.)
 
=={{header|Maxima}}==
<langsyntaxhighlight lang="maxima">sieve(n):=block(
[a:makelist(true,n),i:1,j],
a[1]:false,
Line 7,821 ⟶ 12,369:
for j from i*i step i while j<=n do a[j]:false
)
)$</langsyntaxhighlight>
 
=={{header|MAXScript}}==
fn eratosthenes n =
Line 7,841 ⟶ 12,390:
eratosthenes 100
 
=={{header|Mercury}}==
<syntaxhighlight lang="mercury">:- module sieve.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module bool, array, int.
 
main(!IO) :-
sieve(50, Sieve),
dump_primes(2, size(Sieve), Sieve, !IO).
 
:- pred dump_primes(int, int, array(bool), io, io).
:- mode dump_primes(in, in, array_di, di, uo) is det.
dump_primes(N, Limit, !.A, !IO) :-
( if N < Limit then
unsafe_lookup(!.A, N, Prime),
(
Prime = yes,
io.write_line(N, !IO)
;
Prime = no
),
dump_primes(N + 1, Limit, !.A, !IO)
else
true
).
 
:- pred sieve(int, array(bool)).
:- mode sieve(in, array_uo) is det.
sieve(N, !:A) :-
array.init(N, yes, !:A),
sieve(2, N, !A).
 
:- pred sieve(int, int, array(bool), array(bool)).
:- mode sieve(in, in, array_di, array_uo) is det.
sieve(N, Limit, !A) :-
( if N < Limit then
unsafe_lookup(!.A, N, Prime),
(
Prime = yes,
sift(N + N, N, Limit, !A),
sieve(N + 1, Limit, !A)
;
Prime = no,
sieve(N + 1, Limit, !A)
)
else
true
).
 
:- pred sift(int, int, int, array(bool), array(bool)).
:- mode sift(in, in, in, array_di, array_uo) is det.
sift(I, N, Limit, !A) :-
( if I < Limit then
unsafe_set(I, no, !A),
sift(I + N, N, Limit, !A)
else
true
).</syntaxhighlight>
 
=={{header|Microsoft Small Basic}}==
{{trans|GW-BASIC}}
<langsyntaxhighlight lang="microsoftsmallbasic">
TextWindow.Write("Enter number to search to: ")
limit = TextWindow.ReadNumber()
Line 7,867 ⟶ 12,477:
TextWindow.WriteLine("")
EndIf
</syntaxhighlight>
</lang>
 
=={{header|Modula-2}}==
<syntaxhighlight lang="modula2">MODULE Erato;
FROM InOut IMPORT WriteCard, WriteLn;
FROM MathLib IMPORT sqrt;
 
CONST Max = 100;
 
VAR prime: ARRAY [2..Max] OF BOOLEAN;
i: CARDINAL;
 
PROCEDURE Sieve;
VAR i, j, sqmax: CARDINAL;
BEGIN
sqmax := TRUNC(sqrt(FLOAT(Max)));
 
FOR i := 2 TO Max DO prime[i] := TRUE; END;
FOR i := 2 TO sqmax DO
IF prime[i] THEN
j := i * 2;
(* alas, the BY clause in a FOR loop must be a constant *)
WHILE j <= Max DO
prime[j] := FALSE;
j := j + i;
END;
END;
END;
END Sieve;
 
BEGIN
Sieve;
FOR i := 2 TO Max DO
IF prime[i] THEN
WriteCard(i,5);
WriteLn;
END;
END;
END Erato.</syntaxhighlight>
{{out}}
<pre style='height:50ex;'> 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</pre>
 
=={{header|Modula-3}}==
===Regular version===
This version runs slow because of the way I/O is implemented in the CM3 compiler. Setting <code>ListPrimes = FALSE</code> achieves speed comparable to C on sufficiently high values of <code>LastNum</code> (e.g., 10^6).
<langsyntaxhighlight lang="modula3">MODULE Eratosthenes EXPORTS Main;
 
IMPORT IO;
Line 7,930 ⟶ 12,604:
IO.PutChar('\n');
 
END Eratosthenes.</langsyntaxhighlight>
 
===Advanced version===
This version uses more "advanced" types.
<langsyntaxhighlight lang="modula3">(* From the CM3 examples folder (comments removed). *)
 
MODULE Sieve EXPORTS Main;
Line 7,959 ⟶ 12,633:
END;
IO.Put("\n");
END Sieve.</langsyntaxhighlight>
 
=={{header|Mojo}}==
 
Tested with Mojo version 0.7:
 
<syntaxhighlight lang="mojo">from memory import memset_zero
from memory.unsafe import (DTypePointer)
from time import (now)
 
alias cLIMIT: Int = 1_000_000_000
 
struct SoEBasic(Sized):
var len: Int
var cmpsts: DTypePointer[DType.bool] # because DynamicVector has deep copy bug in mojo version 0.7
var sz: Int
var ndx: Int
fn __init__(inout self, limit: Int):
self.len = limit - 1
self.sz = limit - 1
self.ndx = 0
self.cmpsts = DTypePointer[DType.bool].alloc(limit - 1)
memset_zero(self.cmpsts, limit - 1)
for i in range(limit - 1):
let s = i * (i + 4) + 2
if s >= limit - 1: break
if self.cmpsts[i]: continue
let bp = i + 2
for c in range(s, limit - 1, bp):
self.cmpsts[c] = True
for i in range(limit - 1):
if self.cmpsts[i]: self.sz -= 1
fn __del__(owned self):
self.cmpsts.free()
fn __copyinit__(inout self, existing: Self):
self.len = existing.len
self.cmpsts = DTypePointer[DType.bool].alloc(self.len)
for i in range(self.len):
self.cmpsts[i] = existing.cmpsts[i]
self.sz = existing.sz
self.ndx = existing.ndx
fn __moveinit__(inout self, owned existing: Self):
self.len = existing.len
self.cmpsts = existing.cmpsts
self.sz = existing.sz
self.ndx = existing.ndx
fn __len__(self: Self) -> Int: return self.sz
fn __iter__(self: Self) -> Self: return self
fn __next__(inout self: Self) -> Int:
if self.ndx >= self.len: return 0
while (self.ndx < self.len) and (self.cmpsts[self.ndx]):
self.ndx += 1
let rslt = self.ndx + 2; self.sz -= 1; self.ndx += 1
return rslt
 
fn main():
print("The primes to 100 are:")
for prm in SoEBasic(100): print_no_newline(prm, " ")
print()
let strt0 = now()
let answr0 = len(SoEBasic(1_000_000))
let elpsd0 = (now() - strt0) / 1000000
print("Found", answr0, "primes up to 1,000,000 in", elpsd0, "milliseconds.")
let strt1 = now()
let answr1 = len(SoEBasic(cLIMIT))
let elpsd1 = (now() - strt1) / 1000000
print("Found", answr1, "primes up to", cLIMIT, "in", elpsd1, "milliseconds.")</syntaxhighlight>
 
{{out}}
 
<pre>The primes to 100 are:
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
Found 78498 primes up to 1,000,000 in 1.2642770000000001 milliseconds.
Found 50847534 primes up to 1000000000 in 6034.328751 milliseconds.</pre>
as run on an AMD 7840HS CPU at 5.1 GHz.
 
Note that due to the huge memory array used, when large ranges are selected, the speed is disproportional in speed slow down by about four times.
 
This solution uses an interator struct which seems to be the Mojo-preferred way to do this, and normally a DynamicVector would have been used the the culling array except that there is a bug in this version of DynamicVector where the array is not properly deep copied when copied to a new location, so the raw pointer type is used.
 
===Odds-Only with Optimizations===
 
This version does three significant improvements to the above code as follows:
1) It is trivial to skip the processing to store representations for and cull the even comosite numbers other than the prime number two, saving half the storage space and reducing the culling time to about 40 percent.
2) There is a repeating pattern of culling composite representations over a bit-packed byte array (which reduces the storage requirement by another eight times) that repeats every eight culling operations, which can be encapsulated by a extreme loop unrolling technique with compiler generated constants as done here.
3) Further, there is a further extreme optimization technique of dense culling for small base prime values whose culling span is less than one register in size where the loaded register is repeatedly culled for different base prime strides before being written out (with such optimization done by the compiler), again using compiler generated modification constants. This technique is usually further optimizated by modern compilers to use efficient autovectorization and the use of SIMD registers available to the architecture to reduce these culling operations to an avererage of a tiny fraction of a CPU clock cycle per cull.
 
Mojo version 0.7 was tested:
 
<syntaxhighlight lang="mojo">from memory import (memset_zero, memcpy)
from memory.unsafe import (DTypePointer)
from math.bit import ctpop
from time import (now)
 
alias cLIMIT: Int = 1_000_000_000
 
alias cBufferSize: Int = 262144 # bytes
alias cBufferBits: Int = cBufferSize * 8
 
alias UnrollFunc = fn(DTypePointer[DType.uint8], Int, Int, Int) -> None
 
@always_inline
fn extreme[OFST: Int, BP: Int](pcmps: DTypePointer[DType.uint8], bufsz: Int, s: Int, bp: Int):
var cp = pcmps + (s >> 3)
let r1: Int = ((s + bp) >> 3) - (s >> 3)
let r2: Int = ((s + 2 * bp) >> 3) - (s >> 3)
let r3: Int = ((s + 3 * bp) >> 3) - (s >> 3)
let r4: Int = ((s + 4 * bp) >> 3) - (s >> 3)
let r5: Int = ((s + 5 * bp) >> 3) - (s >> 3)
let r6: Int = ((s + 6 * bp) >> 3) - (s >> 3)
let r7: Int = ((s + 7 * bp) >> 3) - (s >> 3)
let plmt: DTypePointer[DType.uint8] = pcmps + bufsz - r7
while cp < plmt:
cp.store(cp.load() | (1 << OFST))
(cp + r1).store((cp + r1).load() | (1 << ((OFST + BP) & 7)))
(cp + r2).store((cp + r2).load() | (1 << ((OFST + 2 * BP) & 7)))
(cp + r3).store((cp + r3).load() | (1 << ((OFST + 3 * BP) & 7)))
(cp + r4).store((cp + r4).load() | (1 << ((OFST + 4 * BP) & 7)))
(cp + r5).store((cp + r5).load() | (1 << ((OFST + 5 * BP) & 7)))
(cp + r6).store((cp + r6).load() | (1 << ((OFST + 6 * BP) & 7)))
(cp + r7).store((cp + r7).load() | (1 << ((OFST + 7 * BP) & 7)))
cp += bp
let eplmt: DTypePointer[DType.uint8] = plmt + r7
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << OFST))
cp += r1
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << ((OFST + BP) & 7)))
cp += r2 - r1
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << ((OFST + 2 * BP) & 7)))
cp += r3 - r2
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << ((OFST + 3 * BP) & 7)))
cp += r4 - r3
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << ((OFST + 4 * BP) & 7)))
cp += r5 - r4
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << ((OFST + 5 * BP) & 7)))
cp += r6 - r5
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << ((OFST + 6 * BP) & 7)))
cp += r7 - r6
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << ((OFST + 7 * BP) & 7)))
 
fn mkExtrm[CNT: Int](pntr: Pointer[UnrollFunc]):
@parameter
if CNT >= 32:
return
alias OFST = CNT >> 2
alias BP = ((CNT & 3) << 1) + 1
pntr.offset(CNT).store(extreme[OFST, BP])
mkExtrm[CNT + 1](pntr)
 
@always_inline
fn mkExtremeFuncs() -> Pointer[UnrollFunc]:
let jmptbl: Pointer[UnrollFunc] = Pointer[UnrollFunc].alloc(32)
mkExtrm[0](jmptbl)
return jmptbl
let extremeFuncs = mkExtremeFuncs()
 
alias DenseFunc = fn(DTypePointer[DType.uint64], Int, Int) -> DTypePointer[DType.uint64]
 
fn mkDenseCull[N: Int, BP: Int](cp: DTypePointer[DType.uint64]):
@parameter
if N >= 64:
return
alias MUL = N * BP
var cop = cp.offset(MUL >> 6)
cop.store(cop.load() | (1 << (MUL & 63)))
mkDenseCull[N + 1, BP](cp)
 
@always_inline
fn denseCullFunc[BP: Int](pcmps: DTypePointer[DType.uint64], bufsz: Int, s: Int) -> DTypePointer[DType.uint64]:
var cp: DTypePointer[DType.uint64] = pcmps + (s >> 6)
let plmt = pcmps + (bufsz >> 3) - BP
while cp < plmt:
mkDenseCull[0, BP](cp)
cp += BP
return cp
 
fn mkDenseFunc[CNT: Int](pntr: Pointer[DenseFunc]):
@parameter
if CNT >= 64:
return
alias BP = (CNT << 1) + 3
pntr.offset(CNT).store(denseCullFunc[BP])
mkDenseFunc[CNT + 1](pntr)
 
@always_inline
fn mkDenseFuncs() -> Pointer[DenseFunc]:
let jmptbl : Pointer[DenseFunc] = Pointer[DenseFunc].alloc(64)
mkDenseFunc[0](jmptbl)
return jmptbl
 
let denseFuncs : Pointer[DenseFunc] = mkDenseFuncs()
 
@always_inline
fn cullPass(cmpsts: DTypePointer[DType.uint8], bytesz: Int, s: Int, bp: Int):
if bp <= 129: # dense culling
var sm = s
while (sm >> 3) < bytesz and (sm & 63) != 0:
cmpsts[sm >> 3] |= (1 << (sm & 7))
sm += bp
let bcp = denseFuncs[(bp - 3) >> 1](cmpsts.bitcast[DType.uint64](), bytesz, sm)
var ns = 0
var ncp = bcp
let cmpstslmtp = (cmpsts + bytesz).bitcast[DType.uint64]()
while ncp < cmpstslmtp:
ncp[0] |= (1 << (ns & 63))
ns += bp
ncp = bcp + (ns >> 6)
else: # extreme loop unrolling culling
extremeFuncs[((s & 7) << 2) + ((bp & 7) >> 1)](cmpsts, bytesz, s, bp)
# for c in range(s, self.len, bp): # slow bit twiddling way
# self.cmpsts[c >> 3] |= (1 << (c & 7))
 
fn countPagePrimes(ptr: DTypePointer[DType.uint8], bitsz: Int) -> Int:
let wordsz: Int = (bitsz + 63) // 64 # round up to nearest 64 bit boundary
var rslt: Int = wordsz * 64
let bigcmps = ptr.bitcast[DType.uint64]()
for i in range(wordsz - 1):
rslt -= ctpop(bigcmps[i]).to_int()
rslt -= ctpop(bigcmps[wordsz - 1] | (-2 << ((bitsz - 1) & 63))).to_int()
return rslt
 
struct SoEOdds(Sized):
var len: Int
var cmpsts: DTypePointer[DType.uint8] # because DynamicVector has deep copy bug in Mojo version 0.7
var sz: Int
var ndx: Int
fn __init__(inout self, limit: Int):
self.len = 0 if limit < 2 else (limit - 3) // 2 + 1
self.sz = 0 if limit < 2 else self.len + 1 # for the unprocessed only even prime of two
self.ndx = -1
let bytesz = 0 if limit < 2 else ((self.len + 63) & -64) >> 3 # round up to nearest 64 bit boundary
self.cmpsts = DTypePointer[DType.uint8].alloc(bytesz)
memset_zero(self.cmpsts, bytesz)
for i in range(self.len):
let s = (i + i) * (i + 3) + 3
if s >= self.len: break
if (self.cmpsts[i >> 3] >> (i & 7)) & 1 != 0: continue
let bp = i + i + 3
cullPass(self.cmpsts, bytesz, s, bp)
self.sz = countPagePrimes(self.cmpsts, self.len) + 1 # add one for only even prime of two
fn __del__(owned self):
self.cmpsts.free()
fn __copyinit__(inout self, existing: Self):
self.len = existing.len
let bytesz = (self.len + 7) // 8
self.cmpsts = DTypePointer[DType.uint8].alloc(bytesz)
memcpy(self.cmpsts, existing.cmpsts, bytesz)
self.sz = existing.sz
self.ndx = existing.ndx
fn __moveinit__(inout self, owned existing: Self):
self.len = existing.len
self.cmpsts = existing.cmpsts
self.sz = existing.sz
self.ndx = existing.ndx
fn __len__(self: Self) -> Int: return self.sz
fn __iter__(self: Self) -> Self: return self
@always_inline
fn __next__(inout self: Self) -> Int:
if self.ndx < 0:
self.ndx = 0; self.sz -= 1; return 2
while (self.ndx < self.len) and ((self.cmpsts[self.ndx >> 3] >> (self.ndx & 7)) & 1 != 0):
self.ndx += 1
let rslt = (self.ndx << 1) + 3; self.sz -= 1; self.ndx += 1; return rslt
 
fn main():
print("The primes to 100 are:")
for prm in SoEOdds(100): print_no_newline(prm, " ")
print()
let strt0 = now()
let answr0 = len(SoEOdds(1_000_000))
let elpsd0 = (now() - strt0) / 1000000
print("Found", answr0, "primes up to 1,000,000 in", elpsd0, "milliseconds.")
let strt1 = now()
let answr1 = len(SoEOdds(cLIMIT))
let elpsd1 = (now() - strt1) / 1000000
print("Found", answr1, "primes up to", cLIMIT, "in", elpsd1, "milliseconds.")</syntaxhighlight>
 
{{out}}
 
<pre>The primes to 100 are:
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
Found 78498 primes up to 1,000,000 in 0.085067000000000004 milliseconds.
Found 50847534 primes up to 1000000000 in 1204.866606 milliseconds.</pre>
 
This was run on the same computer as the above example; notice that while this is much faster than that version, it is still very slow as the sieving range gets large such that the relative processing time for a range that is 1000 times as large is about ten times slower than as might be expected by simple scaling. This is due to the "one huge sieving buffer" algorithm that gets very large with increasing range (and in fact will eventually limit the sieving range that can be used) to exceed the size of CPU cache buffers and thus greatly slow average memory access times.
 
===Page-Segmented Odds-Only with Optimizations===
 
While the above version performs reasonably well for small sieving ranges that fit within the CPU caches of a few tens of millions, as one can see it gets much slower with larger ranges and as well its huge RAM memory consumption limits the maximum range over which it can be used. This version solves these problems be breaking the huge sieving array into "pages" that each fit within the CPU cache size and processing each "page" sequentially until the target range is reached. This technique also greatly reduces memory requirements to only that required to store the base prime value representations up to the square root of the range limit (about O(n/log n) storage plus a fixed size page buffer. In this case, the storage for the base primes has been reduced by a constant factor by storing them as single byte deltas from the previous value, which works for ranges up to the 64-bit number range where the biggest gap is two times 192 and since we store only for odd base primes, the gap values are all half values to fit in a single byte.
 
Currently, Mojo has problems with some functions in the standard libraries such as the integer square root function is not accurate nor does it work for the required integer types so a custom integer square root function is supplied. As well, current Mojo does not support recursion for hardly any useful cases (other than compile time global function recursion), so the `SoeOdds` structure from the previous answer had to be kept to generate the base prime representation table (or this would have had to be generated from scratch within the new `SoEOddsPaged` structure). Finally, it didn't seem to be worth using the `Sized` trait for the new structure as this would seem to sometimes require processing the pages twice, one to obtain the size and once if iteration across the prime values is required.
 
Tested with Mojo version 0.7:
 
<syntaxhighlight lang="mojo">from memory import (memset_zero, memcpy)
from memory.unsafe import (DTypePointer)
from math.bit import ctpop
from time import (now)
 
alias cLIMIT: Int = 1_000_000_000
 
alias cBufferSize: Int = 262144 # bytes
alias cBufferBits: Int = cBufferSize * 8
 
fn intsqrt(n: UInt64) -> UInt64:
if n < 4:
if n < 1: return 0 else: return 1
var x: UInt64 = n; var qn: UInt64 = 0; var r: UInt64 = 0
while qn < 64 and (1 << qn) <= n:
qn += 2
var q: UInt64 = 1 << qn
while q > 1:
if qn >= 64:
q = 1 << (qn - 2); qn = 0
else:
q >>= 2
let t: UInt64 = r + q
r >>= 1
if x >= t:
x -= t; r += q
return r
 
alias UnrollFunc = fn(DTypePointer[DType.uint8], Int, Int, Int) -> None
 
@always_inline
fn extreme[OFST: Int, BP: Int](pcmps: DTypePointer[DType.uint8], bufsz: Int, s: Int, bp: Int):
var cp = pcmps + (s >> 3)
let r1: Int = ((s + bp) >> 3) - (s >> 3)
let r2: Int = ((s + 2 * bp) >> 3) - (s >> 3)
let r3: Int = ((s + 3 * bp) >> 3) - (s >> 3)
let r4: Int = ((s + 4 * bp) >> 3) - (s >> 3)
let r5: Int = ((s + 5 * bp) >> 3) - (s >> 3)
let r6: Int = ((s + 6 * bp) >> 3) - (s >> 3)
let r7: Int = ((s + 7 * bp) >> 3) - (s >> 3)
let plmt: DTypePointer[DType.uint8] = pcmps + bufsz - r7
while cp < plmt:
cp.store(cp.load() | (1 << OFST))
(cp + r1).store((cp + r1).load() | (1 << ((OFST + BP) & 7)))
(cp + r2).store((cp + r2).load() | (1 << ((OFST + 2 * BP) & 7)))
(cp + r3).store((cp + r3).load() | (1 << ((OFST + 3 * BP) & 7)))
(cp + r4).store((cp + r4).load() | (1 << ((OFST + 4 * BP) & 7)))
(cp + r5).store((cp + r5).load() | (1 << ((OFST + 5 * BP) & 7)))
(cp + r6).store((cp + r6).load() | (1 << ((OFST + 6 * BP) & 7)))
(cp + r7).store((cp + r7).load() | (1 << ((OFST + 7 * BP) & 7)))
cp += bp
let eplmt: DTypePointer[DType.uint8] = plmt + r7
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << OFST))
cp += r1
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << ((OFST + BP) & 7)))
cp += r2 - r1
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << ((OFST + 2 * BP) & 7)))
cp += r3 - r2
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << ((OFST + 3 * BP) & 7)))
cp += r4 - r3
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << ((OFST + 4 * BP) & 7)))
cp += r5 - r4
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << ((OFST + 5 * BP) & 7)))
cp += r6 - r5
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << ((OFST + 6 * BP) & 7)))
cp += r7 - r6
if eplmt == cp or eplmt < cp: return
cp.store(cp.load() | (1 << ((OFST + 7 * BP) & 7)))
 
fn mkExtrm[CNT: Int](pntr: Pointer[UnrollFunc]):
@parameter
if CNT >= 32:
return
alias OFST = CNT >> 2
alias BP = ((CNT & 3) << 1) + 1
pntr.offset(CNT).store(extreme[OFST, BP])
mkExtrm[CNT + 1](pntr)
 
@always_inline
fn mkExtremeFuncs() -> Pointer[UnrollFunc]:
let jmptbl: Pointer[UnrollFunc] = Pointer[UnrollFunc].alloc(32)
mkExtrm[0](jmptbl)
return jmptbl
let extremeFuncs = mkExtremeFuncs()
 
alias DenseFunc = fn(DTypePointer[DType.uint64], Int, Int) -> DTypePointer[DType.uint64]
 
fn mkDenseCull[N: Int, BP: Int](cp: DTypePointer[DType.uint64]):
@parameter
if N >= 64:
return
alias MUL = N * BP
var cop = cp.offset(MUL >> 6)
cop.store(cop.load() | (1 << (MUL & 63)))
mkDenseCull[N + 1, BP](cp)
 
@always_inline
fn denseCullFunc[BP: Int](pcmps: DTypePointer[DType.uint64], bufsz: Int, s: Int) -> DTypePointer[DType.uint64]:
var cp: DTypePointer[DType.uint64] = pcmps + (s >> 6)
let plmt = pcmps + (bufsz >> 3) - BP
while cp < plmt:
mkDenseCull[0, BP](cp)
cp += BP
return cp
 
fn mkDenseFunc[CNT: Int](pntr: Pointer[DenseFunc]):
@parameter
if CNT >= 64:
return
alias BP = (CNT << 1) + 3
pntr.offset(CNT).store(denseCullFunc[BP])
mkDenseFunc[CNT + 1](pntr)
 
@always_inline
fn mkDenseFuncs() -> Pointer[DenseFunc]:
let jmptbl : Pointer[DenseFunc] = Pointer[DenseFunc].alloc(64)
mkDenseFunc[0](jmptbl)
return jmptbl
 
let denseFuncs : Pointer[DenseFunc] = mkDenseFuncs()
 
@always_inline
fn cullPass(cmpsts: DTypePointer[DType.uint8], bytesz: Int, s: Int, bp: Int):
if bp <= 129: # dense culling
var sm = s
while (sm >> 3) < bytesz and (sm & 63) != 0:
cmpsts[sm >> 3] |= (1 << (sm & 7))
sm += bp
let bcp = denseFuncs[(bp - 3) >> 1](cmpsts.bitcast[DType.uint64](), bytesz, sm)
var ns = 0
var ncp = bcp
let cmpstslmtp = (cmpsts + bytesz).bitcast[DType.uint64]()
while ncp < cmpstslmtp:
ncp[0] |= (1 << (ns & 63))
ns += bp
ncp = bcp + (ns >> 6)
else: # extreme loop unrolling culling
extremeFuncs[((s & 7) << 2) + ((bp & 7) >> 1)](cmpsts, bytesz, s, bp)
# for c in range(s, self.len, bp): # slow bit twiddling way
# self.cmpsts[c >> 3] |= (1 << (c & 7))
 
fn cullPage(lwi: Int, lmt: Int, cmpsts: DTypePointer[DType.uint8], bsprmrps: DTypePointer[DType.uint8]):
var bp = 1; var ndx = 0
while True:
bp += bsprmrps[ndx].to_int() << 1
let i = (bp - 3) >> 1
var s = (i + i) * (i + 3) + 3
if s >= lmt: break
if s >= lwi: s -= lwi
else:
s = (lwi - s) % bp
if s != 0: s = bp - s
cullPass(cmpsts, cBufferSize, s, bp)
ndx += 1
 
fn countPagePrimes(ptr: DTypePointer[DType.uint8], bitsz: Int) -> Int:
let wordsz: Int = (bitsz + 63) // 64 # round up to nearest 64 bit boundary
var rslt: Int = wordsz * 64
let bigcmps = ptr.bitcast[DType.uint64]()
for i in range(wordsz - 1):
rslt -= ctpop(bigcmps[i]).to_int()
rslt -= ctpop(bigcmps[wordsz - 1] | (-2 << ((bitsz - 1) & 63))).to_int()
return rslt
 
struct SoEOdds(Sized):
var len: Int
var cmpsts: DTypePointer[DType.uint8] # because DynamicVector has deep copy bug in Mojo version 0.7
var sz: Int
var ndx: Int
fn __init__(inout self, limit: Int):
self.len = 0 if limit < 2 else (limit - 3) // 2 + 1
self.sz = 0 if limit < 2 else self.len + 1 # for the unprocessed only even prime of two
self.ndx = -1
let bytesz = 0 if limit < 2 else ((self.len + 63) & -64) >> 3 # round up to nearest 64 bit boundary
self.cmpsts = DTypePointer[DType.uint8].alloc(bytesz)
memset_zero(self.cmpsts, bytesz)
for i in range(self.len):
let s = (i + i) * (i + 3) + 3
if s >= self.len: break
if (self.cmpsts[i >> 3] >> (i & 7)) & 1 != 0: continue
let bp = i + i + 3
cullPass(self.cmpsts, bytesz, s, bp)
self.sz = countPagePrimes(self.cmpsts, self.len) + 1 # add one for only even prime of two
fn __del__(owned self):
self.cmpsts.free()
fn __copyinit__(inout self, existing: Self):
self.len = existing.len
let bytesz = (self.len + 7) // 8
self.cmpsts = DTypePointer[DType.uint8].alloc(bytesz)
memcpy(self.cmpsts, existing.cmpsts, bytesz)
self.sz = existing.sz
self.ndx = existing.ndx
fn __moveinit__(inout self, owned existing: Self):
self.len = existing.len
self.cmpsts = existing.cmpsts
self.sz = existing.sz
self.ndx = existing.ndx
fn __len__(self: Self) -> Int: return self.sz
fn __iter__(self: Self) -> Self: return self
@always_inline
fn __next__(inout self: Self) -> Int:
if self.ndx < 0:
self.ndx = 0; self.sz -= 1; return 2
while (self.ndx < self.len) and ((self.cmpsts[self.ndx >> 3] >> (self.ndx & 7)) & 1 != 0):
self.ndx += 1
let rslt = (self.ndx << 1) + 3; self.sz -= 1; self.ndx += 1; return rslt
 
struct SoEOddsPaged:
var len: Int
var cmpsts: DTypePointer[DType.uint8] # because DynamicVector has deep copy bug in Mojo version 0.7
var sz: Int # 0 means finished; otherwise contains number of odd base primes
var ndx: Int
var lwi: Int
var bsprmrps: DTypePointer[DType.uint8] # contains deltas between odd base primes starting from zero
fn __init__(inout self, limit: UInt64):
self.len = 0 if limit < 2 else ((limit - 3) // 2 + 1).to_int()
self.sz = 0 if limit < 2 else 1 # means iterate until this is set to zero
self.ndx = -1 # for unprocessed only even prime of two
self.lwi = 0
if self.len < cBufferBits:
let bytesz = ((self.len + 63) & -64) >> 3 # round up to nearest 64 bit boundary
self.cmpsts = DTypePointer[DType.uint8].alloc(bytesz)
self.bsprmrps = DTypePointer[DType.uint8].alloc(self.sz)
else:
self.cmpsts = DTypePointer[DType.uint8].alloc(cBufferSize)
let bsprmitr = SoEOdds(intsqrt(limit).to_int())
self.sz = len(bsprmitr)
self.bsprmrps = DTypePointer[DType.uint8].alloc(self.sz)
var ndx = -1; var oldbp = 1
for bsprm in bsprmitr:
if ndx < 0: ndx += 1; continue # skip over the 2 prime
self.bsprmrps[ndx] = (bsprm - oldbp) >> 1
oldbp = bsprm; ndx += 1
self.bsprmrps[ndx] = 255 # one extra value to go beyond the necessary cull space
fn __del__(owned self):
self.cmpsts.free(); self.bsprmrps.free()
fn __copyinit__(inout self, existing: Self):
self.len = existing.len
self.sz = existing.sz
let bytesz = cBufferSize if self.len >= cBufferBits
else ((self.len + 63) & -64) >> 3 # round up to nearest 64 bit boundary
self.cmpsts = DTypePointer[DType.uint8].alloc(bytesz)
memcpy(self.cmpsts, existing.cmpsts, bytesz)
self.ndx = existing.ndx
self.lwi = existing.lwi
self.bsprmrps = DTypePointer[DType.uint8].alloc(self.sz)
memcpy(self.bsprmrps, existing.bsprmrps, self.sz)
fn __moveinit__(inout self, owned existing: Self):
self.len = existing.len
self.cmpsts = existing.cmpsts
self.sz = existing.sz
self.ndx = existing.ndx
self.lwi = existing.lwi
self.bsprmrps = existing.bsprmrps
fn countPrimes(self) -> Int:
if self.len <= cBufferBits: return len(SoEOdds(2 * self.len + 1))
var cnt = 1; var lwi = 0
let cmpsts = DTypePointer[DType.uint8].alloc(cBufferSize)
memset_zero(cmpsts, cBufferSize)
cullPage(0, cBufferBits, cmpsts, self.bsprmrps)
while lwi + cBufferBits <= self.len:
cnt += countPagePrimes(cmpsts, cBufferBits)
lwi += cBufferBits
memset_zero(cmpsts, cBufferSize)
let lmt = lwi + cBufferBits if lwi + cBufferBits <= self.len else self.len
cullPage(lwi, lmt, cmpsts, self.bsprmrps)
cnt += countPagePrimes(cmpsts, self.len - lwi)
return cnt
fn __len__(self: Self) -> Int: return self.sz
fn __iter__(self: Self) -> Self: return self
@always_inline
fn __next__(inout self: Self) -> Int: # don't count number of primes by interating - slooow
if self.ndx < 0:
self.ndx = 0; self.lwi = 0
if self.len < 2: self.sz = 0
elif self.len <= cBufferBits:
let bytesz = ((self.len + 63) & -64) >> 3 # round up to nearest 64 bit boundary
memset_zero(self.cmpsts, bytesz)
for i in range(self.len):
let s = (i + i) * (i + 3) + 3
if s >= self.len: break
if (self.cmpsts[i >> 3] >> (i & 7)) & 1 != 0: continue
let bp = i + i + 3
cullPass(self.cmpsts, bytesz, s, bp)
else:
memset_zero(self.cmpsts, cBufferSize)
cullPage(0, cBufferBits, self.cmpsts, self.bsprmrps)
return 2
let rslt = ((self.lwi + self.ndx) << 1) + 3; self.ndx += 1
if self.lwi + cBufferBits >= self.len:
while (self.lwi + self.ndx < self.len) and ((self.cmpsts[self.ndx >> 3] >> (self.ndx & 7)) & 1 != 0):
self.ndx += 1
else:
while (self.ndx < cBufferBits) and ((self.cmpsts[self.ndx >> 3] >> (self.ndx & 7)) & 1 != 0):
self.ndx += 1
while (self.ndx >= cBufferBits) and (self.lwi + cBufferBits <= self.len):
self.ndx = 0; self.lwi += cBufferBits; memset_zero(self.cmpsts, cBufferSize)
let lmt = self.lwi + cBufferBits if self.lwi + cBufferBits <= self.len else self.len
cullPage(self.lwi, lmt, self.cmpsts, self.bsprmrps)
let buflmt = cBufferBits if self.lwi + cBufferBits <= self.len else self.len - self.lwi
while (self.ndx < buflmt) and ((self.cmpsts[self.ndx >> 3] >> (self.ndx & 7)) & 1 != 0):
self.ndx += 1
if self.lwi + self.ndx >= self.len: self.sz = 0
return rslt
 
fn main():
print("The primes to 100 are:")
for prm in SoEOddsPaged(100): print_no_newline(prm, " ")
print()
let strt0 = now()
let answr0 = SoEOddsPaged(1_000_000).countPrimes()
let elpsd0 = (now() - strt0) / 1000000
print("Found", answr0, "primes up to 1,000,000 in", elpsd0, "milliseconds.")
let strt1 = now()
let answr1 = SoEOddsPaged(cLIMIT).countPrimes()
let elpsd1 = (now() - strt1) / 1000000
print("Found", answr1, "primes up to", cLIMIT, "in", elpsd1, "milliseconds.")</syntaxhighlight>
 
{{out}}
 
<pre>The primes to 100 are:
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
Found 78498 primes up to 1,000,000 in 0.084122000000000002 milliseconds.
Found 50847534 primes up to 1000000000 in 139.509275 milliseconds.</pre>
 
This was tested on the same computer as the previous Mojo versions. Note that the time now scales quite well with range since there are no longer the huge RAM access time bottleneck's. This version is only about 2.25 times slower than Kim Walich's primesieve program written in C++ and the mostly constant factor difference will be made up if one adds wheel factorization to the same level as he uses (basic wheel factorization ratio of 48/105 plus some other more minor optimizations). This version can count the number of primes to 1e11 in about 21.85 seconds on this machine. It will work reasonably efficiently up to a range of about 1e14 before other optimization techniques such as "bucket sieving" should be used.
 
For counting the number of primes to a billion (1e9), this version has reduced the time by about a factor of 40 from the original version and over eight times from the odds-only version above. Adding wheel factorization will make it almost two and a half times faster yet for a gain in speed of about a hundred times over the original version.
 
=={{header|MUMPS}}==
<langsyntaxhighlight MUMPSlang="mumps">ERATO1(HI)
;performs the Sieve of Erotosethenes up to the number passed in.
;This version sets an array containing the primes
Line 7,971 ⟶ 13,282:
FOR I=2:1:HI S:'$DATA(P(I)) ERATO1(I)=I
KILL I,J,P
QUIT</langsyntaxhighlight>
Example:
<pre>USER>SET MAX=100,C=0 DO ERATO1^ROSETTA(MAX)
Line 7,978 ⟶ 13,289:
PRIMES BETWEEN 1 AND 100
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,</pre>
 
=={{header|Neko}}==
<syntaxhighlight lang="actionscript">/* The Computer Language Shootout
http://shootout.alioth.debian.org/
 
contributed by Nicolas Cannasse
*/
fmt = function(i) {
var s = $string(i);
while( $ssize(s) < 8 )
s = " "+s;
return s;
}
nsieve = function(m) {
var a = $amake(m);
var count = 0;
var i = 2;
while( i < m ) {
if $not(a[i]) {
count += 1;
var j = (i << 1);
while( j < m ) {
if( $not(a[j]) ) a[j] = true;
j += i;
}
}
i += 1;
}
$print("Primes up to ",fmt(m)," ",fmt(count),"\n");
}
 
var n = $int($loader.args[0]);
if( n == null ) n = 2;
var i = 0;
while( i < 3 ) {
nsieve(10000 << (n - i));
i += 1;
}</syntaxhighlight>
 
{{out}}
<pre>prompt$ nekoc nsieve.neko
prompt$ time -p neko nsieve.n
Primes up to 40000 4203
Primes up to 20000 2262
Primes up to 10000 1229
real 0.02
user 0.01
sys 0.00</pre>
 
 
=={{header|NetRexx}}==
===Version 1 (slow)===
<langsyntaxhighlight Rexxlang="rexx">/* NetRexx */
 
options replace format comments java crossref savelog symbols binary
Line 8,037 ⟶ 13,397:
method isFalse public constant binary returns boolean
return \isTrue
</syntaxhighlight>
</lang>
;Output
<pre style="overflow:scroll">
Line 8,045 ⟶ 13,405:
</pre>
===Version 2 (significantly, i.e. 10 times faster)===
<langsyntaxhighlight NetRexxlang="netrexx">/* NetRexx ************************************************************
* Essential improvements:Use boolean instead of Rexx for sv
* and remove methods isTrue and isFalse
Line 8,111 ⟶ 13,471:
end p_
 
return primes</langsyntaxhighlight>
 
=={{header|newLISP}}==
{{incorrect|newLISP|This version uses rem (division) testing and so is a trial division algorithm, not a sieve of Eratosthenes.}}
This version is maybe a little different because it no longer stores the primes after they've been generated and sent to the main output. Lisp has very convenient list editing, so we don't really need the Boolean flag arrays you'd tend find in the Algol-like languages. We can just throw away the multiples of each prime from an initial list of integers. The implementation is easier if we delete every multiple, including the prime number itself: the list always contains only the numbers that haven't been processed yet, starting with the next prime, and the program is finished when the list becomes empty.
 
Note that the lambda expression in the following script does not involve a closure; newLISP has dynamic scope, so it matters that the same variable names will not be reused for some other purpose (at runtime) before the anonymous function is called.
 
<syntaxhighlight lang="newlisp">(set 'upper-bound 1000)
 
; The initial sieve is a list of all the numbers starting at 2.
(set 'sieve (sequence 2 upper-bound))
 
; Keep working until the list is empty.
(while sieve
 
; The first number in the list is always prime
(set 'new-prime (sieve 0))
(println new-prime)
 
; Filter the list leaving only the non-multiples of each number.
(set 'sieve
(filter
(lambda (each-number)
(not (zero? (% each-number new-prime))))
sieve)))
 
(exit)</syntaxhighlight>
 
{{output}}
<pre>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
101
103
107
109
113
127
131
137
139
149
151
157
163
167
173
179
181
191
193
197
199
211
223
227
229
233
239
241
251
257
263
269
271
277
281
283
293
307
311
313
317
331
337
347
349
353
359
367
373
379
383
389
397
401
409
419
421
431
433
439
443
449
457
461
463
467
479
487
491
499
503
509
521
523
541
547
557
563
569
571
577
587
593
599
601
607
613
617
619
631
641
643
647
653
659
661
673
677
683
691
701
709
719
727
733
739
743
751
757
761
769
773
787
797
809
811
821
823
827
829
839
853
857
859
863
877
881
883
887
907
911
919
929
937
941
947
953
967
971
977
983
991
997
</pre>
 
=={{header|Nial}}==
Line 8,119 ⟶ 13,677:
|primes 10
=2 3 5 7
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">from math import sqrt
iterator primesUpto(limit: int): int =
Line 8,127 ⟶ 13,686:
for n in 2 .. sqrtLimit: # cull to square root of limit
if not composites[n]: # if prime -> cull its composites
for c in countup(n *% n, limit +% 1, n): # start at ``n`` squared
composites[c] = true
for n in 2 .. limit: # separate iteration over results
Line 8,136 ⟶ 13,695:
for x in primesUpto(100):
stdout.write(x, " ")
echo ""()
var count = 0
for p in primesUpto(1000000):
count += 1
echo "There are ", count, " primes up to 1000000."</langsyntaxhighlight>
{{out}}
<pre>Primes are:
Line 8,151 ⟶ 13,710:
The above version wastes quite a lot of memory by using a sequence of boolean values to sieve the composite numbers and sieving all numbers when two is the only even prime. The below code uses a bit-packed sequence to save a factor of eight in memory and also sieves only odd primes for another memory saving by a factor of two; it is also over two and a half times faster due to reduced number of culling operations and better use of the CPU cache as a little cache goes a lot further - this better use of cache is more than enough to make up for the extra bit-packing shifting operations:
 
<langsyntaxhighlight lang="nim">iterator isoe_upto(top: uint): uint =
let topndx = int((top - 3) div 2)
let sqrtndx = (int(sqrt float64(top)) - 3) div 2
Line 8,163 ⟶ 13,722:
for i in 0 .. topndx:
if (cmpsts[i shr 5] and (1u32 shl (i and 31))) == 0:
yield uint(i + i + 3)</langsyntaxhighlight>
 
The above code can be used with the same output functions as in the first code, just replacing the name of the iterator "iprimes_upto" with this iterator's name "isoe_upto" in two places. The output will be identical.
Line 8,170 ⟶ 13,729:
 
For many purposes, one doesn't know the exact upper limit desired to easily use the above versions; in addition, those versions use an amount of memory proportional to the range sieved. In contrast, unbounded versions continuously update their range as they progress and only use memory proportional to the secondary base primes stream, which is only proportional to the square root of the range. One of the most basic functional versions is the TreeFolding sieve which is based on merging lazy streams as per Richard Bird's contribution to incremental sieves in Haskell, but which has a much better asymptotic execution complexity due to the added tree folding. The following code is a version of that in Nim (odds-only):
<syntaxhighlight lang ="nim">from times import epochTimesugar
from times import epochTime
 
type PrimeType = int
Line 8,181 ⟶ 13,741:
 
proc merge(xs, ys: CIS[PrimeType]): CIS[PrimeType] =
let x = xs.head; let y = ys.head
let y = ys.head
if x < y:
CIS[PrimeType](head: x, tail: () => merge(xs.tail(), ys))
Line 8,205 ⟶ 13,766:
 
proc pairs(css: CIS[CIS[PrimeType]]): CIS[CIS[PrimeType]] =
let cs0 = css.head; let rest0 = css.tail()
let rest0 = css.tail()
CIS[CIS[PrimeType]](
head: merge(cs0, rest0.head),
Line 8,217 ⟶ 13,779:
 
proc minusAt(n: PrimeType, cs: CIS[PrimeType]): CIS[PrimeType] =
var nn = n; var ncs = cs
while nn >=var ncs.head: nn += 2; ncs = ncs.tail()cs
while nn >= ncs.head:
nn += 2;
ncs = ncs.tail()
CIS[PrimeType](head: nn, tail: () => minusAt(nn + 2, ncs))
 
Line 8,226 ⟶ 13,791:
tail: () => minusAt(5.PrimeType, oddprms().allmults.cmpsts))
 
var prms = CIS[PrimeType](head: 2.PrimeType, tail: () => oddprms())
var prms =
while true:
CIS[PrimeType](head: 2.PrimeType, tail: () => oddprms())
while true: yield prms.head; prms = prms.tail()
prms = prms.tail()
 
stdout.write "The first 25 primes are: "
Line 8,235 ⟶ 13,801:
if counter >= 25: break
stdout.write(p, " "); counter += 1
echo ""()
 
start = epochTime()
let start = epochTime()
counter = 0
for p in primesTreeFolding():
if p > range1000000: break else: counter += 1
else: counter += 1
elapsed = epochTime() - start
let elapsed = epochTime() - start
echo "There are ", counter, " primes up to 1000000."
echo "This test took ", elapsed, " seconds."</langsyntaxhighlight>
{{output}}
<pre>The first 25 primes are: 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
There are 78498 primes up to 1000000.
This test took 10.7532386779785162780287265777588 seconds.</pre>
 
ItWith Nim 1.4, it takes inabout the0.4s order of(in arelease secondor danger mode) to compute the primes tountil aone million, (dependingbetter onthan CPU)the time needed in previous versions. With option "--gc arc", andthis time drops to 0.28s on a small laptop. This is sostill slow compared to bound algorithm which is due to the many small memory allocations/de-allocations required, which is a characteristic of functional forms of code. Is is purely functional in that everything is immutable other than that Nim does not have Tail Call Optimization (TCO) so that we can freely use function recursion with no execution time cost; therefore, where necessary this is implemented with imperative loops, which is what TCO is generally turned into such forms "under the covers". It is also slow due to the algorithm being only O(n (log n) (log (log n))) rather than without the extra "log n" factor as some version have. This slowness makes it only moderately useful for ranges up to a few million.
 
Since the algorithm does not require the memoization of a full lazy list, it uses an internal Co Inductive Stream of deferred execution states, finally outputting an iterator to enumerate over the lazily computed stream of primes.
Line 8,255 ⟶ 13,823:
 
To show the cost of functional forms of code, the following code is written embracing mutability, both by using a mutable hash table to store the state of incremental culling by the secondary stream of base primes and by using mutable values to store the state wherever possible, as per the following code:
<langsyntaxhighlight lang="nim">import tables, times
 
type PrimeType = int
Line 8,265 ⟶ 13,833:
var n = 9.PrimeType
let bps = primesHashTable()
var bp = bps() # advance past 2
bp = bps(); var q = bp * bp # to initialize with 3
var q = bp * bp # to initialize with 3
while true:
if n >= q:
let incincr = bp + bp
h.add([n + inc,incr] inc)= incr
bp = bps(); q = bp * bp
q = bp * bp
elif h.hasKey(n):
var incincr: PrimeType
discard h.take(n, incincr)
var nxt = n + incincr
while h.hasKey(nxt): nxt += inc # ensure no duplicates
h.add( nxt, inc)+= incr # ensure no duplicates
else: yield nh[nxt] = incr
else:
yield n
n += 2.PrimeType
output
Line 8,286 ⟶ 13,858:
var iter = primesHashTable()
for p in iter():
if counter >= 25: break else: stdout.write(p, " "); counter += 1
break
else:
stdout.write(p, " ")
counter += 1
echo ""
let start = epochTime()
Line 8,292 ⟶ 13,868:
iter = primesHashTable()
for p in iter():
if p > 1000000: break else: counter += 1
else: counter += 1
let elapsed = epochTime() - start
echo "The number of primes up to a million is: ", counter
stdout.write("This test took ", elapsed, " seconds.\n")</langsyntaxhighlight>
 
{{out}}
Time for version compiled with “-d:danger” option.
<pre>The first 25 primes are: 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
The number of primes up to a million is: 78498
This test took 0.05106830596923828 seconds.</pre>
 
The output is identical to the first unbounded version, other than, in danger mode, it is over about 15eight times faster sieving to a million. For larger ranges it will continue to pull further ahead of the above version due to only O(n (log (log n))) performance because of the hash table having an average of O(1) access, and it is only so slow due to the large constant overhead of doing the hashing calculations and look-ups.
 
'''Very fast Page Segmented version using a bit-packed mutable array (odds-only)'''
Line 8,304 ⟶ 13,887:
 
For the highest speeds, one needs to use page segmented mutable arrays as in the bit-packed version here:
<langsyntaxhighlight lang="nim"># a Page Segmented Odd-Only Bit-Packed Sieve of Eratosthenes...
 
from times import epochTime # for testing
Line 8,474 ⟶ 14,057:
let elpsd = epochTime() - start
 
echo "Found ", counter, " primes up to ", LIMIT, " in ", elpsd, " seconds."</langsyntaxhighlight>
{{output}}
Time is obtained with Nim 1.4 with options <code>-d:danger --gc:arc</code>.
<pre>Page Segmented Bit-Packed Odds-Only Sieve of Eratosthenes
Needs at least 16384 bytes of CPU L1 cache memory.
Line 8,481 ⟶ 14,065:
First 25 primes: 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
The number of primes up to a million is: 78498 - these both found by (slower) enumeration.
Found 50847534 primes up to 1000000000 in 10.3997950553894047931935787200928 seconds.</pre>
 
The above version approaches a hundred times faster than the incremental style versions above due to the high efficiency of direct mutable memory operations in modern CPU's, and is useful for ranges of billions. This version maintains its efficiency using the CPU L1 cache to a range of over 16 billion and then gets a little slower for ranges of a trillion or more using the CPU's L2 cache. It takes an average of only about 3.5 CPU clock cycles per composite number cull, or about 70 CPU clock cycles per prime found.
Line 8,491 ⟶ 14,075:
=={{header|Niue}}==
{{incorrect|Niue|It uses rem testing and so is a trial division algorithm, not a sieve of Eratosthenes.}}
<langsyntaxhighlight Niuelang="niue">[ dup 2 < ] '<2 ;
[ 1 + 'count ; [ <2 [ , ] when ] count times ] 'fill-stack ;
 
Line 8,511 ⟶ 14,095:
 
10 sieve .s ( => 2 3 5 7 9 ) reset newline
30 sieve .s ( => 2 3 5 7 11 13 17 19 23 29 ) </langsyntaxhighlight>
 
=={{header|Oberon-2}}==
<langsyntaxhighlight lang="oberon2">MODULE Primes;
 
IMPORT Out, Math;
Line 8,546 ⟶ 14,131:
END;
Out.Ln;
END Primes.</langsyntaxhighlight>
 
=={{header|OCaml}}==
===Imperative===
<langsyntaxhighlight lang="ocaml">let sieve n =
let is_prime = Array.create n true in
let limit = truncate(sqrt (float (n - 1))) in
Line 8,562 ⟶ 14,148:
is_prime.(0) <- false;
is_prime.(1) <- false;
is_prime</langsyntaxhighlight>
 
<langsyntaxhighlight lang="ocaml">let primes n =
let primes, _ =
let sieve = sieve n in
Line 8,572 ⟶ 14,158:
([], Array.length sieve - 1)
in
primes</langsyntaxhighlight>
 
in the top-level:
Line 8,581 ⟶ 14,167:
 
===Functional===
<langsyntaxhighlight lang="ocaml">(* first define some iterators *)
# let fold_iter f init a b =
let rec aux acc i =
if i > b
then (acc)
else aux (f acc i) (succ i)
in
aux init a ;;
(* val fold_iter : ('a -> int -> 'a) -> 'a -> int -> int -> 'a = <fun>*)
 
# let fold_step f init a b step =
let rec aux acc i =
if i > b
then (acc)
else aux (f acc i) (i + step)
in
aux init a ;;
(* val fold_step : ('a -> int -> 'a) -> 'a -> int -> int -> int -> 'a = <fun>*)
 
(* remove a given value from a list *)
# let remove li v =
let rec aux acc = function
| hd::tl when hd = v -> (List.rev_append acc tl)
| hd::tl -> aux (hd::acc) tl
| [] -> li
in
aux [] li ;;
(* val remove : 'a list -> 'a -> 'a list = <fun>*)
 
(* the main function *)
# let primes n =
let li =
(* create a list [from 2; ... until n] *)
List.rev(fold_iter (fun acc i -> (i::acc)) [] 2 n)
in
let limit = truncate(sqrt(float n)) in
fold_iter (fun li i ->
if List.mem i li (* test if (i) is prime *)
then (fold_step remove li (i*i) n i)
else li)
li 2 (pred limit)
(* val primes : int -> int list *)
;;
</syntaxhighlight>
val primes : int -> int list = <fun>
in the top-level:
 
<syntaxhighlight lang="ocaml"># primes 200 ;;
- : int list =
[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; 101; 103; 107; 109; 113; 127; 131; 137; 139; 149; 151;
157; 163; 167; 173; 179; 181; 191; 193; 197; 199]</langsyntaxhighlight>
 
=== Another functional version ===
Line 8,635 ⟶ 14,221:
This uses zero to denote struck-out numbers. It is slightly inefficient as it strikes-out multiples above p rather than p<sup>2</sup>
 
<syntaxhighlight lang ="ocaml"># let rec strike_nth k n l = match l with
| [] -> []
| h :: t ->
if k = 0 then 0 :: strike_nth (n-1) n t
else h :: strike_nth (k-1) n t;;
(* val strike_nth : int -> int -> int list -> int list = <fun>*)
 
# let primes n =
let limit = truncate(sqrt(float n)) in
let rec range a b = if a > b then [] else a :: range (a+1) b in
Line 8,650 ⟶ 14,236:
| h :: t -> if h > limit then List.filter ((<) 0) l else
h :: sieve_primes (strike_nth (h-1) h t) in
sieve_primes (range 2 n) ;;
(* val primes : int -> int list = <fun>*)
 
</syntaxhighlight>
# primes 200;;
in the top-level:
<syntaxhighlight lang="ocaml"># primes 200;;
- : int list =
[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; 101; 103; 107; 109; 113; 127; 131; 137; 139; 149; 151;
157; 163; 167; 173; 179; 181; 191; 193; 197; 199]</langsyntaxhighlight>
 
=={{header|Oforth}}==
 
<langsyntaxhighlight Oforthlang="oforth">: eratosthenes(n)
| i j |
ListBuffer newSize(n) dup add(null) seqFrom(2, n) over addAll
Line 8,667 ⟶ 14,255:
dup at(i) ifNotNull: [ i sq n i step: j [ dup put(j, null) ] ]
]
filter(#notNull) ;</langsyntaxhighlight>
 
{{out}}
Line 8,676 ⟶ 14,264:
 
=={{header|Ol}}==
<langsyntaxhighlight lang="scheme">
(define all (iota 999 2))
 
Line 8,693 ⟶ 14,281:
(loop (cons (car r) l) (cdr r) (+ n 1) every)))))))
)
</syntaxhighlight>
</lang>
 
Output:
<pre>
(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 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997)
</pre>
 
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">
/*ooRexx program generates & displays primes via the sieve of Eratosthenes.
* derived from first Rexx version
* uses an array rather than a stem for the list
* uses string methods rather than BIFs
* uses new ooRexx keyword LOOP, extended assignment
* and line comments
* uses meaningful variable names and restructures code
* layout for improved understandability
****************************************************************************/
arg highest --get highest number to use.
if \highest~datatype('W') then
highest = 200 --use default value.
isPrime = .array~new(highest) --container for all numbers.
isPrime~fill(1) --assume all numbers are prime.
w = highest~length --width of the biggest number,
-- it's used for aligned output.
out1 = 'prime'~right(20) --first part of output messages.
np = 0 --no primes so far.
loop j = 2 for highest - 1 --all numbers up through highest.
if isPrime[j] = 1 then do --found one.
np += 1 --bump the prime counter.
say out1 np~right(w) ' --> ' j~right(w) --display output.
loop m = j * j to highest by j
isPrime[m] = '' --strike all multiples: not prime.
end
end
end
say
say np~right(out1~length + 1 + w) 'primes found up to and including ' highest
exit
</syntaxhighlight>
{{out}}
<pre>
prime 1 --> 2
prime 2 --> 3
prime 3 --> 5
prime 4 --> 7
prime 5 --> 11
prime 6 --> 13
prime 7 --> 17
prime 8 --> 19
prime 9 --> 23
prime 10 --> 29
prime 11 --> 31
prime 12 --> 37
prime 13 --> 41
prime 14 --> 43
prime 15 --> 47
prime 16 --> 53
prime 17 --> 59
prime 18 --> 61
prime 19 --> 67
prime 20 --> 71
prime 21 --> 73
prime 22 --> 79
prime 23 --> 83
prime 24 --> 89
prime 25 --> 97
prime 26 --> 101
prime 27 --> 103
prime 28 --> 107
prime 29 --> 109
prime 30 --> 113
prime 31 --> 127
prime 32 --> 131
prime 33 --> 137
prime 34 --> 139
prime 35 --> 149
prime 36 --> 151
prime 37 --> 157
prime 38 --> 163
prime 39 --> 167
prime 40 --> 173
prime 41 --> 179
prime 42 --> 181
prime 43 --> 191
prime 44 --> 193
prime 45 --> 197
prime 46 --> 199
 
46 primes found up to and including 200
</pre>
===Wheel Version===
<syntaxhighlight lang="oorexx">
/*ooRexx program generates primes via sieve of Eratosthenes algorithm.
* wheel version, 2 handled as special case
* loops optimized: outer loop stops at the square root of
* the limit, inner loop starts at the square of the
* prime just found
* use a list rather than an array and remove composites
* rather than just mark them
* convert list of primes to a list of output messages and
* display them with one say statement
*******************************************************************************/
arg highest -- get highest number to use.
if \highest~datatype('W') then
highest = 200 -- use default value.
w = highest~length -- width of the biggest number,
-- it's used for aligned output.
thePrimes = .list~of(2) -- the first prime is 2.
loop j = 3 to highest by 2 -- populate the list with odd nums.
thePrimes~append(j)
end
 
j = 3 -- first prime (other than 2)
ix = thePrimes~index(j) -- get the index of 3 in the list.
loop while j*j <= highest -- strike multiples of odd ints.
-- up to sqrt(highest).
loop jm = j*j to highest by j+j -- start at J squared, incr. by 2*J.
thePrimes~removeItem(jm) -- delete it since it's composite.
end
ix = thePrimes~next(ix) -- the index of the next prime.
j = thePrimes[ix] -- the next prime.
end
np = thePrimes~items -- the number of primes since the
-- list is now only primes.
out1 = ' prime number' -- first part of output messages.
out2 = ' --> ' -- middle part of output messages.
ix = thePrimes~first
loop n = 1 to np -- change the list of primes
-- to output messages.
thePrimes[ix] = out1 n~right(w) out2 thePrimes[ix]~right(w)
ix = thePrimes~next(ix)
end
last = np~right(out1~length+1+w) 'primes found up to and including ' highest
thePrimes~append(.endofline || last) -- add blank line and summary line.
say thePrimes~makearray~toString -- display the output.
exit
</syntaxhighlight>
{{out}}when using the limit of 100
<pre>
prime number 1 --> 2
prime number 2 --> 3
prime number 3 --> 5
prime number 4 --> 7
prime number 5 --> 11
prime number 6 --> 13
prime number 7 --> 17
prime number 8 --> 19
prime number 9 --> 23
prime number 10 --> 29
prime number 11 --> 31
prime number 12 --> 37
prime number 13 --> 41
prime number 14 --> 43
prime number 15 --> 47
prime number 16 --> 53
prime number 17 --> 59
prime number 18 --> 61
prime number 19 --> 67
prime number 20 --> 71
prime number 21 --> 73
prime number 22 --> 79
prime number 23 --> 83
prime number 24 --> 89
prime number 25 --> 97
 
25 primes found up to and including 100
</pre>
 
=={{header|Oz}}==
{{trans|Haskell}}
<langsyntaxhighlight lang="oz">declare
fun {Sieve N}
S = {Array.new 2 N true}
Line 8,725 ⟶ 14,475:
end
in
{Show {Primes 30}}</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">Eratosthenes(lim)={
my(v=VectorsmallVecsmall(lim\1,unused,1));
forprime(p=2,sqrt(lim),
forstep(i=p^2,lim,p,
Line 8,736 ⟶ 14,486:
);
for(i=1,lim,if(v[i],print1(i", ")))
};</langsyntaxhighlight>
 
An alternate version:
 
<langsyntaxhighlight lang="parigp">Sieve(n)=
{
v=vector(n,unused,1);
Line 8,746 ⟶ 14,496:
if(v[i],
forstep(j=i^2,n,i,v[j]=0)));
for(i=2,n,if(v[i],print1(i",")))
};</langsyntaxhighlight>
 
=={{header|Pascal}}==
Note: Some Pascal implementations put quite low limits on the size of a set (e.g. Turbo Pascal doesn't allow more than 256 members). To compile on such an implementation, reduce the constant PrimeLimit accordingly.
<langsyntaxhighlight lang="pascal">
program primes(output)
 
Line 8,792 ⟶ 14,542:
end
end.
</syntaxhighlight>
</lang>
===alternative using wheel ===
Using growing wheel to fill array for sieving for minimal unmark operations.
Sieving only with possible-prime factors.
<langsyntaxhighlight lang="pascal">
program prim(output);
//Sieve of Erathosthenes with fast elimination of multiples of small primes
Line 8,926 ⟶ 14,676:
inc(prCnt,Ord(primes[i]));
writeln(prCnt,' primes up to ',PrimeLimit);
end.</langsyntaxhighlight>
 
output: ( i3 4330 Haswell 3.5 Ghz fpc 2.6.4 -O3 )
Line 8,942 ⟶ 14,692:
 
===Classic Sieve===
<langsyntaxhighlight lang="perl">sub sieve {
my $n = shift;
my @composite;
Line 8,957 ⟶ 14,707:
}
@primes;
}</langsyntaxhighlight>
 
===Odds only (faster)===
<langsyntaxhighlight lang="perl">sub sieve2 {
my($n) = @_;
return @{([],[],[2],[2,3],[2,3])[$n]} if $n <= 4;
Line 8,976 ⟶ 14,726:
}
@primes;
}</langsyntaxhighlight>
 
===Odds only, using vectors for lower memory use===
<langsyntaxhighlight lang="perl">sub dj_vector {
my($end) = @_;
return @{([],[],[2],[2,3],[2,3])[$end]} if $end <= 4;
Line 8,994 ⟶ 14,744:
do { push @primes, 2*$_+1 if !vec($sieve,$_,1) } for (1..int(($end-1)/2));
@primes;
}</langsyntaxhighlight>
 
===Odds only, using strings for best performance===
Compared to array versions, about 2x faster (with 5.16.0 or later) and lower memory. Much faster than the experimental versions below. It's possible a mod-6 or mod-30 wheel could give more improvement, though possibly with obfuscation. The best next step for performance and functionality would be segmenting.
<langsyntaxhighlight lang="perl">sub string_sieve {
my ($n, $i, $s, $d, @primes) = (shift, 7);
 
Line 9,013 ⟶ 14,763:
push @primes, pos while m/0/g;
@primes;
}</langsyntaxhighlight>
 
This older version uses half the memory, but at the expense of a bit of speed and code complexity:
<langsyntaxhighlight lang="perl">sub dj_string {
my($end) = @_;
return @{([],[],[2],[2,3],[2,3])[$end]} if $end <= 4;
Line 9,037 ⟶ 14,787:
push @primes, 2*pos($sieve)-1 while $sieve =~ m/0/g;
@primes;
}</langsyntaxhighlight>
 
===Experimental===
Line 9,043 ⟶ 14,793:
 
Golfing a bit, at the expense of speed:
<langsyntaxhighlight lang="perl">sub sieve{ my (@s, $i);
grep { not $s[ $i = $_ ] and do
{ $s[ $i += $_ ]++ while $i <= $_[0]; 1 }
Line 9,049 ⟶ 14,799:
}
 
print join ", " => sieve 100;</langsyntaxhighlight>
 
Or with bit strings (much slower than the vector version above):
<langsyntaxhighlight lang="perl">sub sieve{ my ($s, $i);
grep { not vec $s, $i = $_, 1 and do
{ (vec $s, $i += $_, 1) = 1 while $i <= $_[0]; 1 }
Line 9,058 ⟶ 14,808:
}
 
print join ", " => sieve 100;</langsyntaxhighlight>
 
A short recursive version:
<langsyntaxhighlight lang="perl">sub erat {
my $p = shift;
return $p, $p**2 > $_[$#_] ? @_ : erat(grep $_%$p, @_)
}
 
print join ', ' => erat 2..100000;</langsyntaxhighlight>
 
Regexp (purely an example -- the regex engine limits it to only 32769):<langsyntaxhighlight lang="perl">sub sieve {
my ($s, $p) = "." . ("x" x shift);
 
Line 9,079 ⟶ 14,829:
}
 
print sieve(1000);</langsyntaxhighlight>
 
===Extensible sieves===
 
Here are two incremental versions, which allows one to create a tied array of primes:
<langsyntaxhighlight lang="perl">use strict;
use warnings;
package Tie::SieveOfEratosthenes;
Line 9,189 ⟶ 14,939:
}
 
1;</langsyntaxhighlight>
This one is based on the vector sieve shown earlier, but adds to a list as needed, just sieving in the segment. Slightly faster and half the memory vs. the previous incremental sieve. It uses the same API -- arguably we should be offset by one so $primes[$n] returns the $n'th prime.
<langsyntaxhighlight lang="perl">use strict;
use warnings;
package Tie::SieveOfEratosthenes;
Line 9,244 ⟶ 14,994:
}
 
1;</langsyntaxhighlight>
 
=={{header|Perl 6Phix}}==
{{Trans|Euphoria}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">constant</span> <span style="color: #000000;">limit</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1000</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">primes</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">flags</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">limit</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">limit</span><span style="color: #0000FF;">))</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">flags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">i</span><span style="color: #0000FF;">*</span><span style="color: #000000;">i</span> <span style="color: #008080;">to</span> <span style="color: #000000;">limit</span> <span style="color: #008080;">by</span> <span style="color: #000000;">i</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">flags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">limit</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">flags</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">primes</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">i</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">primes</span><span style="color: #0000FF;">,{</span><span style="color: #004600;">pp_Maxlen</span><span style="color: #0000FF;">,</span><span style="color: #000000;">77</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
{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,
101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,
193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,
293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,
409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,
521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,
641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,
757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,
881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997}
</pre>
See also [[Sexy_primes#Phix]] where the sieve is more useful than a list of primes.<br>
Most applications should use the builtins, eg <code>get_primes(-get_maxprime(1000*1000))</code> or <code>get_primes_le(1000)</code> both give exactly the same output as above.
 
=={{header|Phixmonti}}==
<lang perl6>sub sieve( Int $limit ) {
<syntaxhighlight lang="phixmonti">include ..\Utilitys.pmt
my @is-prime = False, False, slip True xx $limit - 1;
 
def sequence /# ( ini end [step] ) #/
gather for @is-prime.kv -> $number, $is-prime {
( ) swap for if0 $is-primeput {endfor
enddef
take $number;
loop (my $s = $number**2; $s <= $limit; $s += $number) {
@is-prime[$s] = False;
}
}
}
}
 
1000 var limit
(sieve 100).join(",").say;</lang>
 
( 1 limit ) sequence
=== A set-based approach ===
 
( 2 limit ) for >ps
More or less the same as the first Python example:
( tps dup * limit tps ) for
<lang perl6>sub eratsieve($n) {
dup limit < if 0 swap set else drop endif
# Requires n(1 - 1/(log(n-1))) storage
endfor
my $multiples = set();
cps
gather for 2..$n -> $i {
endfor
unless $i (&) $multiples { # is subset
( 1 limit 0 ) remove
take $i;
pstack</syntaxhighlight>
$multiples (+)= set($i**2, *+$i ... (* > $n)); # union
}
}
}
 
Another solution
say flat eratsieve(100);</lang>
<syntaxhighlight lang="phixmonti">include ..\Utilitys.pmt
This gives:
1000
 
( "Primes in " over ": " ) lprint
(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)
 
2 swap 2 tolist for >ps
=== Using a chain of filters ===
2
dup tps < while
tps over mod 0 == if false else 1 + true endif
over tps < and
endwhile
tps < ps> swap if drop endif
endfor
 
pstack</syntaxhighlight>
{{incorrect|Perl6|This version uses modulo (division) testing and so is a trial division algorithm, not a sieve of Eratosthenes.}}
{{out}}
<pre>Primes in 1000:
[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, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
 
=== Press any key to exit ===</pre>
<lang perl6>sub primes ( UInt $n ) {
gather {
# create an iterator from 2 to $n (inclusive)
my $iterator := (2..$n).iterator;
 
loop {
# If it passed all of the filters it must be prime
my $prime := $iterator.pull-one;
# unless it is actually the end of the sequence
last if $prime =:= IterationEnd;
 
take $prime; # add the prime to the `gather` sequence
 
# filter out the factors of the current prime
$iterator := Seq.new($iterator).grep(* % $prime).iterator;
# (2..*).grep(* % 2).grep(* % 3).grep(* % 5).grep(* % 7)…
}
}
}
 
put primes( 100 );</lang>
Which prints
 
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
 
=={{header|Phix}}==
{{Trans|Euphoria}}
<lang Phix>constant limit = 1000
sequence primes = {}
sequence flags = repeat(1, limit)
for i=2 to floor(sqrt(limit)) do
if flags[i] then
for k=i*i to limit by i do
flags[k] = 0
end for
end if
end for
for i=2 to limit do
if flags[i] then
primes &= i
end if
end for
? primes</lang>
{{out}}
<pre>
{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,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,
179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,
373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,
587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,
809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997}
</pre>
See also [[Sexy_primes#Phix]] where the sieve is more useful than a list of primes, and [[Extensible_prime_generator#Phix]] for
a more memory efficient and therefore often faster and more appropriate method.
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php">
function iprimes_upto($limit)
{
Line 9,362 ⟶ 15,096:
return $primes;
}
</lang>
 
echo wordwrap(
'Primes less or equal than 1000 are : ' . PHP_EOL .
implode(' ', array_keys(iprimes_upto(1000), true, true)),
100
);
</syntaxhighlight>
 
{{out}}
<pre>Primes less or equal than 1000 are :
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 101 103 107 109 113 127 131
137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269
271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421
431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587
593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743
751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919
929 937 941 947 953 967 971 977 983 991 997</pre>
 
=={{header|Picat}}==
The SoE is provided in the standard library, defined as follows:
<syntaxhighlight lang="picat">
primes(N) = L =>
A = new_array(N),
foreach(I in 2..floor(sqrt(N)))
if (var(A[I])) then
foreach(J in I**2..I..N)
A[J]=0
end
end
end,
L=[I : I in 2..N, var(A[I])].
</syntaxhighlight>
{{Out}}
<pre>
Picat> L = math.primes(100).
L = [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]
yes
</pre>
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de sieve (N)
(let Sieve (range 1 N)
(set Sieve)
Line 9,372 ⟶ 15,142:
(for (S (nth Sieve (* I I)) S (nth (cdr S) I))
(set S) ) ) )
(filter bool Sieve) ) )</langsyntaxhighlight>
Output:
<pre>: (sieve 100)
-> (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)</pre>
===Alternate Version Using a 2x3x5x7 Wheel===
This works by destructively modifying the CDR of the previous cell when it finds a composite number. For sieving large sets (e.g. 1,000,000) it's much faster than the above.
<syntaxhighlight lang="picolisp">
(setq WHEEL-2357
(2 4 2 4 6 2 6 4
2 4 6 6 2 6 4 2
6 4 6 8 4 2 4 2
4 8 6 4 6 2 4 6
2 6 6 4 2 4 6 2
6 4 2 4 2 10 2 10 .))
 
(de roll2357wheel (Limit)
(let W WHEEL-2357
(make
(for (N 11 (<= N Limit) (+ N (pop 'W)))
(link N)))))
 
(de sqr (X) (* X X))
 
(de remove-multiples (L)
(let (N (car L) M (* N N) P L Q (cdr L))
(while Q
(let A (car Q)
(until (>= M A)
(setq M (+ M N)))
(when (= A M)
(con P (cdr Q))))
(setq P Q Q (cdr Q)))))
 
 
(de sieve (Limit)
(let Sieve (roll2357wheel Limit)
(for (P Sieve (<= (sqr (car P)) Limit) (cdr P))
(remove-multiples P))
(append (2 3 5 7) Sieve)))
</syntaxhighlight>
{{Out}}
<pre>
: (sieve 100)
-> (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)
: (filter '((N) (> N 900)) (sieve 1000))
-> (907 911 919 929 937 941 947 953 967 971 977 983 991 997)
: (last (sieve 1000000))
-> 999983
</pre>
 
=={{header|PL/I}}==
<langsyntaxhighlight lang="pli">eratos: proc options (main) reorder;
 
dcl i fixed bin (31);
Line 9,414 ⟶ 15,229:
end;
end;
end eratos;</langsyntaxhighlight>
 
=={{header|PL/M}}==
<syntaxhighlight lang="plm">100H:
 
DECLARE PRIME$MAX LITERALLY '5000';
 
/* CREATE SIEVE OF GIVEN SIZE */
MAKE$SIEVE: PROCEDURE(START, SIZE);
DECLARE (START, SIZE, M, N) ADDRESS;
DECLARE PRIME BASED START BYTE;
PRIME(0)=0; /* 0 AND 1 ARE NOT PRIMES */
PRIME(1)=0;
DO N=2 TO SIZE;
PRIME(N)=1; /* ASSUME ALL OTHERS ARE PRIME AT BEGINNING */
END;
DO N=2 TO SIZE;
IF PRIME(N) THEN DO; /* IF A NUMBER IS PRIME... */
DO M=N*N TO SIZE BY N;
PRIME(M) = 0; /* THEN ITS MULTIPLES ARE NOT */
END;
END;
END;
END MAKE$SIEVE;
 
/* CP/M CALLS */
BDOS: PROCEDURE(FUNC, ARG);
DECLARE FUNC BYTE, ARG ADDRESS;
GO TO 5;
END BDOS;
 
DECLARE BDOS$EXIT LITERALLY '0',
BDOS$PRINT LITERALLY '9';
 
/* PRINT A 16-BIT NUMBER */
PRINT$NUMBER: PROCEDURE(N);
DECLARE (N, P) ADDRESS;
DECLARE S (8) BYTE INITIAL ('.....',10,13,'$');
DECLARE C BASED P BYTE;
P = .S(5);
DIGIT:
P = P - 1;
C = (N MOD 10) + '0';
N = N / 10;
IF N > 0 THEN GO TO DIGIT;
CALL BDOS(BDOS$PRINT, P);
END PRINT$NUMBER;
 
/* PRINT ALL PRIMES UP TO N */
PRINT$PRIMES: PROCEDURE(N, SIEVE);
DECLARE (I, N, SIEVE) ADDRESS;
DECLARE PRIME BASED SIEVE BYTE;
CALL MAKE$SIEVE(SIEVE, N);
DO I = 2 TO N;
IF PRIME(I) THEN CALL PRINT$NUMBER(I);
END;
END PRINT$PRIMES;
 
CALL PRINT$PRIMES(PRIME$MAX, .MEMORY);
 
CALL BDOS(BDOS$EXIT, 0);
EOF</syntaxhighlight>
{{out}}
<pre>2
3
5
7
11
....
4967
4969
4973
4987
4999</pre>
 
=={{header|PL/SQL}}==
<syntaxhighlight lang="plsql">create or replace package sieve_of_eratosthenes as
type array_of_booleans is varray(100000000) of boolean;
type table_of_integers is table of integer;
function find_primes (n number) return table_of_integers pipelined;
end sieve_of_eratosthenes;
/
 
create or replace package body sieve_of_eratosthenes as
function find_primes (n number) return table_of_integers pipelined is
flag array_of_booleans;
ptr integer;
i integer;
begin
flag := array_of_booleans(false, true);
flag.extend(n - 2, 2);
ptr := 1;
<< outer_loop >>
while ptr * ptr <= n loop
while not flag(ptr) loop
ptr := ptr + 1;
end loop;
i := ptr * ptr;
while i <= n loop
flag(i) := false;
i := i + ptr;
end loop;
ptr := ptr + 1;
end loop outer_loop;
for i in 1 .. n loop
if flag(i) then
pipe row (i);
end if;
end loop;
return;
end find_primes;
end sieve_of_eratosthenes;
/</syntaxhighlight>
 
Usage:
 
<syntaxhighlight lang="sql">select column_value as prime_number
from table(sieve_of_eratosthenes.find_primes(30));
 
PRIME_NUMBER
------------
2
3
5
7
11
13
17
19
23
29
 
10 rows selected.
 
Elapsed: 00:00:00.01
 
select count(*) as number_of_primes, sum(column_value) as sum_of_primes
from table(sieve_of_eratosthenes.find_primes(1e7));
 
NUMBER_OF_PRIMES SUM_OF_PRIMES
---------------- ---------------
664579 3203324994356
 
Elapsed: 00:00:02.60</syntaxhighlight>
 
=={{header|Pony}}==
<langsyntaxhighlight lang="pony">use "time" // for testing
use "collections"
 
Line 9,475 ⟶ 15,435:
env.out.print("Found " + count.string() + " primes to " + limit.string() + ".")
env.out.print("This took " + elpsd.string() + " milliseconds.")
end</langsyntaxhighlight>
{{out}}
<pre>Primes to 100: 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
Line 9,492 ⟶ 15,452:
It is a waste not to do the trivial changes to the above code to sieve odds-only, which is about two and a half times faster due to the decreased number of culling operations; it doesn't really do much about the huge array problem though, other than to reduce it by a factor of two.
 
<langsyntaxhighlight lang="pony">use "time" // for testing
use "collections"
 
Line 9,551 ⟶ 15,511:
env.out.print("Found " + count.string() + " primes to " + limit.string() + ".")
env.out.print("This took " + elpsd.string() + " milliseconds.")
end</langsyntaxhighlight>
The output is the same as the above except that it is about two and a half times faster due to that many less culling operations.
 
Line 9,573 ⟶ 15,533:
===Basic procedure===
It outputs immediately so that the number can be used by the pipeline.
<langsyntaxhighlight PowerShelllang="powershell">function Sieve ( [int] $num )
{
$isprime = @{}
Line 9,584 ⟶ 15,544:
{ $isprime[$i] = $false }
}
}</langsyntaxhighlight>
===Another implementation===
<syntaxhighlight lang="powershell">
<lang PowerShell>
function eratosthenes ($n) {
if($n -ge 1){
Line 9,601 ⟶ 15,561:
1..$n | where{$prime[$_]}
} else {
Write-Warning "$n must be equal oris greaterless than 1"
}
}
"$(eratosthenes 100)"
</syntaxhighlight>
</lang>
<b>Output:</b>
<pre>
Line 9,612 ⟶ 15,572:
 
=={{header|Processing}}==
Calculate the primes up to 1000000 with Processing, including a visualisation of the process. As an additional visual effect, the layout of the pixel could be changed from the line-by-line layout to a spiral-like layout starting in the middle of the screen.
<langsyntaxhighlight lang="java">int maxx,maxyi=2;
int maxx;
int maxy;
int max;
boolean[] sieve;
 
void plot(int pos, boolean active) {
set(pos%maxx,pos/maxx, active?#000000:#ffffff);
}
void setup() {
size(1000, 1000, P2D);
// frameRate(2);
maxx=width;
maxy=height;
max=width*height;
sieve=new boolean[max+1];
 
sieve[1]=false;
plot(0, false);
plot(1, false);
for (int i=2; i<=max; i++) {
sieve[i]=true;
plot(i, true);
}
}
 
int i=2;
void draw() {
if (!sieve[i]) {
while (i*i<max && !sieve[i]) {
i++;
}
}
if (sieve[i]) {
print(i+" ");
for (int j=i*i; j<=max; j+=i) {
if (sieve[j]) {
sieve[j]=false;
plot(j, false);
}
}
}
if (i*i<max) {
i++;
} else {
Line 9,661 ⟶ 15,617:
println("finished");
}
}
}</lang>
 
void plot(int pos, boolean active) {
set(pos%maxx, pos/maxx, active?#000000:#ffffff);
}</syntaxhighlight>
 
As an additional visual effect, the layout of the pixel could be changed from the line-by-line layout to a spiral-like layout starting in the middle of the screen.
 
==={{header|Processing Python mode}}===
 
<syntaxhighlight lang="python">from __future__ import print_function
 
i = 2
 
def setup():
size(1000, 1000)
# frameRate(2)
global maxx, maxy, max_num, sieve
maxx = width
maxy = height
max_num = width * height
sieve = [False] * (max_num + 1)
 
sieve[1] = False
plot(0, False)
plot(1, False)
for i in range(2, max_num + 1):
sieve[i] = True
plot(i, True)
 
 
def draw():
global i
if not sieve[i]:
while (i * i < max_num and not sieve[i]):
i += 1
 
if sieve[i]:
print("{} ".format(i), end = '')
for j in range(i * i, max_num + 1, i):
if sieve[j]:
sieve[j] = False
plot(j, False)
 
if i * i < max_num:
i += 1
else:
noLoop()
println("finished")
 
 
def plot(pos, active):
set(pos % maxx, pos / maxx, color(0) if active else color(255))</syntaxhighlight>
 
=={{header|Prolog}}==
===Using lists===
====Basic bounded sieve====
<langsyntaxhighlight Prologlang="prolog">primes(N, L) :- numlist(2, N, Xs),
sieve(Xs, L).
 
Line 9,679 ⟶ 15,687:
; H3 is H2 + H,
( H1 =:= H2 -> filter(H, H3, T, R)
; filter(H, H3, [H1|T], R) ) ).</langsyntaxhighlight>
 
{{out}}
Line 9,694 ⟶ 15,702:
This is actually the Euler's variant of the sieve of Eratosthenes, generating (and thus removing) each multiple only once, though a sub-optimal implementation.
 
<langsyntaxhighlight Prologlang="prolog">primes(X, PS) :- X > 1, range(2, X, R), sieve(R, PS).
 
range(X, X, [X]) :- !.
Line 9,707 ⟶ 15,715:
remove( _, [], [] ) :- !.
remove( [H | X], [H | Y], R ) :- !, remove(X, Y, R).
remove( X, [H | Y], [H | R]) :- remove(X, Y, R). </langsyntaxhighlight>
 
Running in SWI Prolog,
Line 9,721 ⟶ 15,729:
We can stop early, with massive improvement in complexity (below ~ <i>n<sup>1.5</sup></i> inferences, empirically, vs. the ~ <i>n<sup>2</sup></i> of the above, in ''n'' primes produced; showing only the modified predicates):
 
<langsyntaxhighlight Prologlang="prolog">primes(X, PS) :- X > 1, range(2, X, R), sieve(X, R, PS).
 
sieve(X, [H | T], [H | T]) :- H*H > X, !.
sieve(X, [H | T], [H | S]) :- maplist( mult(H), [H | T], MS),
remove(MS, T, R), sieve(X, R, S).</langsyntaxhighlight>
 
{{out}}
Line 9,737 ⟶ 15,745:
Optimized by stopping early, traditional sieve of Eratosthenes generating multiples by iterated addition.
 
<langsyntaxhighlight Prologlang="prolog">primes(X, PS) :- X > 1, range(2, X, R), sieve(X, R, PS).
 
range(X, X, [X]) :- !.
Line 9,752 ⟶ 15,760:
remove( [H | X], [H | Y], R ) :- !, remove(X, Y, R).
remove( [H | X], [G | Y], R ) :- H < G, !, remove(X, [G | Y], R).
remove( X, [H | Y], [H | R]) :- remove(X, Y, R). </langsyntaxhighlight>
 
{{out}}
<pre> ?- time(( primes(7920,X), length(X,N) )).
% 140,654 inferences, 0.016 CPU in 0.011 seconds (142% CPU, 9016224 Lips)
X = [2, 3, 5, 7, 11, 13, 17, 19, 23|...],
N = 1000.
</pre>
 
====Sift the Two's and Sift the Three's====
Another version, based on Cloksin&Mellish p.175, modified to stop early as well as to work with odds only and use addition in the removing predicate, instead of the <code>mod</code> testing as the original was doing:
<syntaxhighlight lang="prolog">primes(N,[]):- N < 2, !.
primes(N,[2|R]):- ints(3,N,L), sift(N,L,R).
ints(A,B,[A|C]):- A=<B -> D is A+2, ints(D,B,C).
ints(_,_,[]).
sift(_,[],[]).
sift(N,[A|B],[A|C]):- A*A =< N -> rmv(A,B,D), sift(N,D,C)
; C=B.
rmv(A,B,D):- M is A*A, rmv(A,M,B,D).
rmv(_,_,[],[]).
rmv(P,M,[A|B],C):- ( M>A -> C=[A|D], rmv(P,M,B,D)
; M==A -> M2 is M+2*P, rmv(P,M2,B,C)
; M<A -> M2 is M+2*P, rmv(P,M2,[A|B],C)
).</syntaxhighlight>
 
Runs at about n^1.4 time empirically, producing 20,000 primes in 1.4 secs [https://swish.swi-prolog.org/p/modified_C&M_SoE.pl on the SWISH platform] as of 2021-11-26.
 
===Using lazy lists===
Line 9,767 ⟶ 15,793:
====Basic variant====
 
<langsyntaxhighlight lang="prolog">primes(PS):- count(2, 1, NS), sieve(NS, PS).
 
count(N, D, [N|T]):- freeze(T, (N2 is N+D, count(N2, D, T))).
Line 9,777 ⟶ 15,803:
remove([A|T],[B|S],R):- A < B -> remove(T,[B|S],R) ;
A=:=B -> remove(T,S,R) ;
R = [B|R2], freeze(R2, remove([A|T], S, R2)).</langsyntaxhighlight>
 
{{out}}
Line 9,789 ⟶ 15,815:
====Optimized by postponed removal====
Showing only changed predicates.
<langsyntaxhighlight lang="prolog">primes([2|PS]):-
freeze(PS, (primes(BPS), count(3, 1, NS), sieve(NS, BPS, 4, PS))).
 
Line 9,795 ⟶ 15,821:
N < Q -> PS = [N|PS2], freeze(PS2, sieve(NS, BPS, Q, PS2))
; BPS = [BP,BP2|BPS2], Q2 is BP2*BP2, count(Q, BP, MS),
remove(MS, NS, R), sieve(R, [BP2|BPS2], Q2, PS). </langsyntaxhighlight>
 
{{out}}
Line 9,816 ⟶ 15,842:
to record integers that are found to be composite.
 
<langsyntaxhighlight Prologlang="prolog">% %sieve( +N, -Primes ) is true if Primes is the list of consecutive primes
% that are less than or equal to N
sieve( N, [2|Rest]) :-
Line 9,851 ⟶ 15,877:
 
:- dynamic( composite/1 ).
</syntaxhighlight>
</lang>
The above has been tested with SWI-Prolog and gprolog.
 
<langsyntaxhighlight Prologlang="prolog">% SWI-Prolog:
 
?- time( (sieve(100000,P), length(P,N), writeln(N), last(P, LP), writeln(LP) )).
Line 9,861 ⟶ 15,887:
N = 9592,
LP = 99991.
</syntaxhighlight>
</lang>
 
==== Optimized approach====
[http://ideone.com/WDC7z Works with SWI-Prolog].
 
<langsyntaxhighlight Prologlang="prolog">sieve(N, [2|PS]) :- % PS is list of odd primes up to N
retractall(mult(_)),
sieve_O(3,N,PS).
Line 9,895 ⟶ 15,921:
:- dynamic( mult/1 ).
:- main(100000), main(1000000).</langsyntaxhighlight>
 
Running it produces
 
<langsyntaxhighlight Prologlang="prolog">%% stdout copy
[9592, 99991]
[78498, 999983]
Line 9,905 ⟶ 15,931:
%% stderr copy
% 293,176 inferences, 0.14 CPU in 0.14 seconds (101% CPU, 2094114 Lips)
% 3,122,303 inferences, 1.63 CPU in 1.67 seconds (97% CPU, 1915523 Lips)</langsyntaxhighlight>
 
which indicates <i>~ N<sup>1.1</sup></i> [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical orders of growth], which is consistent with the ''O(N log log N)'' theoretical runtime complexity.
Line 9,913 ⟶ 15,939:
Uses a ariority queue, from the paper "The Genuine Sieve of Eratosthenes" by Melissa O'Neill. Works with YAP (Yet Another Prolog)
 
<langsyntaxhighlight Prologlang="prolog">?- use_module(library(heaps)).
 
prime(2).
Line 9,938 ⟶ 15,964:
adjust_heap(H2, N, H).
adjust_heap(H, N, H) :-
\+ min_of_heap(H, N, _).</langsyntaxhighlight>
 
=={{header|PureBasic}}==
 
===Basic procedure===
<langsyntaxhighlight PureBasiclang="purebasic">For n=2 To Sqr(lim)
If Nums(n)=0
m=n*n
Line 9,951 ⟶ 15,977:
Wend
EndIf
Next n</langsyntaxhighlight>
 
===Working example===
<langsyntaxhighlight PureBasiclang="purebasic">Dim Nums.i(0)
Define l, n, m, lim
 
Line 9,990 ⟶ 16,016:
Print(#CRLF$+#CRLF$+"Press ENTER to exit"): Input()
CloseConsole()
EndIf</langsyntaxhighlight>
 
Output may look like;
Line 10,015 ⟶ 16,041:
avoids explicit iteration in the interpreter, giving a further speed improvement.
 
<langsyntaxhighlight lang="python">def eratosthenes2(n):
multiples = set()
for i in range(2, n+1):
Line 10,022 ⟶ 16,048:
multiples.update(range(i*i, n+1, i))
 
print(list(eratosthenes2(100)))</langsyntaxhighlight>
 
===Using array lookup===
The version below uses array lookup to test for primality. The function <tt>primes_upto()</tt> is a straightforward implementation of [http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Algorithm Sieve of Eratosthenes]algorithm. It returns prime numbers less than or equal to <tt>limit</tt>.
<langsyntaxhighlight lang="python">def primes_upto(limit):
is_prime = [False] * 2 + [True] * (limit - 1)
for n in range(int(limit**0.5 + 1.5)): # stop at ``sqrt(limit)``
Line 10,032 ⟶ 16,058:
for i in range(n*n, limit+1, n):
is_prime[i] = False
return [i for i, prime in enumerate(is_prime) if prime]</langsyntaxhighlight>
 
===Using generator===
The following code may be slightly slower than using the array/list as above, but uses no memory for output:
<langsyntaxhighlight lang="python">def iprimes_upto(limit):
is_prime = [False] * 2 + [True] * (limit - 1)
for n in xrange(int(limit**0.5 + 1.5)): # stop at ``sqrt(limit)``
Line 10,043 ⟶ 16,069:
is_prime[i] = False
for i in xrange(limit + 1):
if is_prime[i]: yield i</langsyntaxhighlight>{{out|Example}}<syntaxhighlight lang ="python">>>> list(iprimes_upto(15))
[2, 3, 5, 7, 11, 13]</langsyntaxhighlight>
 
===Odds-only version of the array sieve above===
The following code is faster than the above array version using only odd composite operations (for a factor of over two) and because it has been optimized to use slice operations for composite number culling to avoid extra work by the interpreter:
<langsyntaxhighlight lang="python">def primes2(limit):
if limit < 2: return []
if limit < 3: return [2]
Line 10,058 ⟶ 16,084:
s = p * (i + 1) + i
buf[s::p] = [False] * ((lmtbf - s) // p + 1)
return [2] + [i + i + 3 for i, v in enumerate(buf) if v]</langsyntaxhighlight>
 
Note that "range" needs to be changed to "xrange" for maximum speed with Python 2.
Line 10,065 ⟶ 16,091:
The following code is faster than the above generator version using only odd composite operations (for a factor of over two) and because it has been optimized to use slice operations for composite number culling to avoid extra work by the interpreter:
 
<langsyntaxhighlight lang="python">def iprimes2(limit):
yield 2
if limit < 3: return
Line 10,076 ⟶ 16,102:
buf[s::p] = [False] * ((lmtbf - s) // p + 1)
for i in range(lmtbf + 1):
if buf[i]: yield (i + i + 3)</langsyntaxhighlight>
 
Note that this version may actually run slightly faster than the equivalent array version with the advantage that the output doesn't require any memory.
Line 10,085 ⟶ 16,111:
This uses a 235 factorial wheel for further reductions in operations; the same techniques can be applied to the array version as well; it runs slightly faster and uses slightly less memory as compared to the odds-only algorithms:
 
<langsyntaxhighlight lang="python">def primes235(limit):
yield 2; yield 3; yield 5
if limit < 7: return
Line 10,104 ⟶ 16,130:
s += p * gaps[ci]; ci += 1
for i in range(lmtbf - 6 + (ndxs[(limit - 7) % 30])): # adjust for extras
if buf[i]: yield (30 * (i >> 3) + modPrms[i & 7])</langsyntaxhighlight>
 
Note: Much of the time (almost two thirds for this last case for Python 2.7.6) for any of these array/list or generator algorithms is used in the computation and enumeration of the final output in the last line(s), so any slight changes to those lines can greatly affect execution time. For Python 3 this enumeration is about twice as slow as Python 2 (Python 3.3 slow and 3.4 slower) for an even bigger percentage of time spent just outputting the results. This slow enumeration means that there is little advantage to versions that use even further wheel factorization, as the composite number culling is a small part of the time to enumerate the results.
Line 10,115 ⟶ 16,141:
{{libheader|NumPy}}
Below code adapted from [http://en.literateprograms.org/Sieve_of_Eratosthenes_(Python,_arrays)#simple_implementation literateprograms.org] using [http://numpy.scipy.org/ numpy]
<langsyntaxhighlight lang="python">import numpy
def primes_upto2(limit):
is_prime = numpy.ones(limit + 1, dtype=numpy.bool)
Line 10,121 ⟶ 16,147:
if is_prime[n]:
is_prime[n*n::n] = 0
return numpy.nonzero(is_prime)[0][2:]</langsyntaxhighlight>
'''Performance note:''' there is no point to add wheels here, due to execution of <tt>p[n*n::n] = 0</tt> and <tt>nonzero()</tt> takes us almost all time.
 
Line 10,128 ⟶ 16,154:
===Using wheels with numpy===
Version with wheel based optimization:
<langsyntaxhighlight lang="python">from numpy import array, bool_, multiply, nonzero, ones, put, resize
#
def makepattern(smallprimes):
Line 10,147 ⟶ 16,173:
if isprime[n]:
isprime[n*n::n] = 0
return nonzero(isprime)[0]</langsyntaxhighlight>
 
Examples:
<langsyntaxhighlight lang="python">>>> primes_upto3(10**6, smallprimes=(2,3)) # Wall time: 0.17
array([ 2, 3, 5, ..., 999961, 999979, 999983])
>>> primes_upto3(10**7, smallprimes=(2,3)) # Wall time: '''2.13'''
Line 10,161 ⟶ 16,187:
array([ 2, 3, 5, ..., 9999971, 9999973, 9999991])
>>> primes_upto3(10**7) # Wall time: '''1.30'''
array([ 2, 3, 5, ..., 9999971, 9999973, 9999991])</langsyntaxhighlight>
The above-mentioned examples demonstrate that the ''given'' wheel based optimization does not show significant performance gain.
 
Line 10,168 ⟶ 16,194:
 
{{works with|Python|2.6+, 3.x}}
<langsyntaxhighlight lang="python">import heapq
 
# generates all prime numbers
Line 10,195 ⟶ 16,221:
yield i
i += 1</langsyntaxhighlight>
Example:
<pre>
Line 10,216 ⟶ 16,242:
The adding of each discovered prime's incremental step info to the mapping should be '''''postponed''''' until the prime's ''square'' is seen amongst the candidate numbers, as it is useless before that point. This drastically reduces the space complexity from <i>O(n)</i> to <i>O(sqrt(n/log(n)))</i>, in ''<code>n</code>'' primes produced, and also lowers the run time complexity quite low ([http://ideone.com/VXep9F this test entry in Python 2.7] and [http://ideone.com/muuS4H this test entry in Python 3.x] shows about <i>~ n<sup>1.08</sup></i> [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirical order of growth] which is very close to the theoretical value of <i>O(n log(n) log(log(n)))</i>, in ''<code>n</code>'' primes produced):
{{works with|Python|2.6+, 3.x}}
<langsyntaxhighlight lang="python">def primes():
yield 2; yield 3; yield 5; yield 7;
bps = (p for p in primes()) # separate supply of "base" primes (b.p.)
Line 10,239 ⟶ 16,265:
import itertools
def primes_up_to(limit):
return list(itertools.takewhile(lambda p: p <= limit, primes()))</langsyntaxhighlight>
 
===Fast infinite generator using a wheel===
Although theoretically over three times faster than odds-only, the following code using a 2/3/5/7 wheel is only about 1.5 times faster than the above odds-only code due to the extra overheads in code complexity. The [http://ideone.com/LFaRnT test link for Python 2.7] and [http://ideone.com/ZAY0T2 test link for Python 3.x] show about the same empirical order of growth as the odds-only implementation above once the range grows enough so the dict operations become amortized to a constant factor.
{{works with|Python|2.6+, 3.x}}
<langsyntaxhighlight lang="python">def primes():
for p in [2,3,5,7]: yield p # base wheel primes
gaps1 = [ 2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,8 ]
Line 10,273 ⟶ 16,299:
if nni > 47: nni = 0
n += gaps[ni]; ni = nni # advance on the wheel
for p, pi in wheel_prime_pairs(): yield p # strip out indexes</langsyntaxhighlight>
 
Further gains of about 1.5 times in speed can be made using the same code by only changing the tables and a few constants for a further constant factor gain of about 1.5 times in speed by using a 2/3/5/7/11/13/17 wheel (with the gaps list 92160 elements long) computed for a slight constant overhead time as per the [http://ideone.com/4Ld26g test link for Python 2.7] and [http://ideone.com/72Dmyt test link for Python 3.x]. Further wheel factorization will not really be worth it as the gains will be small (if any and not losses) and the gaps table huge - it is already too big for efficient use by 32-bit Python 3 and the wheel should likely be stopped at 13:
<langsyntaxhighlight lang="python">def primes():
whlPrms = [2,3,5,7,11,13,17] # base wheel primes
for p in whlPrms: yield p
Line 10,316 ⟶ 16,342:
n += gaps[ni]; ni = nni # advance on the wheel
for p, pi in wheel_prime_pairs(): yield p # strip out indexes
</syntaxhighlight>
</lang>
 
 
===Iterative sieve on unbounded count from 2===
See [[Extensible_prime_generator#Python:_Iterative_sieve_on_unbounded_count_from_2| Extensible prime generator: Iterative sieve on unbounded count from 2]]
 
=={{header|Quackery}}==
<syntaxhighlight lang="quackery"> [ dup 1
[ 2dup > while
+ 1 >>
2dup / again ]
drop nip ] is sqrt ( n --> n )
[ stack [ 3 ~ ] constant ] is primes ( --> s )
( If a number is prime, the corresponding bit on the
number on the primes ancillary stack is set.
Initially all the bits are set except for 0 and 1,
which are not prime numbers by definition.
"eratosthenes" unsets all bits above those specified
by it's argument. )
[ bit ~
primes take & primes put ] is -composite ( n --> )
[ bit primes share & 0 != ] is isprime ( n --> b )
[ dup dup sqrt times
[ i^ 1+
dup isprime if
[ dup 2 **
[ dup -composite
over +
rot 2dup >
dip unrot until ]
drop ]
drop ]
drop
1+ bit 1 -
primes take &
primes put ] is eratosthenes ( n --> )
100 eratosthenes
100 times [ i^ isprime if [ i^ echo sp ] ]</syntaxhighlight>
 
'''Output:'''
 
<pre>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</pre>
 
=={{header|R}}==
<langsyntaxhighlight rlang="rsplus">sieve <- function(n) {
if (n < 2) returninteger(NULL0)
else {
a <- rep(T, n)
a[1] primes <- Frep(T, n)
primes[[1]] <- F
for(i in seq(n)) {
if for(a[i] in seq(sqrt(n))) {
j <- if(primes[[i]]) * i{
if primes[seq(ji >* i, n), return(which(a)i)] <- F
a[seq(j, n, by=i)] <- F}
}
which(primes)
}
}
 
sieve(1000)</langsyntaxhighlight>
 
{{out}}
<pre> [1] 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61
[19] 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151
[37] 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251
[55] 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359
[73] 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463
[91] 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593
[109] 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701
[127] 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827
[145] 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953
[163] 967 971 977 983 991 997</pre>
 
'''Alternate Odds-Only Version'''
 
<syntaxhighlight lang="rsplus">sieve <- function(n) {
if (n < 2) return(integer(0))
lmt <- (sqrt(n) - 1) / 2
sz <- (n - 1) / 2
buf <- rep(TRUE, sz)
for(i in seq(lmt)) {
if (buf[i]) {
buf[seq((i + i) * (i + 1), sz, by=(i + i + 1))] <- FALSE
}
}
cat(2, sep='')
for(i in seq(sz)) {
if (buf[i]) {
cat(" ", (i + i + 1), sep='')
}
}
}
 
sieve(1000)</syntaxhighlight>
 
{{out}}
<pre>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 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997</pre>
 
=={{header|Racket}}==
===Imperative versions===
Ugly imperative version:
<langsyntaxhighlight Racketlang="racket">#lang racket
 
(define (sieve n)
Line 10,353 ⟶ 16,461:
(reverse primes))
 
(sieve 100)</langsyntaxhighlight>
 
A little nicer, but still imperative:
<langsyntaxhighlight Racketlang="racket">#lang racket
(define (sieve n)
(define primes (make-vector (add1 n) #t))
Line 10,366 ⟶ 16,474:
#:when (vector-ref primes n))
n))
(sieve 100)</langsyntaxhighlight>
 
Imperative version using a bit vector:
<langsyntaxhighlight Racketlang="racket">#lang racket
(require data/bit-vector)
;; Returns a list of prime numbers up to natural number limit
Line 10,382 ⟶ 16,490:
(for/list ([i (bit-vector-length bv)] #:unless (bit-vector-ref bv i)) i))
(eratosthenes 100)
</syntaxhighlight>
</lang>
 
{{output}}
Line 10,391 ⟶ 16,499:
These examples use infinite lists (streams) to implement the sieve of Eratosthenes in a functional way, and producing all prime numbers. The following functions are used as a prefix for pieces of code that follow:
 
<langsyntaxhighlight Racketlang="racket">#lang lazy
(define (ints-from i d) (cons i (ints-from (+ i d) d)))
(define (after n l f)
Line 10,404 ⟶ 16,512:
(cond [(< x1 x2) (cons x1 (union (cdr l1) l2 ))]
[(> x1 x2) (cons x2 (union l1 (cdr l2)))]
[else (cons x1 (union (cdr l1) (cdr l2)))])))</langsyntaxhighlight>
 
==== Basic sieve ====
 
<langsyntaxhighlight Racketlang="racket">(define (sieve l)
(define x (car l))
(cons x (sieve (diff (cdr l) (ints-from (+ x x) x)))))
(define primes (sieve (ints-from 2 1)))
(!! (take 25 primes))</langsyntaxhighlight>
 
Runs at ~ n^2.1 [http://en.wikipedia.org/wiki/Analysis_of_algorithms#Empirical_orders_of_growth empirically], for ''n <= 1500'' primes produced.
Line 10,419 ⟶ 16,527:
Note that the first number, 2, and its multiples stream <code>(ints-from 4 2)</code> are handled separately to ensure that the non-primes list is never empty, which simplifies the code for <code>union</code> which assumes non-empty infinite lists.
 
<langsyntaxhighlight Racketlang="racket">(define (sieve l non-primes)
(let ([x (car l)] [np (car non-primes)])
(cond [(= x np) (sieve (cdr l) (cdr non-primes))] ; else x < np
[else (cons x (sieve (cdr l) (union (ints-from (* x x) x)
non-primes)))])))
(define primes (cons 2 (sieve (ints-from 3 1) (ints-from 4 2))))</langsyntaxhighlight>
 
==== Basic sieve Optimized with postponed processing ====
Since a prime's multiples that count start from its square, we should only start removing them when we reach that square.
<langsyntaxhighlight Racketlang="racket">(define (sieve l prs)
(define p (car prs))
(define q (* p p))
(after q l (λ(t) (sieve (diff t (ints-from q p)) (cdr prs)))))
(define primes (cons 2 (sieve (ints-from 3 1) primes)))</langsyntaxhighlight>
 
Runs at ~ n^1.4 up to n=10,000. The initial 2 in the self-referential primes definition is needed to prevent a "black hole".
Line 10,439 ⟶ 16,547:
Since prime's multiples that matter start from its square, we should only add them when we reach that square.
 
<langsyntaxhighlight Racketlang="racket">(define (composites l q primes)
(after q l
(λ(t)
Line 10,447 ⟶ 16,555:
(define primes (cons 2
(diff (ints-from 3 1)
(composites (ints-from 4 2) 9 (cdr primes)))))</langsyntaxhighlight>
 
==== Implementation of Richard Bird's algorithm ====
Line 10,453 ⟶ 16,561:
Appears in [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf M.O'Neill's paper]. Achieves on its own the proper postponement that is specifically arranged for in the version above (with <code>after</code>), and is yet more efficient, because it folds to the right and so builds the right-leaning structure of merges at run time, where the more frequently-producing streams of multiples appear <i>higher</i> in that structure, so the composite numbers produced by them have less <code>merge</code> nodes to percolate through:
 
<langsyntaxhighlight Racketlang="racket">(define primes
(cons 2 (diff (ints-from 3 1)
(foldr (λ(p r) (define q (* p p))
(cons q (union (ints-from (+ q p) p) r)))
'() primes))))</langsyntaxhighlight>
 
=== Using threads and channels ===
Line 10,463 ⟶ 16,571:
Same algorithm as [[#With merged composites|"merged composites" above]] (without the postponement optimization), but now using threads and channels to produce a channel of all prime numbers (similar to newsqueak). The macro at the top is a convenient wrapper around definitions of channels using a thread that feeds them.
 
<langsyntaxhighlight Racketlang="racket">#lang racket
(define-syntax (define-thread-loop stx)
(syntax-case stx ()
Line 10,489 ⟶ 16,597:
(out! x) (let loop () (out! (channel-get l)) (loop)))
(define primes (cons 2 (sieve (ints-from 3 1) (ints-from 4 2))))
(for/list ([i 25] [x (in-producer channel-get eof primes)]) x)</langsyntaxhighlight>
 
=== Using generators ===
Line 10,495 ⟶ 16,603:
Yet another variation of the same algorithm as above, this time using generators.
 
<langsyntaxhighlight Racketlang="racket">#lang racket
(require racket/generator)
(define (ints-from i d)
Line 10,515 ⟶ 16,623:
(define (cons x l) (generator () (yield x) (let loop () (yield (l)) (loop))))
(define primes (cons 2 (sieve (ints-from 3 1) (ints-from 4 2))))
(for/list ([i 25] [x (in-producer primes)]) x)</langsyntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
 
<syntaxhighlight lang="raku" line>sub sieve( Int $limit ) {
my @is-prime = False, False, slip True xx $limit - 1;
 
gather for @is-prime.kv -> $number, $is-prime {
if $is-prime {
take $number;
loop (my $s = $number**2; $s <= $limit; $s += $number) {
@is-prime[$s] = False;
}
}
}
}
 
(sieve 100).join(",").say;</syntaxhighlight>
 
=== A set-based approach ===
 
More or less the same as the first Python example:
<syntaxhighlight lang="raku" line>sub eratsieve($n) {
# Requires n(1 - 1/(log(n-1))) storage
my $multiples = set();
gather for 2..$n -> $i {
unless $i (&) $multiples { # is subset
take $i;
$multiples (+)= set($i**2, *+$i ... (* > $n)); # union
}
}
}
 
say flat eratsieve(100);</syntaxhighlight>
This gives:
 
(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)
 
=== Using a chain of filters ===
 
{{incorrect|Raku|This version uses modulo (division) testing and so is a trial division algorithm, not a sieve of Eratosthenes.}}
 
''Note: while this is "incorrect" by a strict interpretation of the rules, it is being left as an interesting example''
 
<syntaxhighlight lang="raku" line>sub primes ( UInt $n ) {
gather {
# create an iterator from 2 to $n (inclusive)
my $iterator := (2..$n).iterator;
 
loop {
# If it passed all of the filters it must be prime
my $prime := $iterator.pull-one;
# unless it is actually the end of the sequence
last if $prime =:= IterationEnd;
 
take $prime; # add the prime to the `gather` sequence
 
# filter out the factors of the current prime
$iterator := Seq.new($iterator).grep(* % $prime).iterator;
# (2..*).grep(* % 2).grep(* % 3).grep(* % 5).grep(* % 7)…
}
}
}
 
put primes( 100 );</syntaxhighlight>
Which prints
 
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
 
=={{header|RATFOR}}==
<syntaxhighlight lang="ratfor">
 
program prime
#
define(true,1)
define(false,0)
#
integer loop,loop2,limit,k,primes,count
integer isprime(1000)
 
limit = 1000
count = 0
 
for (loop=1; loop<=limit; loop=loop+1)
{
isprime(loop) = true
}
 
isprime(1) = false
 
for (loop=2; loop<=limit; loop=loop+1)
 
 
{
if (isprime(loop) == true)
{
count = count + 1
for (loop2=loop*loop; loop2 <= limit; loop2=loop2+loop)
{
isprime(loop2) = false
}
}
}
write(*,*)
write(*,101) count
 
101 format('There are ',I12,' primes.')
 
count = 0
for (loop=1; loop<=limit; loop=loop+1)
if (isprime(loop) == true)
{
Count = count + 1
write(*,'(I6,$)')loop
if (mod(count,10) == 0) write(*,*)
}
write(*,*)
 
end
</syntaxhighlight>
 
=={{header|Red}}==
<syntaxhighlight lang="red">
primes: function [n [integer!]][
poke prim: make bitset! n 1 true
r: 2 while [r * r <= n][
repeat q n / r - 1 [poke prim q + 1 * r true]
until [not pick prim r: r + 1]
]
collect [repeat i n [if not prim/:i [keep i]]]
]
 
primes 100
== [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]
</syntaxhighlight>
 
=={{header|Refal}}==
<syntaxhighlight lang="refal">$ENTRY Go {
= <Print <Primes 100>>;
};
 
Primes {
s.N = <Sieve <Iota 2 s.N>>;
};
 
Iota {
s.End s.End = s.End;
s.Start s.End = s.Start <Iota <+ 1 s.Start> s.End>;
};
 
Cross {
s.Step e.List = <Cross (s.Step 1) s.Step e.List>;
(s.Step s.Skip) = ;
(s.Step 1) s.Item e.List = X <Cross (s.Step s.Step) e.List>;
(s.Step s.N) s.Item e.List = s.Item <Cross (s.Step <- s.N 1>) e.List>;
};
 
Sieve {
= ;
X e.List = <Sieve e.List>;
s.N e.List = s.N <Sieve <Cross s.N e.List>>;
};</syntaxhighlight>
{{out}}
<pre>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</pre>
 
=={{header|REXX}}==
Line 10,523 ⟶ 16,795:
As the stemmed array gets heavily populated, the number of entries ''may'' slow down the REXX interpreter substantially,
<br>depending upon the efficacy of the hashing technique being used for REXX variables (setting/retrieving).
<langsyntaxhighlight REXXlang="rexx">/*REXX program generates and displays primes via the sieve of Eratosthenes algorithm.*/
parse arg H .; if H=='' | H=="," then H= 200 /*optain optional argument from the CL.*/
w= length(H); @prime= right('prime', 20) /*W: is used for aligning the output.*/
Line 10,534 ⟶ 16,806:
end /*j*/ /* ─── */
say /*stick a fork in it, we're all done. */
say right(#, 1+w+length(@prime) ) 'primes found up to and including ' H</langsyntaxhighlight>
'''output''' &nbsp; when using the input default of: &nbsp; <tt> 200 </tt>
<pre style="height:45ex">
Line 10,593 ⟶ 16,865:
 
Also added is a final message indicating the number of primes found.
<langsyntaxhighlight lang="rexx">/*REXX program generates primes via a wheeled sieve of Eratosthenes algorithm. */
parse arg H .; if H=='' then H=200 /*let the highest number be specified. */
tell=h>0; H=abs(H); w=length(H) /*a negative H suppresses prime listing*/
Line 10,616 ⟶ 16,888:
.: parse arg n; b=n%cw; r=n//cw+1;_=x2b(c2x(@.b));@.b=x2c(b2x(left(_,r-1)'1'substr(_,r+1)));return
s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1) /*pluralizer.*/
th: procedure; parse arg x; x=abs(x); return word('th st nd rd',1+x//10*(x//100%10\==1)*(x//10<4))</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the input default of: &nbsp; &nbsp; <tt> 200 </tt>}}
<pre style="height:45ex">
Line 10,678 ⟶ 16,950:
</pre>
{{out|output|text=&nbsp; when using the input of: &nbsp; &nbsp; <tt> -100000 </tt>}}
<pre>
9592 primes found up to and including 100000.
</pre>
Line 10,693 ⟶ 16,966:
 
It also uses a short-circuit test for striking out composites &nbsp; ≤ &nbsp; &radic;{{overline|&nbsp;target&nbsp;}}
<langsyntaxhighlight lang="rexx">/*REXX pgm generates and displays primes via a wheeled sieve of Eratosthenes algorithm. */
parse arg H .; if H=='' | H=="," then H= 200 /*obtain the optional argument from CL.*/
w= length(H); @prime= right('prime', 20) /*w: is used for aligning the output. */
Line 10,703 ⟶ 16,976:
#= # + 1 /*bump the prime number counter. */
say @prime right(#,w) " ───► " right(j,w) /*display the prime to the terminal. */
if ! then iterate /*shouldskip the top part of loop? be skipped ? ___ */
jj=if j * j>H then !=1 /*computeindicate theskip squaretop of J.part if J > H ___ */
if jj>H do then !m=1 j*j to H by j+j; @.m=; end /*indicatestrike skipodd topmultiples partas ifnot J > √ H prime. */
do m=jj to H by j+j; @.m=; end /*strike odd multiples as not prime. */
end /*j*/ /* ─── */
say /*stick a fork in it, we're all done. */
say right(#, 1 + w + length(@prime) ) 'primes found up to and including ' H</langsyntaxhighlight>
{{out|output|text=&nbsp; is identical to the first (non-wheel) version; &nbsp; program execution is over &nbsp; ''twice'' &nbsp; as fast.}}
 
Line 10,715 ⟶ 16,987:
 
===Wheel Version restructured===
<langsyntaxhighlight lang="rexx">/*REXX program generates primes via sieve of Eratosthenes algorithm.
* 21.07.2012 Walter Pachl derived from above Rexx version
* avoid symbols @ and # (not supported by ooRexx)
Line 10,743 ⟶ 17,015:
np=np+1
Say ' prime number' right(np,w) " --> " right(prime,w)
Return</langsyntaxhighlight>
'''output''' is mostly identical to the above versions.
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
limit = 100
sieve = list(limit)
Line 10,756 ⟶ 17,028:
if sieve[i] = 0 see "" + i + " " ok
next
</syntaxhighlight>
</lang>
Output:
<pre>
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
</pre>
 
=={{header|RPL}}==
This is a direct translation from Wikipedia. The variable <code>i</code> has been renamed <code>ii</code> to avoid confusion with the language constant <code>i</code>=√ -1
{{works with|Halcyon Calc|4.2.8}}
{| class="wikitable"
! RPL code
! Comment
|-
|
≪ → n
≪ { } n + 1 CON 'A' STO
2 n √ '''FOR''' ii
'''IF''' A ii GET '''THEN'''
ii SQ n '''FOR''' j
'A' j 0 PUT ii '''STEP'''
'''END'''
'''NEXT'''
{ }
2 n '''FOR''' ii '''IF''' A ii GET '''THEN''' ii + '''END NEXT'''
'A' PURGE
≫ ≫ '<span style="color:blue">SIEVE</span>' STO
|
<span style="color:blue">SIEVE</span> ''( n -- { prime_numbers } )''
let A be an array of Boolean values, indexed by 2 to n,
initially all set to true.
for i = 2, 3, 4, ..., not exceeding √n do
if A[i] is true
for j = i^2, i^2+i,... not exceeding n do
set A[j] := false
return all i such that A[i] is true.
|}
100 <span style="color:blue">SIEVE</span>
{{out}}
<pre>
1: { 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 }
</pre>
Latest RPL versions allow to remove some slow <code>FOR..NEXT</code> loops and use local variables only.
{{works with|HP|49}}
« 'X' DUP 1 4 PICK 1 SEQ DUP → n a seq123
« 2 n √ '''FOR''' ii
'''IF''' a ii GET '''THEN'''
ii SQ n '''FOR''' j
'a' j 0 PUT ii '''STEP'''
'''END'''
'''NEXT'''
a seq123 IFT TAIL
» » '<span style="color:blue">SIEVE</span>' STO
{{works with|HP|49}}
 
=={{header|Ruby}}==
''eratosthenes'' starts with <code>nums = [nil, nil, 2, 3, 4, 5, ..., n]</code>, then marks ( the nil setting ) multiples of <code>2, 3, 5, 7, ...</code> there, then returns all non-nil numbers which are the primes.
<langsyntaxhighlight lang="ruby">def eratosthenes(n)
nums = [nil, nil, *2..n]
(2..Math.sqrt(n)).each do |i|
Line 10,772 ⟶ 17,098:
end
p eratosthenes(100)</langsyntaxhighlight>
<pre>[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]</pre>
 
Line 10,783 ⟶ 17,109:
* Both inner loops skip multiples of 2 and 3.
 
<langsyntaxhighlight lang="ruby">def eratosthenes2(n)
# For odd i, if i is prime, nums[i >> 1] is true.
# Set false for all multiples of 3.
Line 10,825 ⟶ 17,151:
end
 
p eratosthenes2(100)</langsyntaxhighlight>
 
This simple benchmark compares ''eratosthenes'' with ''eratosthenes2''.
 
<langsyntaxhighlight lang="ruby">require 'benchmark'
Benchmark.bmbm {|x|
x.report("eratosthenes") { eratosthenes(1_000_000) }
x.report("eratosthenes2") { eratosthenes2(1_000_000) }
}</langsyntaxhighlight>
 
''eratosthenes2'' runs about 4 times faster than ''eratosthenes''.
Line 10,840 ⟶ 17,166:
[[MRI]] 1.9.x implements the sieve of Eratosthenes at file [http://redmine.ruby-lang.org/projects/ruby-19/repository/entry/lib/prime.rb prime.rb], <code>class EratosthensesSeive</code> (around [http://redmine.ruby-lang.org/projects/ruby-19/repository/entry/lib/prime.rb#L421 line 421]). This implementation optimizes for space, by packing the booleans into 16-bit integers. It also hardcodes all primes less than 256.
 
<langsyntaxhighlight lang="ruby">require 'prime'
p Prime::EratosthenesGenerator.new.take_while {|i| i <= 100}</langsyntaxhighlight>
 
=={{header|Run BASIC}}==
<langsyntaxhighlight lang="runbasic">input "Gimme the limit:"; limit
dim flags(limit)
for i = 2 to limit
Line 10,851 ⟶ 17,177:
next k
if flags(i) = 0 then print i;", ";
next i</langsyntaxhighlight>
<pre>Gimme the limit:?100
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, </pre>
Line 10,857 ⟶ 17,183:
=={{header|Rust}}==
[[Category:Rust]]
 
===Unboxed Iterator===
 
A slightly more idiomatic, optimized and modern iterator output example.
 
<syntaxhighlight lang="rust">fn primes(n: usize) -> impl Iterator<Item = usize> {
const START: usize = 2;
if n < START {
Vec::new()
} else {
let mut is_prime = vec![true; n + 1 - START];
let limit = (n as f64).sqrt() as usize;
for i in START..limit + 1 {
let mut it = is_prime[i - START..].iter_mut().step_by(i);
if let Some(true) = it.next() {
it.for_each(|x| *x = false);
}
}
is_prime
}
.into_iter()
.enumerate()
.filter_map(|(e, b)| if b { Some(e + START) } else { None })
}</syntaxhighlight>
 
Notes:
# Starting at an offset of 2 means that an <code>n < 2</code> input requires zero allocations, because <code>Vec::new()</code> doesn't allocate memory until elements are pushed into it.
# Using <code>Vec</code> as an output to the <code>if .. {} else {}</code> condition means the output is statically deterministic, avoiding the need for a boxed trait object.
# Iterating <code>is_prime</code> with <code>.iter_mut()</code> and then using <code>.step_by(i)</code> makes all the optimizations required, and removes a lot of tediousness.
# Returning <code>impl Iterator</code> allows for static dispatching instead of dynamic dispatching, which is possible because the type is now statically known at compile time, making the zero input/output condition an order of magnitude faster.
 
 
===Sieve of Eratosthenes - No optimization===
<langsyntaxhighlight lang="rust">fn simple_sieve(limit: usize) -> Vec<usize> {
 
let mut is_prime = vec![true; limit+1];
Line 10,881 ⟶ 17,239:
fn main() {
println!("{:?}", simple_sieve(100));
}</langsyntaxhighlight>
{{out}}
<pre>[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]</pre>
Line 10,889 ⟶ 17,247:
The above code doesn't even do the basic optimizing of only culling composites by primes up to the square root of the range as allowed in the task; it also outputs a vector of resulting primes, which consumes memory. The following code fixes both of those, outputting the results as an Iterator:
 
<langsyntaxhighlight lang="rust">use std::iter::{empty, once};
use std::time::Instant;
 
Line 10,933 ⟶ 17,291:
let dur = secs * 1000 + millis;
println!("Culling composites took {} milliseconds.", dur);
}</langsyntaxhighlight>
{{output}}
<pre>[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]
Line 10,945 ⟶ 17,303:
The following code improves the above code by sieving only odd composite numbers as 2 is the only even prime for a reduction in number of operations by a factor of about two and a half with reduction of memory use by a factor of two, and bit-packs the composite sieving array for a further reduction of memory use by a factor of eight and with some saving in time due to better CPU cache use for a given sieving range; it also demonstrates how to eliminate the redundant array bounds check:
 
<langsyntaxhighlight lang="rust">fn optimized_sieve(limit: usize) -> Box<Iterator<Item = usize>> {
if limit < 3 {
return if limit < 2 { Box::new(empty()) } else { Box::new(once(2)) }
Line 10,975 ⟶ 17,333:
Some((i + i + 3) as usize) } else { None } }
}))
}</langsyntaxhighlight>
 
The above function can be used just by substituting "optimized_sieve" for "basic_sieve" in the previous "main" function, and the outputs are the same except that the time is only 1584 milliseconds, or about three times as fast.
Line 10,985 ⟶ 17,343:
While that above code is quite fast, as the range increases above the 10's of millions it begins to lose efficiency due to loss of CPU cache associativity as the size of the one-large-array used for culling composites grows beyond the limits of the various CPU caches. Accordingly the following page-segmented code where each culling page can be limited to not larger than the L1 CPU cache is about four times faster than the above for the range of one billion:
 
<langsyntaxhighlight lang="rust">use std::iter::{empty, once};
use std::rc::Rc;
use std::cell::RefCell;
Line 11,159 ⟶ 17,517:
let dur = secs * 1000 + millis;
println!("Culling composites took {} milliseconds.", dur);
}</langsyntaxhighlight>
 
The output is about the same as the previous codes except much faster; as well as cache size improvements mentioned above, it has a population count primes counting function that is able to determine the number of found primes about twice as fast as using the Iterator count() method (commented out and labelled as "the slow way" in the main function).
Line 11,170 ⟶ 17,528:
 
The above code demonstrates some techniques to work within the limitations of Rust's ownership/borrowing/lifetime memory model as it: 1) uses a recursive secondary base primes Iterator made persistent by using a Vec that uses its own value as a source of its own page stream, 2) this is done by using a recursive variable that accessed as a Rc reference counted heap value with internal mutability by a pair of RefCell's, 3) note that the above secondary stream is not thread safe and needs to have the Rc changed to an Arc, the RefCell's changed to Mutex'es or (probably preferably RwLock's that enclose/lock all reading and writing operations in the secondary stream "Bpsi"'s next() method, and 4) the use of Iterators where their performance doesn't matter (at the page level) while using tight loops at more inner levels.
 
=={{header|SAS}}==
The following defines an IML routine to compute the sieve, and as an example stores the primes below 1000 in a dataset.
 
<lang>proc iml;
start sieve(n);
a = J(n,1);
a[1] = 0;
do i = 1 to n;
if a[i] then do;
if i*i>n then return(a);
a[i*(i:int(n/i))] = 0;
end;
end;
finish;
 
a = loc(sieve(1000))`;
create primes from a;
append from a;
close primes;
quit;</lang>
 
=={{header|SASL}}==
{{incorrect|SASL|These use REM (division) testing and so are Trial Division algorithms, not Sieve of Eratosthenes.}}
Copied from SASL manual, top of page 36. This provides an infinite list.
<lang SASL>
show primes
WHERE
primes = sieve (2...)
sieve (p : x ) = p : sieve {a <- x; a REM p > 0}
?
</lang>
 
The limited list for the first 1000 numbers
<lang SASL>
show primes
WHERE
primes = sieve (2..1000)
sieve (p : x ) = p : sieve {a <- x; a REM p > 0}
?
</lang>
 
=={{header|S-BASIC}}==
<langsyntaxhighlight lang="basic">
comment
Find primes up to the specified limit (here 1,000) using
Line 11,241 ⟶ 17,558:
next i
 
rem - write out primes 810 per line
count = 0
col = 1
Line 11,247 ⟶ 17,564:
if flags(i) = true then
begin
print using "#####";i;
count = count + 1
col = col + 1
if col > 810 then
begin
print
Line 11,261 ⟶ 17,578:
 
end
</syntaxhighlight>
</lang>
{{out}}
<pre>
Finding primes from 2 to 1000
2 3 5 7 11 13 17 19 23 29
31 37 41 43 47 53 59 61 67 71
. . .
877 881 883 887 907 911 919 929 937 941
947 953 967 971 977 983 991 997
168 primes were found.
</pre>
 
=={{header|SAS}}==
The following defines an IML routine to compute the sieve, and as an example stores the primes below 1000 in a dataset.
 
<syntaxhighlight lang="text">proc iml;
start sieve(n);
a = J(n,1);
a[1] = 0;
do i = 1 to n;
if a[i] then do;
if i*i>n then return(a);
a[i*(i:int(n/i))] = 0;
end;
end;
finish;
 
a = loc(sieve(1000))`;
create primes from a;
append from a;
close primes;
quit;</syntaxhighlight>
 
=={{header|SASL}}==
{{incorrect|SASL|These use REM (division) testing and so are Trial Division algorithms, not Sieve of Eratosthenes.}}
Copied from SASL manual, top of page 36. This provides an infinite list.
<syntaxhighlight lang="sasl">
show primes
WHERE
primes = sieve (2...)
sieve (p : x ) = p : sieve {a <- x; a REM p > 0}
?
</syntaxhighlight>
 
The limited list for the first 1000 numbers
<syntaxhighlight lang="sasl">
show primes
WHERE
primes = sieve (2..1000)
sieve (p : x ) = p : sieve {a <- x; a REM p > 0}
?
</syntaxhighlight>
 
=={{header|Scala}}==
 
=== Genuine Eratosthenes sieve===
<langsyntaxhighlight Scalalang="scala">import scala.annotation.tailrec
import scala.collection.parallel.mutable
import scala.compat.Platform
Line 11,287 ⟶ 17,655:
assert(sieveOfEratosthenes(15099480).size == 976729)
println(s"Successfully completed without errors. [total ${Platform.currentTime - executionStart} ms]")
}</langsyntaxhighlight>
 
{{out}}
Line 11,298 ⟶ 17,666:
The following [['''odds-only''']] code is written in a very concise functional style (no mutable state other than the contents of the composites buffer and "higher order functions" for clarity), in this case using a Scala mutable BitSet:
 
<langsyntaxhighlight Scalalang="scala">object SoEwithBitSet {
def makeSoE_PrimesTo(top: Int): Iterator[Int] = {
val topNdx = (top - 3) / 2 //odds composite BitSet buffer offset down to 3
Line 11,306 ⟶ 17,674:
(0 to (Math.sqrt(top).toInt - 3) / 2).filterNot { cmpsts }.foreach { cullPrmCmpsts }
Iterator.single(2) ++ (0 to topNdx).filterNot { cmpsts }.map { pi => pi + pi + 3 } }
}</langsyntaxhighlight>
 
In spite of being very concise, it is very much faster than the above code converted to odds-only due to the use of the BitSet instead of the hash table based Set (or ParSet), taking only a few seconds to enumerate the primes to 100 million as compared to the 10's of seconds to count the primes to above 15 million above.
Line 11,313 ⟶ 17,681:
The below [['''odds-only''']] code using a primitive array (bit packed) and tail recursion to avoid some of the enumeration delays due to nested complex "higher order" function calls is almost eight times faster than the above more functional code:
 
<langsyntaxhighlight Scalalang="scala">object SoEwithArray {
def makeSoE_PrimesTo(top: Int) = {
import scala.annotation.tailrec
Line 11,340 ⟶ 17,708:
Iterator.single(2) ++ Iterator.iterate(3)(p => getNxtPrmFrom(((p + 2) - 3) >>> 1)).takeWhile(_ <= top)
}
}</langsyntaxhighlight>
 
It can be tested with the following code:
 
<langsyntaxhighlight Scalalang="scala">object Main extends App {
import SoEwithArray._
val top_num = 100000000
Line 11,353 ⟶ 17,721:
println(f"Found $count primes up to $top_num" + ".")
println("Using one large mutable Array and tail recursive loops.")
}</langsyntaxhighlight>
 
To produce the following output:
Line 11,365 ⟶ 17,733:
The above code still uses an amount of memory proportional to the range of the sieve (although bit-packed as 8 values per byte). As well as only sieving odd candidates, the following code uses a fixed range buffer that is about the size of the CPU L2 cache plus only storage for the base primes up to the square root of the range for a large potential saving in RAM memory used as well as greatly reducing memory access times. The use of innermost tail recursive loops for critical loops where the majority of the execution time is spent rather than "higher order" functions from iterators also greatly reduces execution time, with much of the remaining time used just to enumerate the primes output:
 
<langsyntaxhighlight Scalalang="scala">object APFSoEPagedOdds {
import scala.annotation.tailrec
Line 11,456 ⟶ 17,824:
val (cnt, nlwp) = gen.next(); val nacc = acc + cnt
if (nlwp <= top) takeUpto(nacc) else nacc }; takeUpto(1) }
}</langsyntaxhighlight>
 
As the above and all following sieves are "infinite", they all require an extra range limiting condition to produce a finite output, such as the addition of ".takeWhile(_ <= topLimit)" where "topLimit" is the specified range as is done in the following code:
 
<langsyntaxhighlight Scalalang="scala">object MainSoEPagedOdds extends App {
import APFSoEPagedOdds._
countSoEPrimesTo(100)
Line 11,469 ⟶ 17,837:
val elpsd = System.currentTimeMillis() - strt
println(f"Found $cnt primes up to $top in $elpsd milliseconds.")
}</langsyntaxhighlight>
 
which outputs the following:
Line 11,486 ⟶ 17,854:
The following code uses delayed recursion via Streams to implement the Richard Bird algorithm mentioned in the last part (the Epilogue) of [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf M.O'Neill's paper], which is '''a true incremental Sieve of Eratosthenes'''. It is nowhere near as fast as the array based solutions due to the overhead of functionally chasing the merging of the prime multiple streams; this also means that the empirical performance is not according to the usual Sieve of Eratosthenes approximations due to this overhead increasing as the log of the sieved range, but it is much better than [[Primality_by_trial_division#Odds-Only_.22infinite.22_primes_generator_using_Streams_and_Co-Inductive_Streams|the "unfaithful" sieve]].
 
<langsyntaxhighlight Scalalang="scala"> def birdPrimes() = {
def oddPrimes: Stream[Int] = {
def merge(xs: Stream[Int], ys: Stream[Int]): Stream[Int] = {
Line 11,507 ⟶ 17,875:
}
2 #:: oddPrimes
}</langsyntaxhighlight>
 
Now this algorithm doesn't really need the memoization and full laziness as offered by Streams, so an implementation and use of a Co-Inductive Stream (CIS) class is sufficient and reduces execution time by almost a factor of two:<langsyntaxhighlight lang="scala"> class CIS[A](val start: A, val continue: () => CIS[A])
 
def primesBirdCIS: Iterator[Int] = {
Line 11,541 ⟶ 17,909:
 
Iterator.single(2) ++ Iterator.iterate(oddPrimes())(_.continue()).map(_.start)
}</langsyntaxhighlight>
 
Further gains in performance for these last two implementations can be had by using further wheel factorization and "tree folding/merging" as per [http://www.haskell.org/haskellwiki/Primes#Tree_merging_with_Wheel this Haskell implementation].
Line 11,548 ⟶ 17,916:
As per [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf the "unfaithful sieve" article linked above], the incremental "infinite" Sieve of Eratosthenes can be implemented using a hash table instead of a Priority Queue or Map (Binary Heap) as were used in that article. The following implementation postpones the adding of base prime representations to the hash table until necessary to keep the hash table small:
 
<langsyntaxhighlight lang="scala"> def SoEInc: Iterator[Int] = {
val nextComposites = scala.collection.mutable.HashMap[Int, Int]()
def oddPrimes: Iterator[Int] = {
Line 11,572 ⟶ 17,940:
}
List(2, 3).toIterator ++ oddPrimes
}</langsyntaxhighlight>
 
The above could be implemented using Streams or Co-Inductive Streams to pass the continuation parameters as passed here in a tuple but there would be no real difference in speed and there is no need to use the implied laziness. As compared to the versions of the Bird (or tree folding) Sieve of Eratosthenes, this has the expected same computational complexity as the array based versions, but is about 20 times slower due to the constant overhead of processing the key value hashing. Memory use is quite low, only being the hash table entries for each of the base prime values less than the square root of the last prime enumerated multiplied by the size of each hash entry (about 12 bytes in this case) plus a "load factor" percentage overhead in hash table size to minimize hash collisions (about twice as large as entries actually used by default on average).
Line 11,583 ⟶ 17,951:
===Tail-recursive solution===
{{Works with|Scheme|R<math>^5</math>RS}}
<langsyntaxhighlight lang="scheme">; Tail-recursive solution :
(define (sieve n)
(define (aux u v)
Line 11,603 ⟶ 17,971:
; (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)
; > (length (sieve 10000000))
; 664579</langsyntaxhighlight>
 
===Simpler, non-tail-recursive solution===
<langsyntaxhighlight lang="scheme">; Simpler solution, with the penalty that none of 'iota, 'strike or 'sieve is tail-recursive :
(define (iota start stop stride)
(if (> start stop)
Line 11,628 ⟶ 17,996:
 
(display (primes 100))
(newline)</langsyntaxhighlight>
Output:
<syntaxhighlight lang="text">(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)</langsyntaxhighlight>
===Optimised using an odds-wheel===
Optimised using a pre-computed wheel based on 2 (i.e. odds only):
<langsyntaxhighlight lang="scheme">(define (primes-wheel-2 limit)
(let ((stop (sqrt limit)))
(define (sieve lst)
Line 11,643 ⟶ 18,011:
 
(display (primes-wheel-2 100))
(newline)</langsyntaxhighlight>
Output:
<syntaxhighlight lang="text">(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)</langsyntaxhighlight>
 
===Vector-based===
Vector-based (faster), works with R<math>^5</math>RS:
<langsyntaxhighlight lang="scheme">; initialize v to vector of sequential integers
(define (initialize! v)
(define (iter v n) (if (>= n (vector-length v))
Line 11,691 ⟶ 18,059:
(initialize! v)
(vector-set! v 1 0) ; 1 is not a prime
(remove zero? (vector->list (iter v 2)))))</langsyntaxhighlight>
 
===SICP-style streams===
Using SICP-style ''head''-forced streams. Works with MIT-Scheme, Chez Scheme, &ndash; or any other Scheme, if writing out by hand the expansion of the only macro here, <code>s-cons</code>, with explicit lambda. Common functions:
 
<langsyntaxhighlight lang="scheme"> ;;;; Stream Implementation
(define (head s) (car s))
(define (tail s) ((cdr s)))
Line 11,727 ⟶ 18,095:
((< h1 h2) (s-cons h1 (s-union (tail s1) s2 )))
((< h2 h1) (s-cons h2 (s-union s1 (tail s2))))
(else (s-cons h1 (s-union (tail s1) (tail s2)))))))</langsyntaxhighlight>
 
====The simplest, naive sieve====
Very slow, running at ~ <i>n<sup>2.2</sup></i>, empirically, and worsening:
<langsyntaxhighlight lang="scheme"> (define (sieve s)
(let ((p (head s)))
(s-cons p
(sieve (s-diff s (from-By p p))))))
(define primes (sieve (from-By 2 1)))</langsyntaxhighlight>
 
====Bounded, stopping early====
Stops at the square root of the upper limit ''m'', running at about ~ <i>n<sup>1.4</sup></i> in ''n'' primes produced, empirically. Returns infinite stream
of numbers which is only valid up to ''m'', includes composites above it:
<langsyntaxhighlight lang="scheme"> (define (primes-To m)
(define (sieve s)
(let ((p (head s)))
Line 11,747 ⟶ 18,115:
(sieve (s-diff (tail s)
(from-By (* p p) p))))))))
(sieve (from-By 2 1)))</langsyntaxhighlight>
 
====Combined multiples sieve====
Archetypal, straightforward approach by Richard Bird, presented in [http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf Melissa E. O'Neill article]. Uses <code>s-linear-join</code>, i.e. right fold, which is less efficient and of worse time complexity than the ''tree''-folding that follows. Does not attempt to conserve space by arranging for the additional inner feedback loop, as is done in the tree-folding variant below.
<langsyntaxhighlight lang="scheme"> (define (primes-stream-ala-Bird)
(define (mults p) (from-By (* p p) p))
(define primes ;; primes are
Line 11,762 ⟶ 18,130:
(s-cons (head (head sts))
(s-union (tail (head sts))
(s-linear-join (tail sts)))))</langsyntaxhighlight>
 
Here is a version of the same sieve, which is self contained with all the requisite functions wrapped in the overall function; optimized further. It works with odd primes only, and arranges for a separate primes feed for the base primes separate from the output stream, ''calculated recursively'' by the recursive call to "oddprms" in forming "cmpsts". It also ''"fuses"'' two functions, <code>s-diff</code> and <code>from-By</code>, into one, <code>minusstrtat</code>:
 
<langsyntaxhighlight lang="scheme">(define (birdPrimes)
(define (mltpls p)
(define pm2 (* p 2))
Line 11,788 ⟶ 18,156:
(define (cmpsts) (mrgmltpls (allmltpls (oddprms)))) ;; internal define's are mutually recursive
(define (oddprms) (cons 3 (lambda () (minusstrtat 5 (cmpsts)))))
(cons 2 (lambda () (oddprms))))</langsyntaxhighlight>
 
It can be tested with the following code:
 
<langsyntaxhighlight lang="scheme">(define (nthPrime n)
(let nxtprm ((cnt 0) (ps (birdPrimes)))
(if (< cnt n) (nxtprm (+ cnt 1) ((cdr ps))) (car ps))))
(nthPrime 1000000)</langsyntaxhighlight>
 
{{output}}
Line 11,805 ⟶ 18,173:
The most efficient. Finds composites as a tree of unions of each prime's multiples.
 
<langsyntaxhighlight lang="scheme"> ;;;; all primes' multiples are removed, merged through a tree of unions
;;;; runs in ~ n^1.15 run time in producing n = 100K .. 1M primes
(define (primes-stream)
Line 11,827 ⟶ 18,195:
(s-union (tail (head sts))
(head (tail sts))))
(pairs (tail (tail sts)))))</langsyntaxhighlight>
 
[http://ideone.com/Uuil5M Print 10 last primes] of the first thousand primes:
Line 11,837 ⟶ 18,205:
This can be also accomplished by the following self contained code which follows the format of the <code>birdPrimes</code> code above with the added "pairs" function integrated into the "mrgmltpls" function:
 
<langsyntaxhighlight lang="scheme">(define (treemergePrimes)
(define (mltpls p)
(define pm2 (* p 2))
Line 11,863 ⟶ 18,231:
(define (cmpsts) (mrgmltpls (allmltpls (oddprms)))) ;; internal define's are mutually recursive
(define (oddprms) (cons 3 (lambda () (minusstrtat 5 (cmpsts)))))
(cons 2 (lambda () (oddprms))))</langsyntaxhighlight>
 
It can be tested with the same code as the self-contained Richard Bird sieve, just by calling <code>treemergePrimes</code> instead of <code>birdPrimes</code>.
Line 11,869 ⟶ 18,237:
===Generators===
 
<langsyntaxhighlight lang="scheme">(define (integers n)
(lambda ()
(let ((ans n))
Line 11,893 ⟶ 18,261:
x)))
 
(define primes (sieve (integers 2))) </langsyntaxhighlight>
 
=={{header|Scilab}}==
<langsyntaxhighlight lang="scliab">function a = sieve(n)
a = ~zeros(n, 1)
a(1) = %f
Line 11,914 ⟶ 18,282:
 
sum(sieve(1000))
// 168, the number of primes below 1000</langsyntaxhighlight>
 
 
=={{header|Scratch}}==
<syntaxhighlight lang="scratch">
when clicked
broadcast: fill list with zero (0) and wait
broadcast: put one (1) in list of multiples and wait
broadcast: fill primes where zero (0 in list
 
when I receive: fill list with zero (0)
delete all of primes
delete all of list
set i to 0
set maximum to 25
repeat maximum
add 0 to list
change i by 1
{end repeat}
 
when I receive: put ones (1) in list of multiples
set S to sqrt of maximum
set i to 2
set k to 0
repeat S
change J by 1
set i to 2
repeat until i > 100
if not (i = J) then
if item i of list = 0 then
set m to (i mod J)
if (m = 0) then
replace item i of list with 1
{end repeat until}
change i by 1
set k to 1
delete all of primes
{end repeat}
set J to 1
 
when I receive: fill primes where zeros (0) in list
repeat maximum
if (item k of list) = 0 then
add k to primes
set k to (k + 1)
{end repeat}
</syntaxhighlight>
 
===Comments===
Scratch is a graphical drag and drop language designed to teach
children an introduction to programming. It has easy to use
multimedia and animation features. The code listed above was not
entered into the Scratch IDE but faithfully represents the graphical
code blocks used to run the sieve algorithm. The actual Scratch
graphical code blocks cannot be represented on this web site due
to its inability to directly represent graphical code. The actual code and output
can be seen or downloaded at an external URL web link:
 
[http://melellington.com/sieve/scratch-sieve-output.pdf Scratch Code and Output]
 
=={{header|Seed7}}==
The program below computes the number of primes between 1 and 10000000:
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const func set of integer: eratosthenes (in integer: n) is func
Line 11,940 ⟶ 18,366:
begin
writeln(card(eratosthenes(10000000)));
end func;</langsyntaxhighlight>
 
Original source: [http://seed7.sourceforge.net/algorith/math.htm#sieve_of_eratosthenes]
 
=={{header|SETL}}==
<syntaxhighlight lang="setl">program eratosthenes;
print(sieve 100);
 
op sieve(n);
numbers := [1..n];
numbers(1) := om;
loop for i in [2..floor sqrt n] do
loop for j in [i*i, i*i+i..n] do
numbers(j) := om;
end loop;
end loop;
return [n : n in numbers | n /= om];
end op;
end program;</syntaxhighlight>
{{out}}
<pre>[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]</pre>
 
=={{header|Sidef}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="ruby">func sieve(limit) {
var sieve_arr = [false, false, (limit-1).of(true)...]
gather {
Line 11,960 ⟶ 18,404:
}
 
say sieve(100).join(",")</langsyntaxhighlight>
{{out}}
<pre>
Line 11,967 ⟶ 18,411:
 
Alternative implementation:
<langsyntaxhighlight lang="ruby">func sieve(limit) {
var composite = []
for n in (2 .. limit.isqrt) {
Line 11,977 ⟶ 18,421:
}
 
say sieve(100).join(",")</langsyntaxhighlight>
 
=={{header|Simula}}==
{{works with|Simula-67}}
<langsyntaxhighlight lang="simula">BEGIN
INTEGER ARRAY t(0:1000);
INTEGER i,j,k;
Line 12,008 ⟶ 18,452:
OutInt(i,5); OutImage
END
END</langsyntaxhighlight>
{{out}}
<pre style="height:20ex"> 2
Line 12,032 ⟶ 18,476:
997</pre>
===A Concurrent Prime Sieve===
<langsyntaxhighlight lang="simula">
! A CONCURRENT PRIME SIEVE ;
 
Line 12,140 ⟶ 18,584:
END;
END;
</syntaxhighlight>
</lang>
Output:
<pre>
Line 12,189 ⟶ 18,633:
=={{header|Smalltalk}}==
A simple implementation that you can run in a workspace. It finds all the prime numbers up to and including <i>limit</i>—for the sake of example, up to and including 100.
<langsyntaxhighlight lang="smalltalk">| potentialPrimes limit |
limit := 100.
potentialPrimes := Array new: limit.
Line 12,204 ⟶ 18,648:
Transcript show: testNumber asString; cr
]
]</langsyntaxhighlight>
 
=={{header|SNOBOL4}}==
Line 12,210 ⟶ 18,654:
Using strings instead of arrays, and the square/sqrt optimizations.
 
<langsyntaxhighlight SNOBOL4lang="snobol4"> define('sieve(n)i,j,k,p,str,res') :(sieve_end)
sieve i = lt(i,n - 1) i + 1 :f(sv1)
str = str (i + 1) ' ' :(sieve)
Line 12,226 ⟶ 18,670:
* # Test and display
output = sieve(100)
end</langsyntaxhighlight>
 
Output:
<pre>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</pre>
 
=={{header|SparForte}}==
As a structured script.
<syntaxhighlight lang="ada">#!/usr/local/bin/spar
pragma annotate( summary, "sieve" );
pragma annotate( description, "The Sieve of Eratosthenes is a simple algorithm that" );
pragma annotate( description, "finds the prime numbers up to a given integer. Implement ");
pragma annotate( description, "this algorithm, with the only allowed optimization that" );
pragma annotate( description, "the outer loop can stop at the square root of the limit," );
pragma annotate( description, "and the inner loop may start at the square of the prime" );
pragma annotate( description, "just found. That means especially that you shouldn't" );
pragma annotate( description, "optimize by using pre-computed wheels, i.e. don't assume" );
pragma annotate( description, "you need only to cross out odd numbers (wheel based on" );
pragma annotate( description, "2), numbers equal to 1 or 5 modulo 6 (wheel based on 2" );
pragma annotate( description, "and 3), or similar wheels based on low primes." );
pragma annotate( see_also, "http://rosettacode.org/wiki/Sieve_of_Eratosthenes" );
pragma annotate( author, "Ken O. Burtch" );
pragma license( unrestricted );
 
pragma restriction( no_external_commands );
 
procedure sieve is
last_bool : constant positive := 20;
type bool_array is array(2..last_bool) of boolean;
a : bool_array;
test_num : positive;
-- limit : positive := positive(numerics.sqrt(float(arrays.last(a))));
 
-- n : positive := 2;
begin
for i in arrays.first(a)..last_bool loop
a(i) := true;
end loop;
 
for num in arrays.first(a)..last_bool loop
if a(num) then
test_num := num * num;
while test_num <= last_bool loop
a(test_num) := false;
test_num := @ + num;
end loop;
end if;
end loop;
for i in arrays.first(a)..last_bool loop
if a(i) then
put_line(i);
end if;
end loop;
end sieve;</syntaxhighlight>
 
=={{header|Standard ML}}==
Works with SML/NJ. This uses BitArrays which are available in SML/NJ. The algorithm is the one on wikipedia, referred to above. Limit: Memory, normally. When more than 20 petabyte of memory available, this code will have its limitation at a maximum integer around 1.44*10E17, due to the maximum list length in SMLNJ. Using two extra loops, however, bit arrays can simply be stored to disk and processed in multiple lists. With a tail recursive wrapper function as well, the upper limit will be determined by available disk space only.
<syntaxhighlight lang="standard ml">
val segmentedSieve = fn N =>
(* output : list of {segment=bit segment, start=number at startposition segment} *)
 
let
 
val NSegmt= 120000000; (* segment size *)
 
 
val inf2i = IntInf.toInt ;
val i2inf = IntInf.fromInt ;
val isInt = fn m => m <= IntInf.fromInt (valOf Int.maxInt);
 
val sweep = fn (bits, step, k, up) => (* strike off bits up to limit *)
(while ( !k < up andalso 0 <= !k ) do
( BitArray.clrBit( bits, !k ) ; k:= !k + step ; ()) ) handle Overflow => ()
 
val rec nextPrimebit = (* find next 1-bit within segment *)
fn Bits =>
fn pos =>
if pos+1 >= BitArray.length Bits
then NONE
else ( if BitArray.sub ( Bits,pos) then SOME (i2inf pos) else nextPrimebit Bits (pos+1) );
 
 
val sieveEratosthenes = fn n: int => (* Eratosthenes sieve , up to+incl n *)
 
let
val nums= BitArray.bits(n,[] );
val i=ref 2;
val k=ref (!i * (!i) -1);
 
in
 
( BitArray.complement nums;
BitArray.clrBit( nums, 0 );
while ( !k <n ) do ( if ( BitArray.sub (nums, !i - 1) ) then sweep (nums, !i, k, n) else ();
i:= !i+1;
k:= !i * (!i) - 1
);
[ { start= i2inf 1, segment=nums } ]
)
 
end;
 
 
 
val sieveThroughSegment =
 
fn ( primes : { segment:BitArray.array, start:IntInf.int } list, low : IntInf.int, up ) =>
(* second segment and on *)
let
val n = inf2i (up-low+1)
val nums = BitArray.bits(n,[] );
val itdone = low div i2inf NSegmt
 
val rec oldprimes = fn c => fn (* use segment B to sweep current one *)
[] => ()
| ctlist as {start=st,segment=B}::t =>
let
val nxt = nextPrimebit B c ;
val p = st + Option.getOpt( nxt,~10)
val modp = ( i2inf NSegmt * itdone ) mod p
val i = inf2i ( if( isInt( p - modp ) ) then p - modp else 0 ) (* i = 0 breaks off *)
val k = ref ( if Option.isSome nxt then (i - 1) else ~2 )
val step = if (isInt(p)) then inf2i(p) else valOf Int.maxInt (* !k+maxInt > n *)
 
in
( sweep (nums, step, k, n) ;
if ( p*p <= up andalso Option.isSome nxt )
then oldprimes ( inf2i (p-st+1) ) ctlist
else oldprimes 0 t (* next segment B *)
)
 
end
 
in
( BitArray.complement nums;
oldprimes 0 primes;
rev ( {start = low, segment = nums } :: rev (primes) )
)
end;
 
 
 
val rec workSegmentsDown = fn firstFn =>
fn nextFns =>
fn sizeSeg : int =>
fn upLimit : IntInf.int =>
let
val residual = upLimit mod i2inf sizeSeg
in
 
if ( upLimit <= i2inf sizeSeg ) then firstFn ( inf2i upLimit )
else
if ( residual > 0 ) then
nextFns ( workSegmentsDown firstFn nextFns sizeSeg (upLimit - residual ), upLimit - residual + 1, upLimit )
else
nextFns ( workSegmentsDown firstFn nextFns sizeSeg (upLimit - i2inf sizeSeg), upLimit - i2inf sizeSeg + 1, upLimit )
end;
 
in
 
workSegmentsDown sieveEratosthenes sieveThroughSegment NSegmt N
 
end;
</syntaxhighlight>
Example, segment size 120 million, prime numbers up to 2.5 billion:
<syntaxhighlight lang="standard ml">
-val writeSegment = fn L : {segment:BitArray.array, start:IntInf.int} list => fn NthSegment =>
let
val M=List.nth (L , NthSegment - 1 )
in
List.map (fn x=> x + #start M) (map IntInf.fromInt (BitArray.getBits ( #segment M)) )
end;
- val primesInBits = segmentedSieve 2500000000 ;
val primesInBits =
[{segment=-,start=1},{segment=-,start=120000001},
{segment=-,start=240000001},{segment=-,start=360000001},
{segment=-,start=480000001},.. <skipped> ,...]
: {segment:BitArray.array, start:IntInf.int} list
- writeSegment primesInBits 21 ;
val it =
[2400000011,2400000017,2400000023,2400000047,2400000061,2400000073,
2400000091,2400000103,2400000121,2400000133,2400000137,2400000157,...]
: IntInf.int list
- writeSegment primesInBits 1 ;
val it = [2,3,5,7,11,13,17,19,23,29,31,37,...] : IntInf.int list
 
 
</syntaxhighlight>
 
=={{header|Stata}}==
A program to create a dataset with a variable p containing primes up to a given number.
<langsyntaxhighlight lang="stata">prog def sieve
args n
clear
Line 12,252 ⟶ 18,884:
qui keep if a
drop a
end</langsyntaxhighlight>
 
Example call
<langsyntaxhighlight lang="stata">sieve 100
list in 1/10 // show only the first ten primes
 
Line 12,272 ⟶ 18,904:
9. | 23 |
10. | 29 |
+----+</langsyntaxhighlight>
 
=== Mata ===
 
<langsyntaxhighlight lang="stata">mata
real colvector sieve(real scalar n) {
real colvector a
Line 12,300 ⟶ 18,932:
4 | 7 |
+-----+
end</langsyntaxhighlight>
 
=={{header|Swift}}==
<langsyntaxhighlight lang="swift">import Foundation // for sqrt() and Date()
 
let max = 1_000_000
func primes(_ n: Int)
let maxroot = Int(sqrt(Double(max)))
-> UnfoldSequence<Int, (Int?, Bool)> {
let startingPoint = Date()
var sieve = Array<Bool>(repeating: true, count: n + 1)
 
let lim = Int(sqrt(Double(n)))
var isprime = [Bool](repeating: true, count: max+1 )
for i in 2...limmaxroot {
if sieveisprime[i] {
for notPrimek in stride(from: i*max/i, through: ni, by: i-1) {
sieve if isprime[notPrimek] = false{
isprime[i*k] = false }
}
}
}
}
 
var count = 0
return sequence(first: 2, next: { (p:Int) -> Int? in
for i in 2...max {
var np = p + 1
whileif np <= n && !sieveisprime[npi] { np += 1}
return np > n ?count nil+= : np1
})
}
print("\(count) primes found under \(max)")
 
print("\(startingPoint.timeIntervalSinceNow * -1) seconds")</syntaxhighlight>
let range = 100000000
 
print("The primes up to 100 are:")
primes(100).forEach { print($0, "", terminator: "") }
print()
 
print("Found \(primes(1000000).reduce(0) { (a, _) in a + 1 }) primes to 1000000.")
 
let start = NSDate()
var answr = primes(range).reduce(0) { (a, _) in a + 1 }
let elpsd = -start.timeIntervalSinceNow
 
print("Found \(answr) primes to \(range).")
 
print(String(format: "This test took %.3f milliseconds.", elpsd * 1000))</lang>
{{output}}
<pre>The78498 primes upfound tounder 100 are:1000000
0.01282501220703125 seconds</pre>
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
Found 78498 primes to 1000000.
Found 5761455 primes to 100000000.
This test took 5406.970 milliseconds.</pre>
 
iMac 3,2 GHz Intel Core i5
As can be seen, this is quite slow for larger ranges as 100 million here (run on a 1.92 Gigahertz Intel x5-Z8350 for about 1800 CPU clock cycles per prime).
 
'''Alternative odds-only version'''
 
The most obvious two improvements are to sieve for only odds as two is the only even prime and to make the sieving array bit-packed so that instead of a whole 8-bit byte per number representation there, each is represented by just one bit; these two changes improved memory use by a factor of 16 and the better CPU cache locality more than compensates for the extra code required to implement bit packing as per the following code:
<langsyntaxhighlight lang="swift">func soePackedOdds(_ n: Int) ->
LazyMapSequence<UnfoldSequence<Int, (Int?, Bool)>, Int> {
Line 12,374 ⟶ 18,991:
return ni > lmti ? nil : ni
}).lazy.map { $0 < 0 ? 2 : $0 + $0 + 3 }
}</langsyntaxhighlight>
 
the output for the same testing (with `soePackedOdds` substituted for `primes`) is the same except that it is about 1.5 times faster or only 1200 cycles per prime.
Line 12,383 ⟶ 19,000:
 
To use Swift's "higher order functions" on the generated `Sequence`'s effectively, one needs unbounded (or only by the numeric range chosen for the implementation) sieves. Many of these are incremental sieves that, instead of buffering a series of culled arrays, records the culling structure of the culling base primes (which should be a secondary stream of primes for efficiency) and produces the primes incrementally through reference and update of that structure. Various structures may be chosen for this, as in a MinHeap Priority Queue, a Hash Dictionary, or a simple List tree structure as used in the following code:
<langsyntaxhighlight lang="swift">import Foundation
 
func soeTreeFoldingOdds() -> UnfoldSequence<Int, (Int?, Bool)> {
Line 12,457 ⟶ 19,074:
print("Found \(answr) primes to \(range).")
 
print(String(format: "This test took %.3f milliseconds.", elpsd * 1000))</langsyntaxhighlight>
 
The output is the same as for the above except that it is much slower at about 56,000 CPU clock cycles per prime even just sieving to ten million due to the many memory allocations/de-allocations. It also has a O(n (log n) (log (log n))) asymptotic computational complexity (with the extra "log n" factor) that makes it slower with increasing range. This makes this algorithm only useful up to ranges of a few million although it is adequate to solve trivial problems such as Euler Problem 10 of summing all the primes to two million.
Line 12,466 ⟶ 19,083:
 
As the above code is slow due to memory allocations/de-allocations and the inherent extra "log n" term in the complexity, the following code uses a Hash Dictionary which has an average of O(1) access time (without the "log n" and uses mutability for increased seed so is in no way purely functional:
<langsyntaxhighlight lang="swift">func soeDictOdds() -> UnfoldSequence<Int, Int> {
var bp = 5; var q = 25
var bps: UnfoldSequence<Int, Int>.Iterator? = nil
Line 12,492 ⟶ 19,109:
defer { n += 2 }; return n
})
}</langsyntaxhighlight>
 
It can be substituted in the above code just by substituting the `soeDictOdds` in three places in the testing code with the same output other than it is over four times faster or about 12,500 CPU clock cycles per prime.
Line 12,499 ⟶ 19,116:
 
An unbounded array-based algorithm can be written that combines the excellent cache locality of the second bounded version above but is unbounded by producing a sequence of sieved bit-packed arrays that are CPU cache size as required with a secondary stream of base primes used in culling produced in the same fashion, as in the following code:
<langsyntaxhighlight lang="swift">import Foundation
 
typealias Prime = UInt64
Line 12,813 ⟶ 19,430:
print("Found \(answr) primes up to \(range).")
 
print(String(format: "This test took %.3f milliseconds.", elpsd * 1000))</langsyntaxhighlight>
{{output}}
<pre>The first 25 primes are:
Line 12,825 ⟶ 19,442:
 
=={{header|Tailspin}}==
<langsyntaxhighlight lang="tailspin">
templates sieve
def limit: $;
Line 12,831 ⟶ 19,448:
1 -> #
$@ !
 
when <..$@::length ?($@($) * $@($) <..$limit>)> do
templates sift
def prime: $;
@: $prime * $prime;
@sieve: [ $@sieve... -> # ];
when <..~$@> do
$ !
when <$@~..> do
@: $@ + $prime;
$ -> #
end sift
 
$@($) -> sift !
$ + 1 -> #
end sieve
 
1000 -> sieve ...-> '$; ' -> !OUT::write
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 12,856 ⟶ 19,473:
 
Better version using the mutability of the @-state to just update a primality flag
<langsyntaxhighlight lang="tailspin">
templates sieve
def limit: $;
Line 12,862 ⟶ 19,479:
@(1): 0;
2..$limit -> #
$@ -> \[i](<=1> $i !\) !
 
when <?($@($) <=1>)> do
def prime2: $ * $;
$prime2..$limit:$ -> @sieve($): 0;
Line 12,870 ⟶ 19,487:
 
1000 -> sieve... -> '$; ' -> !OUT::write
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 12,877 ⟶ 19,494:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
proc sieve n {
Line 12,902 ⟶ 19,519:
}
 
puts [sieve 100] ;# 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</langsyntaxhighlight>
 
 
Summary :/* {{header|TI-83 BASIC}} */
 
=={{header|TI-83 BASIC}}==
<langsyntaxhighlight lang="ti83b">Input "Limit:",N
N→Dim(L1)
For(I,2,N)
Line 12,927 ⟶ 19,544:
End
End
ClrList L1</langsyntaxhighlight>
 
=={{header|UNIX Shell}}==
===With array===
{{works with|zshBourne Again SHell}}
{{works with|Korn Shell}}
<lang bash>#!/usr/bin/zsh
{{works with|Zsh}}
 
<syntaxhighlight lang="bash">function primes() {
typeset -a a
typeset i j
a[1]=""
 
for (( i = 2; i <= $1; i++ )); do
a[1]=""
for (( i = 2; a[$i <]= $1; i++ )); do
done
a[$i]=$i
for (( i = 2; i * i <= $1; i++ )); do
done
if [[ ! -z ${a[$i]} ]]; then
 
for (( ij = 2; i * i; j <= $1; i+j += i )); do
if [[ ! -z $ a[$ij] ]]; then=""
done
for (( j = i * i; j <= $1; j += i )); do
fi
a[$j]=""
done
printf '%s' "${a[2]}"
fi
printf ' %s' ${a[*]:3}
done
printf '\n'
print $a
}
 
primes 1000</langsyntaxhighlight>
 
{{works with|bashOut}}
Output is a single long line:
{{works with|ksh93}}
{{works with|pdksh}}
 
<lang bash>function primes {
typeset a i=2 j m=$1
# No for (( ... )) loop in pdksh. Use while loop.
while (( i <= m )); do
a[$i]=$i
(( i++ ))
done
 
i=2
while (( j = i * i, j <= m )); do
if [[ -n ${a[$i]} ]]; then
while (( j <= m )); do
unset a[$j]
(( j += i ))
done
fi
(( i++ ))
done
# No print command in bash. Use echo command.
echo ${a[*]}
}
 
primes 1000</lang>
 
Both scripts output a single long line.
<pre>2 3 5 7 11 13 17 19 23 ... 971 977 983 991 997</pre>
 
Line 12,990 ⟶ 19,580:
 
{{works with|Bourne Shell}}
<langsyntaxhighlight lang="bash">#! /bin/sh
 
LIMIT=1000
Line 13,032 ⟶ 19,622:
eval \\$p$i && echo $i
i=\`expr $i + 1\`
done`</langsyntaxhighlight>
 
===With piping===
Line 13,044 ⟶ 19,634:
 
{{works with|Bourne Shell}}
<langsyntaxhighlight lang="bash">sourc() {
seq 2 1000
}
Line 13,062 ⟶ 19,652:
}
 
sourc | sink</langsyntaxhighlight>
 
This version works by piping 1s and 0s through ''sed''. The string of 1s and 0s represents the array of primes.
 
{{works with|Bourne Shell}}
<langsyntaxhighlight lang="bash"># Fill $1 characters with $2.
fill () {
# This pipeline would begin
Line 13,099 ⟶ 19,689:
}
 
prime 1000</langsyntaxhighlight>
 
==={{header|C Shell}}===
{{trans|CMake}}
<langsyntaxhighlight lang="csh"># Sieve of Eratosthenes: Echoes all prime numbers through $limit.
@ limit = 80
 
Line 13,130 ⟶ 19,720:
endif
@ i += 1
end</langsyntaxhighlight>
 
=={{header|Ursala}}==
{{incorrect|Ursala|It probably (remainder) uses rem testing and so is a trial division algorithm, not a sieve of Eratosthenes.}}
with no optimizations
<langsyntaxhighlight Ursalalang="ursala">#import nat
 
sieve = ~<{0,1}&& iota; @NttPX ~&r->lx ^/~&rhPlC remainder@rlX~|@r</langsyntaxhighlight>
test program:
<langsyntaxhighlight Ursalalang="ursala">#cast %nL
 
example = sieve 50</langsyntaxhighlight>{{out}}
<2,3,5,7,11,13,17,19,23,29,31,37,41,43,47>
 
=={{header|Vala}}==
{{libheader|Gee}}Without any optimizations:
<langsyntaxhighlight lang="vala">using Gee;
 
ArrayList<int> primes(int limit){
Line 13,182 ⟶ 19,773:
stdout.printf("\n");
}</langsyntaxhighlight>{{out}
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47
 
=={{header|VAX Assembly}}==
<langsyntaxhighlight VAXlang="vax Assemblyassembly"> 000F4240 0000 1 n=1000*1000
0000 0000 2 .entry main,0
7E 7CFD 0002 3 clro -(sp) ;result buffer
Line 13,213 ⟶ 19,805:
0046 27
0001E892 0046 28 bits: .blkl <n+2+31>/32
E892 29 .end main</langsyntaxhighlight>
 
=={{header|VBA}}==
Using Excel<syntaxhighlight lang="vb"> Sub primes()
'BRRJPA
'Prime calculation for VBA_Excel
'p is the superior limit of the range calculation
'This example calculates from 2 to 100000 and print it
'at the collum A
 
 
p = 100000
 
Dim nprimes(1 To 100000) As Integer
b = Sqr(p)
 
For n = 2 To b
 
For k = n * n To p Step n
nprimes(k) = 1
Next k
Next n
 
 
For a = 2 To p
If nprimes(a) = 0 Then
c = c + 1
Range("A" & c).Value = a
End If
Next a
 
End Sub </syntaxhighlight>
 
=={{header|VBScript}}==
To run in console mode with cscript.
<syntaxhighlight lang="vb">
<lang vb>
Dim sieve()
If WScript.Arguments.Count>=1 Then
Line 13,238 ⟶ 19,863:
If sieve(i) Then WScript.Echo i
Next
</syntaxhighlight>
</lang>
 
=={{header|Vedit macro language}}==
Line 13,275 ⟶ 19,900:
-P-----P---------P-----P-----P-P-----P---------P-----P-----P
</pre>
=={{header|VBA}}==
Using Excel<lang vb> Sub primes()
'BRRJPA
'Prime calculation for VBA_Excel
'p is the superior limit of the range calculation
'This example calculates from 2 to 100000 and print it
'at the collum A
 
 
p = 100000
 
Dim nprimes(1 To 100000) As Integer
b = Sqr(p)
 
For n = 2 To b
 
For k = n * n To p Step n
nprimes(k) = 1
Next k
Next n
 
 
For a = 2 To p
If nprimes(a) = 0 Then
c = c + 1
Range("A" & c).Value = a
End If
Next a
 
End Sub </lang >
 
=={{header|Visual Basic}}==
'''Works with:''' VB6
<langsyntaxhighlight lang="vb">Sub Eratost()
Dim sieve() As Boolean
Dim n As Integer, i As Integer, j As Integer
Line 13,328 ⟶ 19,921:
If sieve(i) Then Debug.Print i
Next i
End Sub 'Eratost</langsyntaxhighlight>
 
=={{header|Visual Basic .NET}}==
<langsyntaxhighlight lang="vbnet">Dim n As Integer, k As Integer, limit As Integer
Console.WriteLine("Enter number to search to: ")
limit = Console.ReadLine
Line 13,348 ⟶ 19,941:
Console.WriteLine(n)
End If
Next n</langsyntaxhighlight>
===Alternate===
Since the sieves are being removed only above the current iteration, the separate loop for display is unnecessary. And no '''Math.Sqrt()''' needed. Also, input is from command line parameter instead of Console.ReadLine(). Consolidated ''If'' block with ''For'' statement into two ''Do'' loops.
<langsyntaxhighlight lang="vbnet">Module Module1
Sub Main(args() As String)
Dim lmt As Integer = 500, n As Integer = 2, k As Integer
If args.Count > 0 Then Integer.TryParse(args(0), lmt)
Dim flags(lmt + 1) As Boolean ' non-primes are true in this array.
Do ' a prime was found,
For n = 2 To lmt
If Not flagsConsole.Write($"{n} ") Then ' aso primeshow was foundit,
For k = Console.Write($"{n} ")* n To lmt Step n ' soand showeliminate any multiple of it, at it's square and beyond.
flags(k) = True
For k = n * n To lmt Step n ' and eliminate any multiple of at it's square and beyond
flags(k) = TrueNext
Do Next ' skip over non-primes.
End n += If(n = 2, 1, 2)
Next Loop While flags(n)
Loop while n <= lmt
End Sub
End Module</langsyntaxhighlight>{{out}}<pre>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 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 </pre>
 
=={{header|V (Vlang)}}==
{{trans|go}}
===Basic sieve of array of booleans===
<syntaxhighlight lang="v (vlang)">fn main() {
limit := 201 // means sieve numbers < 201
// sieve
mut c := []bool{len: limit} // c for composite. false means prime candidate
c[1] = true // 1 not considered prime
mut p := 2
for {
// first allowed optimization: outer loop only goes to sqrt(limit)
p2 := p * p
if p2 >= limit {
break
}
// second allowed optimization: inner loop starts at sqr(p)
for i := p2; i < limit; i += p {
c[i] = true // it's a composite
}
// scan to get next prime for outer loop
for {
p++
if !c[p] {
break
}
}
}
// sieve complete. now print a representation.
for n in 1..limit {
if c[n] {
print(" .")
} else {
print("${n:3}")
}
if n%20 == 0 {
println("")
}
}
}</syntaxhighlight>
Output:
<pre>
. 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 . . .
101 .103 . . .107 .109 . . .113 . . . . . . .
. . . . . .127 . . .131 . . . . .137 .139 .
. . . . . . . .149 .151 . . . . .157 . . .
. .163 . . .167 . . . . .173 . . . . .179 .
181 . . . . . . . . .191 .193 . . .197 .199 .
</pre>
 
=={{header|Vorpal}}==
<langsyntaxhighlight lang="vorpal">self.print_primes = method(m){
p = new()
p.fill(0, m, 1, true)
Line 13,390 ⟶ 20,039:
}
 
self.print_primes(100)</langsyntaxhighlight>{{out|Result}}
primes: 25 in 100
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,
 
=={{header|WebAssembly}}==
Line 13,440 ⟶ 20,089:
=={{header|Xojo}}==
Place the following in the '''Run''' event handler of a Console application:
<langsyntaxhighlight Xojolang="xojo">Dim limit, prime, i As Integer
Dim s As String
Dim t As Double
Line 13,472 ⟶ 20,121:
If Not sieve(i) Then Print(Str(i))
Next
s = Input</langsyntaxhighlight>
 
{{out}}
Line 13,501 ⟶ 20,150:
This version uses a dynamic array and can use (a lot) less memory. It's (a lot) slower too.
Since Booleans are manually set to True, the algorithm makes more sense.
<langsyntaxhighlight Xojolang="xojo">Dim limit, prime, i As Integer
Dim s As String
Dim t As Double
Line 13,539 ⟶ 20,188:
If sieve(i) Then Print(Str(i))
Next
s = Input</langsyntaxhighlight>
 
{{out}}
Line 13,565 ⟶ 20,214:
47
...
</pre>
 
=={{header|Woma}}==
 
<syntaxhighlight lang="woma">(sieve(n = /0 -> int; limit = /0 -> int; is_prime = [/0] -> *)) *
i<@>range(n*n, limit+1, n)
is_prime = is_prime[$]i,False
<*>is_prime
 
(primes_upto(limit = 4 -> int)) list(int)
primes = [] -> list
f = [False, False] -> list(bool)
t = [True] -> list(bool)
u = limit - 1 -> int
tt = t * u -> list(bool)
is_prime = flatten(f[^]tt) -> list(bool)
limit_sqrt = limit ** 0.5 -> float
iter1 = int(limit_sqrt + 1.5) -> int
 
n<@>range(iter1)
is_prime[n]<?>is_prime = sieve(n, limit, is_prime)
 
i,prime<@>enumerate(is_prime)
prime<?>primes = primes[^]i
<*>primes</syntaxhighlight>
 
=={{header|Wren}}==
<syntaxhighlight lang="wren">var sieveOfE = Fn.new { |n|
if (n < 2) return []
var comp = List.filled(n-1, false)
var p = 2
while (true) {
var p2 = p * p
if (p2 > n) break
var i = p2
while (i <= n) {
comp[i-2] = true
i = i + p
}
while (true) {
p = p + 1
if (!comp[p-2]) break
}
}
var primes = []
for (i in 0..n-2) {
if (!comp[i]) primes.add(i+2)
}
return primes
}
 
System.print(sieveOfE.call(100))</syntaxhighlight>
 
{{out}}
<pre>
[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]
</pre>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
int Size, Prime, I, Kill;
char Flag;
Line 13,584 ⟶ 20,289:
];
];
]</langsyntaxhighlight>{{out|Example output}}<pre>20
2
3
Line 13,595 ⟶ 20,300:
 
=={{header|Yabasic}}==
<langsyntaxhighlight Yabasiclang="yabasic">#!/usr/bin/yabasic
 
// ---------------------------
Line 13,647 ⟶ 20,352:
 
print "time: ", t, "\n"
print peek("millisrunning")</langsyntaxhighlight>
 
=={{header|Zig}}==
<syntaxhighlight lang="zig">
const std = @import("std");
const stdout = std.io.getStdOut().outStream();
 
pub fn main() !void {
try sieve(1000);
}
 
// using a comptime limit ensures that there's no need for dynamic memory.
fn sieve(comptime limit: usize) !void {
var prime = [_]bool{true} ** limit;
prime[0] = false;
prime[1] = false;
var i: usize = 2;
while (i*i < limit) : (i += 1) {
if (prime[i]) {
var j = i*i;
while (j < limit) : (j += i)
prime[j] = false;
}
}
var c: i32 = 0;
for (prime) |yes, p|
if (yes) {
c += 1;
try stdout.print("{:5}", .{p});
if (@rem(c, 10) == 0)
try stdout.print("\n", .{});
};
try stdout.print("\n", .{});
}
</syntaxhighlight>
{{out}}
<pre>
$ zig run sieve.zig
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 101 103 107 109 113
127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229
233 239 241 251 257 263 269 271 277 281
283 293 307 311 313 317 331 337 347 349
353 359 367 373 379 383 389 397 401 409
419 421 431 433 439 443 449 457 461 463
467 479 487 491 499 503 509 521 523 541
547 557 563 569 571 577 587 593 599 601
607 613 617 619 631 641 643 647 653 659
661 673 677 683 691 701 709 719 727 733
739 743 751 757 761 769 773 787 797 809
811 821 823 827 829 839 853 857 859 863
877 881 883 887 907 911 919 929 937 941
947 953 967 971 977 983 991 997
</pre>
===Odds-only bit packed version===
{{trans|BCPL}}
Includes the iterator, as with the BCPL Odds-only bit packed sieve. Since it's not much extra code, the sieve object also includes methods for getting the size and testing for membership.
<syntaxhighlight lang="zig">
const std = @import("std");
const heap = std.heap;
const mem = std.mem;
const stdout = std.io.getStdOut().writer();
 
pub fn main() !void {
const assert = std.debug.assert;
 
var buf: [fixed_alloc_sz(1000)]u8 = undefined; // buffer big enough for 1,000 primes.
var fba = heap.FixedBufferAllocator.init(&buf);
 
const sieve = try SoE.init(1000, &fba.allocator);
defer sieve.deinit(); // not needed for the FBA, but in general you would de-init the sieve
 
// test membership functions
assert(sieve.contains(997));
assert(!sieve.contains(995));
assert(!sieve.contains(994));
assert(!sieve.contains(1009));
 
try stdout.print("There are {} primes < 1000\n", .{sieve.size()});
var c: u32 = 0;
var iter = sieve.iterator();
while (iter.next()) |p| {
try stdout.print("{:5}", .{p});
c += 1;
if (c % 10 == 0)
try stdout.print("\n", .{});
}
try stdout.print("\n", .{});
}
 
// return size to sieve n prmes if using the Fixed Buffer Allocator
// adds some u64 words for FBA bookkeeping.
pub inline fn fixed_alloc_sz(limit: usize) usize {
return (2 + limit / 128) * @sizeOf(u64);
}
 
pub const SoE = struct {
const all_u64bits_on = 0xFFFF_FFFF_FFFF_FFFF;
const empty = [_]u64{};
 
sieve: []u64,
alloc: *mem.Allocator,
 
pub fn init(limit: u64, allocator: *mem.Allocator) error{OutOfMemory}!SoE {
if (limit < 3)
return SoE{
.sieve = &empty,
.alloc = allocator,
};
 
var bit_sz = (limit + 1) / 2 - 1;
var q = bit_sz >> 6;
var r = bit_sz & 0x3F;
var sz = q + @boolToInt(r > 0);
var sieve = try allocator.alloc(u64, sz);
 
var i: usize = 0;
while (i < q) : (i += 1)
sieve[i] = all_u64bits_on;
if (r > 0)
sieve[q] = (@as(u64, 1) << @intCast(u6, r)) - 1;
 
var bit: usize = 0;
while (true) {
while (sieve[bit >> 6] & @as(u64, 1) << @intCast(u6, bit & 0x3F) == 0)
bit += 1;
 
const p = 2 * bit + 3;
q = p * p;
if (q > limit)
return SoE{
.sieve = sieve,
.alloc = allocator,
};
 
r = (q - 3) / 2;
while (r < bit_sz) : (r += p)
sieve[r >> 6] &= ~((@as(u64, 1)) << @intCast(u6, r & 0x3F));
 
bit += 1;
}
}
 
pub fn deinit(self: SoE) void {
if (self.sieve.len > 0) {
self.alloc.free(self.sieve);
}
}
 
pub fn iterator(self: SoE) SoE_Iterator {
return SoE_Iterator.init(self.sieve);
}
 
pub fn size(self: SoE) usize {
var sz: usize = 1; // sieve doesn't include 2.
for (self.sieve) |bits|
sz += @popCount(u64, bits);
return sz;
}
 
pub fn contains(self: SoE, n: u64) bool {
if (n & 1 == 0)
return n == 2
else {
const bit = (n - 3) / 2;
const q = bit >> 6;
const r = @intCast(u6, bit & 0x3F);
return if (q >= self.sieve.len)
false
else
self.sieve[q] & (@as(u64, 1) << r) != 0;
}
}
};
 
// Create an iterater object to enumerate primes we've generated.
const SoE_Iterator = struct {
const Self = @This();
 
start: u64,
bits: u64,
sieve: []const u64,
 
pub fn init(sieve: []const u64) Self {
return Self{
.start = 0,
.sieve = sieve,
.bits = sieve[0],
};
}
 
pub fn next(self: *Self) ?u64 {
if (self.sieve.len == 0)
return null;
 
// start = 0 => first time, so yield 2.
if (self.start == 0) {
self.start = 3;
return 2;
}
 
var x = self.bits;
while (true) {
if (x != 0) {
const p = @ctz(u64, x) * 2 + self.start;
x &= x - 1;
self.bits = x;
return p;
} else {
self.start += 128;
self.sieve = self.sieve[1..];
if (self.sieve.len == 0)
return null;
x = self.sieve[0];
}
}
}
};
</syntaxhighlight>
{{Out}}
<pre>
There are 168 primes < 1000
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 101 103 107 109 113
127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229
233 239 241 251 257 263 269 271 277 281
283 293 307 311 313 317 331 337 347 349
353 359 367 373 379 383 389 397 401 409
419 421 431 433 439 443 449 457 461 463
467 479 487 491 499 503 509 521 523 541
547 557 563 569 571 577 587 593 599 601
607 613 617 619 631 641 643 647 653 659
661 673 677 683 691 701 709 719 727 733
739 743 751 757 761 769 773 787 797 809
811 821 823 827 829 839 853 857 859 863
877 881 883 887 907 911 919 929 937 941
947 953 967 971 977 983 991 997
</pre>
===Optimized version===
<syntaxhighlight lang="zig">
const stdout = @import("std").io.getStdOut().writer();
 
const lim = 1000;
const n = lim - 2;
 
var primes: [n]?usize = undefined;
 
pub fn main() anyerror!void {
var i: usize = 0;
var m: usize = 0;
 
while (i < n) : (i += 1) {
primes[i] = i + 2;
}
 
i = 0;
while (i < n) : (i += 1) {
if (primes[i]) |prime| {
m += 1;
try stdout.print("{:5}", .{prime});
if (m % 10 == 0) try stdout.print("\n", .{});
var j: usize = i + prime;
while (j < n) : (j += prime) {
primes[j] = null;
}
}
}
try stdout.print("\n", .{});
}
 
</syntaxhighlight>
{{Out}}
<pre>
$ zig run sieve.zig
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 101 103 107 109 113
127 131 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229
233 239 241 251 257 263 269 271 277 281
283 293 307 311 313 317 331 337 347 349
353 359 367 373 379 383 389 397 401 409
419 421 431 433 439 443 449 457 461 463
467 479 487 491 499 503 509 521 523 541
547 557 563 569 571 577 587 593 599 601
607 613 617 619 631 641 643 647 653 659
661 673 677 683 691 701 709 719 727 733
739 743 751 757 761 769 773 787 797 809
811 821 823 827 829 839 853 857 859 863
877 881 883 887 907 911 919 929 937 941
947 953 967 971 977 983 991 997
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn sieve(limit){
composite:=Data(limit+1).fill(1); // bucket of bytes set to 1 (prime)
(2).pump(limit.toFloat().sqrt()+1, Void, // Void==no results, just loop
Line 13,657 ⟶ 20,657:
(2).filter(limit-1,composite.get); // bytes still 1 are prime
}
sieve(53).println();</langsyntaxhighlight>
The pump method is just a loop, passing results from action to action
and collecting the results (ie a minimal state machine). Pumping to Void
890

edits