ref: 3efb5bbb4061056e523858b134c555949591efe2
dir: /appl/math/sieve.b/
implement Sieve; include "sys.m"; sys: Sys; include "draw.m"; include "arg.m"; arg: Arg; M: con 16*1024*1024; N: con 8*M; T: con 2*1024*1024; limit := array[5] of { M, N, 2*N, 3*N, 15*(N/4) }; Sieve: module { init: fn(nil: ref Draw->Context, argv: list of string); }; init(nil: ref Draw->Context, argv: list of string) { sys = load Sys Sys->PATH; arg = load Arg Arg->PATH; np := 0; alg := 3; arg->init(argv); while((c := arg->opt()) != 0){ case (c){ 'a' => alg = int arg->arg(); } } if(alg < 0 || alg > 4) alg = 3; lim := limit[alg]; argv = arg->argv(); if(argv != nil) lim = int hd argv; if(lim < 0 || lim > limit[alg]) lim = limit[alg]; if(lim < 6){ if(lim > 2){ sys->print("2\n"); np++; } if(lim > 3){ sys->print("3\n"); np++; } } else{ case (alg){ 0 => np = init0(lim); 1 => np = init1(lim); 2 => np = init2(lim); 3 => np = init3(lim); 4 => np = init4(lim); } } sys->print("%d primes < %d\n", np, lim); } init0(lim: int): int { p := array[lim] of byte; for(i := 0; i < lim; i++) p[i] = byte 1; p[0] = p[1] = byte 0; np := 0; for(i = 0; i < lim; i++){ if(p[i] == byte 1){ np++; sys->print("%d\n", i); for(j := i+i; j < lim; j += i) p[j] = byte 0; } } return np; } init1(lim: int): int { n := (lim+31)/32; p := array[n] of int; for(i := 0; i < n; i++) p[i] = int 16rffffffff; p[0] = int 16rfffffffc; np := 0; for(i = 0; i < lim; i++){ if(p[i>>5] & (1<<(i&31))){ np++; sys->print("%d\n", i); for(j := i+i; j < lim; j += i) p[j>>5] &= ~(1<<(j&31)); } } return np; } init2(lim: int): int { n := ((lim+1)/2+31)/32; p := array[n] of int; for(i := 0; i < n; i++) p[i] = int 16rffffffff; p[0] = int 16rfffffffe; np := 1; sys->print("%d\n", 2); for(i = 1; i < lim; i += 2){ k := (i-1)>>1; if(p[k>>5] & (1<<(k&31))){ np++; sys->print("%d\n", i); inc := i+i; for(j := i+i+i; j < lim; j += inc){ k = (j-1)>>1; p[k>>5] &= ~(1<<(k&31)); } } } return np; } init3(lim: int): int { n := ((lim+2)/3+31)/32; p := array[n] of int; for(i := 0; i < n; i++) p[i] = int 16rffffffff; p[0] = int 16rfffffffe; np := 2; sys->print("%d\n", 2); sys->print("%d\n", 3); d := 2; for(i = 1; i < lim; i += d){ k := (i-1)/3; if(p[k>>5] & (1<<(k&31))){ np++; sys->print("%d\n", i); inc := 6*i; for(j := 5*i; j > 0 && j < lim; j += inc){ k = (j-1)/3; p[k>>5] &= ~(1<<(k&31)); } for(j = 7*i; j > 0 && j < lim; j += inc){ k = (j-1)/3; p[k>>5] &= ~(1<<(k&31)); } } d = 6-d; } return np; } init4(lim: int): int { n := (4*((lim+14)/15)+31)/32; p := array[n] of int; for(i := 0; i < n; i++) p[i] = int 16rffffffff; p[0] = int 16rfffffffe; np := 3; sys->print("%d\n", 2); sys->print("%d\n", 3); sys->print("%d\n", 5); m := -1; d := array[8] of { 6, 4, 2, 4, 2, 4, 6, 2 }; for(i = 1; i < lim; i += d[m]){ k := (17*(i%30-1))/60+8*(i/30); if(p[k>>5] & (1<<(k&31))){ np++; sys->print("%d\n", i); inc := 30*i; for(j := 7*i; j > 0 && j < lim; j += inc){ k = (17*(j%30-1))/60+8*(j/30); p[k>>5] &= ~(1<<(k&31)); } for(j = 11*i; j > 0 && j < lim; j += inc){ k = (17*(j%30-1))/60+8*(j/30); p[k>>5] &= ~(1<<(k&31)); } for(j = 13*i; j > 0 && j < lim; j += inc){ k = (17*(j%30-1))/60+8*(j/30); p[k>>5] &= ~(1<<(k&31)); } for(j = 17*i; j > 0 && j < lim; j += inc){ k = (17*(j%30-1))/60+8*(j/30); p[k>>5] &= ~(1<<(k&31)); } for(j = 19*i; j > 0 && j < lim; j += inc){ k = (17*(j%30-1))/60+8*(j/30); p[k>>5] &= ~(1<<(k&31)); } for(j = 23*i; j > 0 && j < lim; j += inc){ k = (17*(j%30-1))/60+8*(j/30); p[k>>5] &= ~(1<<(k&31)); } for(j = 29*i; j > 0 && j < lim; j += inc){ k = (17*(j%30-1))/60+8*(j/30); p[k>>5] &= ~(1<<(k&31)); } for(j = 31*i; j > 0 && j < lim; j += inc){ k = (17*(j%30-1))/60+8*(j/30); p[k>>5] &= ~(1<<(k&31)); } } m++; if(m == 8) m = 0; } return np; } init5(lim: int): int { # you must be joking lim = 0; return 0; }