date and time created 88/10/19 15:33:10 by bostic
[unix-history] / usr / src / games / primes / primes.c
CommitLineData
e0bbfbf9
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#ifndef lint
8char copyright[] =
9"@(#) Copyright (c) 1980 Regents of the University of California.\n\
10 All rights reserved.\n";
11#endif not lint
12
779464d0 13#ifndef lint
e0bbfbf9
DF
14static char sccsid[] = "@(#)primes.c 5.1 (Wollongong) %G%";
15#endif not lint
779464d0
SL
16
17/*
18 * primes [ number ]
19 *
20 * Print all primes greater than argument (or number read from stdin).
21 *
22 * A free translation of 'primes.s'
23 *
24 */
25
26#include <stdio.h>
27#include <math.h>
28
29#define TABSIZE 1000 /* size of sieve table */
30#define BIG 4294967296. /* largest unsigned int */
31
32char table[TABSIZE]; /* table for sieve of Eratosthenes */
33int tabbits = 8*TABSIZE; /* number of bits in table */
34
35float fstart;
36unsigned start; /* lowest number to test for prime */
37char bittab[] = { /* bit positions (to save shifting) */
38 01, 02, 04, 010, 020, 040, 0100, 0200
39};
40
41unsigned pt[] = { /* primes < 100 */
42 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
43 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
44};
45
46unsigned factab[] = { /* difference between succesive trial factors */
47 10, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4,
48 2, 6, 4, 6, 8, 4, 2, 4, 2, 4, 8, 6, 4, 6, 2, 4,
49 6, 2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4, 2, 10, 2
50};
51
52main(argc, argv)
53int argc;
54char **argv;
55{
56 register unsigned *fp;
57 register char *p;
58 register int i;
59 unsigned quot;
60 unsigned factor, v;
61
62 if (argc >= 2) { /* get starting no. from arg */
63 if (sscanf(argv[1], "%f", &fstart) != 1
64 || fstart < 0.0 || fstart >= BIG) {
65 ouch();
66 exit(1);
67 }
68 } else { /* get starting no. from stdin */
69 while ((i = scanf("%f", &fstart)) != 1
70 || fstart < 0.0 || fstart >= BIG) {
71 if (i == EOF)
72 exit(1);
73 ouch();
74 }
75 }
76 start = (unsigned)fstart;
77
78 /*
79 * Quick list of primes < 100
80 */
81 if (start <= 97) {
82 for (fp = pt; *fp < start; fp++)
83 ;
84 do
85 printf("%u\n", *fp);
86 while (++fp < &pt[sizeof(pt) / sizeof(*pt)]);
87 start = 100;
88 }
89 quot = start/2;
90 start = quot * 2 + 1;
91
92/*
93 * Loop forever:
94 */
95 for (;;) {
96 /*
97 * Generate primes via sieve of Eratosthenes
98 */
99 for (p = table; p < &table[TABSIZE]; p++) /* clear sieve */
100 *p = '\0';
101 v = (unsigned)sqrt((float)(start + tabbits)); /* highest useful factor */
102 sieve(3);
103 sieve(5);
104 sieve(7);
105 factor = 11;
106 fp = &factab[1];
107 do {
108 sieve(factor);
109 factor += *fp;
110 if (++fp >= &factab[sizeof(factab) / sizeof(*factab)])
111 fp = factab;
112 } while (factor <= v);
113 /*
114 * Print generated primes
115 */
116 for (i = 0; i < 8*TABSIZE; i += 2) {
117 if ((table[i>>3] & bittab[i&07]) == 0)
118 printf("%u\n", start);
119 start += 2;
120 }
121 }
122}
123
124/*
125 * Insert all multiples of given factor into the sieve
126 */
127sieve(factor)
128unsigned factor;
129{
130 register int i;
131 unsigned off;
132 unsigned quot;
133
134 quot = start / factor;
135 off = (quot * factor) - start;
136 if ((int)off < 0)
137 off += factor;
138 while (off < tabbits ) {
139 i = (int)off;
140 table[i>>3] |= bittab[i&07];
141 off += factor;
142 }
143}
144
145/*
146 * Error message
147 */
148ouch()
149{
150 fprintf(stderr, "Ouch.\n");
151}