1implement Primes; 2 3# 4# primes starting [ending] 5# 6# Subject to the Lucent Public License 1.02 7# 8 9include "draw.m"; 10 11Primes: module 12{ 13 init: fn(nil: ref Draw->Context, argl: list of string); 14}; 15 16include "sys.m"; 17 sys: Sys; 18include "math.m"; 19 maths: Math; 20 21bigx: con 9.007199254740992e15; 22pt := array[] of { 23 2, 24 3, 25 5, 26 7, 27 11, 28 13, 29 17, 30 19, 31 23, 32 29, 33 31, 34 37, 35 41, 36 43, 37 47, 38 53, 39 59, 40 61, 41 67, 42 71, 43 73, 44 79, 45 83, 46 89, 47 97, 48 101, 49 103, 50 107, 51 109, 52 113, 53 127, 54 131, 55 137, 56 139, 57 149, 58 151, 59 157, 60 163, 61 167, 62 173, 63 179, 64 181, 65 191, 66 193, 67 197, 68 199, 69 211, 70 223, 71 227, 72 229, 73}; 74wheel := array[] of { 75 10.0, 76 2.0, 77 4.0, 78 2.0, 79 4.0, 80 6.0, 81 2.0, 82 6.0, 83 4.0, 84 2.0, 85 4.0, 86 6.0, 87 6.0, 88 2.0, 89 6.0, 90 4.0, 91 2.0, 92 6.0, 93 4.0, 94 6.0, 95 8.0, 96 4.0, 97 2.0, 98 4.0, 99 2.0, 100 4.0, 101 8.0, 102 6.0, 103 4.0, 104 6.0, 105 2.0, 106 4.0, 107 6.0, 108 2.0, 109 6.0, 110 6.0, 111 4.0, 112 2.0, 113 4.0, 114 6.0, 115 2.0, 116 6.0, 117 4.0, 118 2.0, 119 4.0, 120 2.0, 121 10.0, 122 2.0, 123}; 124BITS: con 8; 125TABLEN: con 1000; 126table := array[TABLEN] of byte; 127bittab := array[8] of { 128 byte 1, 129 byte 2, 130 byte 4, 131 byte 8, 132 byte 16, 133 byte 32, 134 byte 64, 135 byte 128, 136}; 137 138init(nil: ref Draw->Context, args: list of string) 139{ 140 sys = load Sys Sys->PATH; 141 maths = load Math Math->PATH; 142 143 if(len args <= 1){ 144 sys->fprint(sys->fildes(2), "usage: primes starting [ending]\n"); 145 raise "fail:usage"; 146 } 147 args = tl args; 148 nn := real hd args; 149 limit := bigx; 150 if(tl args != nil){ 151 limit = real hd tl args; 152 if(limit < nn) 153 exit; 154 if(limit > bigx) 155 ouch(); 156 } 157 if(nn < 0.0 || nn > bigx) 158 ouch(); 159 if(nn == 0.0) 160 nn = 1.0; 161 if(nn < 230.0){ 162 for(i := 0; i < len pt; i++){ 163 r := real pt[i]; 164 if(r < nn) 165 continue; 166 if(r > limit) 167 exit; 168 sys->print("%d\n", pt[i]); 169 if(limit >= bigx) 170 exit; 171 } 172 nn = 230.0; 173 } 174 (t, nil) := maths->modf(nn/2.0); 175 nn = 2.0*real t+1.0; 176 for(;;){ 177 # 178 # clear the sieve table. 179 # 180 for(i := 0; i < len table; i++) 181 table[i] = byte 0; 182 # 183 # run the sieve 184 # 185 v := maths->sqrt(nn+real (TABLEN*BITS)); 186 mark(nn, 3); 187 mark(nn, 5); 188 mark(nn, 7); 189 i = 0; 190 for(k := 11.0; k <= v; k += wheel[i]){ 191 mark(nn, int k); 192 i++; 193 if(i >= len wheel) 194 i = 0; 195 } 196 # 197 # now get the primes from the table and print them 198 # 199 for(i = 0; i < TABLEN*BITS; i += 2){ 200 if(int table[i>>3]&int bittab[i&8r7]) 201 continue; 202 temp := nn+real i; 203 if(temp > limit) 204 exit; 205 sys->print("%d\n", int temp); 206 if(limit >= bigx) 207 exit; 208 } 209 nn += real (TABLEN*BITS); 210 } 211} 212 213mark(nn: real, k: int) 214{ 215 (it1, nil) := maths->modf(nn/real k); 216 j := int (real k*real it1-nn); 217 if(j < 0) 218 j += k; 219 for(; j < len table*BITS; j += k) 220 table[j>>3] |= bittab[j&8r7]; 221} 222 223ouch() 224{ 225 sys->fprint(sys->fildes(2), "primes: limits exceeded\n"); 226 raise "fail:ouch"; 227} 228 229