1:
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: #include <sys/cdefs.h>
36: #ifndef lint
37: __COPYRIGHT("@(#) Copyright (c) 1989, 1993\n\
38: The Regents of the University of California. All rights reserved.\n");
39: #endif
40:
41: #ifndef lint
42: #if 0
43: static char sccsid[] = "@(#)primes.c 8.5 (Berkeley) 5/10/95";
44: #else
45: __RCSID("$NetBSD: primes.c,v 1.12 2004/01/27 20:30:30 jsm Exp $");
46: #endif
47: #endif
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66: #include <ctype.h>
67: #include <err.h>
68: #include <errno.h>
69: #include <limits.h>
70: #include <math.h>
71: #include <memory.h>
72: #include <stdio.h>
73: #include <stdlib.h>
74: #include <unistd.h>
75:
76: #include "primes.h"
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87: char table[TABSIZE];
88:
89:
90:
91:
92:
93:
94:
95: extern const ubig prime[];
96: extern const ubig *pr_limit;
97:
98:
99:
100:
101:
102:
103: extern const char pattern[];
104: extern const int pattern_size;
105:
106: int main(int, char *[]);
107: void primes(ubig, ubig);
108: ubig read_num_buf(void);
109: void usage(void) __attribute__((__noreturn__));
110:
111: int
112: main(argc, argv)
113: int argc;
114: char *argv[];
115: {
116: ubig start;
117: ubig stop;
118: int ch;
119: char *p;
120:
121:
122: setregid(getgid(), getgid());
123:
124: while ((ch = getopt(argc, argv, "")) != -1)
125: switch (ch) {
126: case '?':
127: default:
128: usage();
129: }
130: argc -= optind;
131: argv += optind;
132:
133: start = 0;
134: stop = BIG;
135:
136:
137:
138:
139:
140:
141:
142: switch (argc) {
143: case 2:
144:
145: if (argv[0][0] == '-' || argv[1][0] == '-')
146: errx(1, "negative numbers aren't permitted.");
147:
148: errno = 0;
149: start = strtoul(argv[0], &p, 10);
150: if (errno)
151: err(1, "%s", argv[0]);
152: if (*p != '\0')
153: errx(1, "%s: illegal numeric format.", argv[0]);
154:
155: errno = 0;
156: stop = strtoul(argv[1], &p, 10);
157: if (errno)
158: err(1, "%s", argv[1]);
159: if (*p != '\0')
160: errx(1, "%s: illegal numeric format.", argv[1]);
161: break;
162: case 1:
163:
164: if (argv[0][0] == '-')
165: errx(1, "negative numbers aren't permitted.");
166:
167: errno = 0;
168: start = strtoul(argv[0], &p, 10);
169: if (errno)
170: err(1, "%s", argv[0]);
171: if (*p != '\0')
172: errx(1, "%s: illegal numeric format.", argv[0]);
173: break;
174: case 0:
175: start = read_num_buf();
176: break;
177: default:
178: usage();
179: }
180:
181: if (start > stop)
182: errx(1, "start value must be less than stop value.");
183: primes(start, stop);
184: exit(0);
185: }
186:
187:
188:
189:
190:
191: ubig
192: read_num_buf()
193: {
194: ubig val;
195: char *p, buf[100];
196:
197: for (;;) {
198: if (fgets(buf, sizeof(buf), stdin) == NULL) {
199: if (ferror(stdin))
200: err(1, "stdin");
201: exit(0);
202: }
203: for (p = buf; isblank(*p); ++p);
204: if (*p == '\n' || *p == '\0')
205: continue;
206: if (*p == '-')
207: errx(1, "negative numbers aren't permitted.");
208: errno = 0;
209: val = strtoul(buf, &p, 10);
210: if (errno)
211: err(1, "%s", buf);
212: if (*p != '\n')
213: errx(1, "%s: illegal numeric format.", buf);
214: return (val);
215: }
216: }
217:
218:
219:
220:
221: void
222: primes(start, stop)
223: ubig start;
224: ubig stop;
225: {
226: char *q;
227: ubig factor;
228: char *tab_lim;
229: const ubig *p;
230: ubig fact_lim;
231: ubig mod;
232:
233:
234:
235:
236:
237:
238: if (start < 3) {
239: start = (ubig)2;
240: }
241: if (stop < 3) {
242: stop = (ubig)2;
243: }
244: if (stop <= start) {
245: return;
246: }
247:
248:
249:
250:
251: if (start != 2 && (start&0x1) == 0) {
252: ++start;
253: }
254: if (stop != 2 && (stop&0x1) == 0) {
255: ++stop;
256: }
257:
258:
259:
260:
261: if (start <= *pr_limit) {
262:
263: for (p = &prime[0], factor = prime[0];
264: factor < stop && p <= pr_limit; factor = *(++p)) {
265: if (factor >= start) {
266: printf("%lu\n", (unsigned long) factor);
267: }
268: }
269:
270: if (p <= pr_limit) {
271: return;
272: }
273: start = *pr_limit+2;
274: }
275:
276:
277:
278:
279:
280: while (start < stop) {
281:
282:
283:
284:
285: factor = (start%(2*3*5*7*11*13))/2;
286: memcpy(table, &pattern[factor], pattern_size-factor);
287:
288: for (fact_lim=pattern_size-factor;
289: fact_lim+pattern_size<=TABSIZE; fact_lim+=pattern_size) {
290: memcpy(&table[fact_lim], pattern, pattern_size);
291: }
292:
293: memcpy(&table[fact_lim], pattern, TABSIZE-fact_lim);
294:
295:
296:
297:
298:
299: if (stop-start > TABSIZE+TABSIZE) {
300: tab_lim = &table[TABSIZE];
301: fact_lim = (int)sqrt(
302: (double)(start)+TABSIZE+TABSIZE+1.0);
303: } else {
304: tab_lim = &table[(stop-start)/2];
305: fact_lim = (int)sqrt((double)(stop)+1.0);
306: }
307:
308: factor = 17;
309: p = &prime[7];
310: do {
311:
312: mod = start%factor;
313: if (mod & 0x1) {
314: q = &table[(factor-mod)/2];
315: } else {
316: q = &table[mod ? factor-(mod/2) : 0];
317: }
318:
319: for ( ; q < tab_lim; q += factor) {
320: *q = '\0';
321: }
322: } while ((factor=(ubig)(*(p++))) <= fact_lim);
323:
324:
325:
326:
327: for (q = table; q < tab_lim; ++q, start+=2) {
328: if (*q) {
329: printf("%lu\n", (unsigned long) start);
330: }
331: }
332: }
333: }
334:
335: void
336: usage()
337: {
338: (void)fprintf(stderr, "usage: primes [start [stop]]\n");
339: exit(1);
340: }