xref: /plan9/sys/src/cmd/primes.c (revision 0be94c91c673b2f850c7eeadec513b7a6ed0c197)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
3*0be94c91SDavid du Colombier #include <bio.h>
43e12c5d1SDavid du Colombier 
57dd7cddfSDavid du Colombier double big = 9.007199254740992e15;
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier int pt[] =
83e12c5d1SDavid du Colombier {
93e12c5d1SDavid du Colombier 	  2,  3,  5,  7, 11, 13, 17, 19, 23, 29,
103e12c5d1SDavid du Colombier 	 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
113e12c5d1SDavid du Colombier 	 73, 79, 83, 89, 97,101,103,107,109,113,
123e12c5d1SDavid du Colombier 	127,131,137,139,149,151,157,163,167,173,
133e12c5d1SDavid du Colombier 	179,181,191,193,197,199,211,223,227,229,
143e12c5d1SDavid du Colombier };
153e12c5d1SDavid du Colombier double wheel[] =
163e12c5d1SDavid du Colombier {
173e12c5d1SDavid du Colombier 	10, 2, 4, 2, 4, 6, 2, 6, 4, 2,
183e12c5d1SDavid du Colombier 	 4, 6, 6, 2, 6, 4, 2, 6, 4, 6,
193e12c5d1SDavid du Colombier 	 8, 4, 2, 4, 2, 4, 8, 6, 4, 6,
203e12c5d1SDavid du Colombier 	 2, 4, 6, 2, 6, 6, 4, 2, 4, 6,
213e12c5d1SDavid du Colombier 	 2, 6, 4, 2, 4, 2,10, 2,
223e12c5d1SDavid du Colombier };
233e12c5d1SDavid du Colombier uchar table[1000];
243e12c5d1SDavid du Colombier uchar bittab[] =
253e12c5d1SDavid du Colombier {
263e12c5d1SDavid du Colombier 	1, 2, 4, 8, 16, 32, 64, 128,
273e12c5d1SDavid du Colombier };
283e12c5d1SDavid du Colombier 
29*0be94c91SDavid du Colombier enum {
30*0be94c91SDavid du Colombier 	ptsiz	= nelem(pt),
31*0be94c91SDavid du Colombier 	whsiz	= nelem(wheel),
32*0be94c91SDavid du Colombier 	tabsiz	= nelem(table),
33*0be94c91SDavid du Colombier 	tsiz8	= tabsiz*8,
34*0be94c91SDavid du Colombier };
35*0be94c91SDavid du Colombier 
363e12c5d1SDavid du Colombier void	mark(double nn, long k);
373e12c5d1SDavid du Colombier 
383e12c5d1SDavid du Colombier void
usage(void)39*0be94c91SDavid du Colombier usage(void)
40*0be94c91SDavid du Colombier {
41*0be94c91SDavid du Colombier 	fprint(2, "usage: %s [start [finish]]\n", argv0);
42*0be94c91SDavid du Colombier 	exits("limits");
43*0be94c91SDavid du Colombier }
44*0be94c91SDavid du Colombier 
45*0be94c91SDavid du Colombier void
ouch(void)46*0be94c91SDavid du Colombier ouch(void)
47*0be94c91SDavid du Colombier {
48*0be94c91SDavid du Colombier 	fprint(2, "limits exceeded\n");
49*0be94c91SDavid du Colombier 	exits("limits");
50*0be94c91SDavid du Colombier }
51*0be94c91SDavid du Colombier 
52*0be94c91SDavid du Colombier void
main(int argc,char * argv[])53*0be94c91SDavid du Colombier main(int argc, char *argv[])
543e12c5d1SDavid du Colombier {
553e12c5d1SDavid du Colombier 	int i;
563e12c5d1SDavid du Colombier 	double k, temp, v, limit, nn;
57*0be94c91SDavid du Colombier 	char *l;
58*0be94c91SDavid du Colombier 	Biobuf bin;
593e12c5d1SDavid du Colombier 
60*0be94c91SDavid du Colombier 	ARGBEGIN{
61*0be94c91SDavid du Colombier 	default:
62*0be94c91SDavid du Colombier 		usage();
63*0be94c91SDavid du Colombier 		break;
64*0be94c91SDavid du Colombier 	}ARGEND;
65*0be94c91SDavid du Colombier 
66*0be94c91SDavid du Colombier 	nn = 0;
673e12c5d1SDavid du Colombier 	limit = big;
68*0be94c91SDavid du Colombier 	switch (argc) {
69*0be94c91SDavid du Colombier 	case 0:
70*0be94c91SDavid du Colombier 		Binit(&bin, 0, OREAD);
71*0be94c91SDavid du Colombier 		while ((l = Brdline(&bin, '\n')) != nil) {
72*0be94c91SDavid du Colombier 			if (*l == '\n')
73*0be94c91SDavid du Colombier 				continue;
74*0be94c91SDavid du Colombier 			nn = atof(l);
75*0be94c91SDavid du Colombier 			if(nn < 0)
76*0be94c91SDavid du Colombier 				sysfatal("negative start");
77*0be94c91SDavid du Colombier 			break;
78*0be94c91SDavid du Colombier 		}
79*0be94c91SDavid du Colombier 		Bterm(&bin);
80*0be94c91SDavid du Colombier 		break;
81*0be94c91SDavid du Colombier 	case 2:
82*0be94c91SDavid du Colombier 		limit = atof(argv[1]);
833e12c5d1SDavid du Colombier 		if(limit < nn)
843e12c5d1SDavid du Colombier 			exits(0);
853e12c5d1SDavid du Colombier 		if(limit > big)
863e12c5d1SDavid du Colombier 			ouch();
87*0be94c91SDavid du Colombier 		/* fallthrough */
88*0be94c91SDavid du Colombier 	case 1:
89*0be94c91SDavid du Colombier 		nn = atof(argv[0]);
90*0be94c91SDavid du Colombier 		break;
91*0be94c91SDavid du Colombier 	default:
92*0be94c91SDavid du Colombier 		usage();
93*0be94c91SDavid du Colombier 		break;
943e12c5d1SDavid du Colombier 	}
95*0be94c91SDavid du Colombier 
963e12c5d1SDavid du Colombier 	if(nn < 0 || nn > big)
973e12c5d1SDavid du Colombier 		ouch();
983e12c5d1SDavid du Colombier 	if(nn == 0)
993e12c5d1SDavid du Colombier 		nn = 1;
1003e12c5d1SDavid du Colombier 
1013e12c5d1SDavid du Colombier 	if(nn < 230) {
1023e12c5d1SDavid du Colombier 		for(i=0; i<ptsiz; i++) {
1033e12c5d1SDavid du Colombier 			if(pt[i] < nn)
1043e12c5d1SDavid du Colombier 				continue;
1053e12c5d1SDavid du Colombier 			if(pt[i] > limit)
1063e12c5d1SDavid du Colombier 				exits(0);
1073e12c5d1SDavid du Colombier 			print("%d\n", pt[i]);
108*0be94c91SDavid du Colombier //			if(limit >= big)
109*0be94c91SDavid du Colombier //				exits(0);
1103e12c5d1SDavid du Colombier 		}
1113e12c5d1SDavid du Colombier 		nn = 230;
1123e12c5d1SDavid du Colombier 	}
1133e12c5d1SDavid du Colombier 
1143e12c5d1SDavid du Colombier 	modf(nn/2, &temp);
115*0be94c91SDavid du Colombier 	nn = 2*temp + 1;
1163e12c5d1SDavid du Colombier /*
1173e12c5d1SDavid du Colombier  *	clear the sieve table.
1183e12c5d1SDavid du Colombier  */
1193e12c5d1SDavid du Colombier 	for(;;) {
1203e12c5d1SDavid du Colombier 		for(i = 0; i < tabsiz; i++)
1213e12c5d1SDavid du Colombier 			table[i] = 0;
1223e12c5d1SDavid du Colombier /*
1233e12c5d1SDavid du Colombier  *	run the sieve.
1243e12c5d1SDavid du Colombier  */
1253e12c5d1SDavid du Colombier 		v = sqrt(nn+tsiz8);
1263e12c5d1SDavid du Colombier 		mark(nn, 3);
1273e12c5d1SDavid du Colombier 		mark(nn, 5);
1283e12c5d1SDavid du Colombier 		mark(nn, 7);
1293e12c5d1SDavid du Colombier 		for(i = 0, k = 11; k <= v; k += wheel[i]) {
1303e12c5d1SDavid du Colombier 			mark(nn, k);
1313e12c5d1SDavid du Colombier 			i++;
1323e12c5d1SDavid du Colombier 			if(i >= whsiz)
1333e12c5d1SDavid du Colombier 				i = 0;
1343e12c5d1SDavid du Colombier 		}
1353e12c5d1SDavid du Colombier /*
1363e12c5d1SDavid du Colombier  *	now get the primes from the table
1373e12c5d1SDavid du Colombier  *	and print them.
1383e12c5d1SDavid du Colombier  */
1393e12c5d1SDavid du Colombier 		for(i = 0; i < tsiz8; i += 2) {
1403e12c5d1SDavid du Colombier 			if(table[i>>3] & bittab[i&07])
1413e12c5d1SDavid du Colombier 				continue;
1423e12c5d1SDavid du Colombier 			temp = nn + i;
1433e12c5d1SDavid du Colombier 			if(temp > limit)
1443e12c5d1SDavid du Colombier 				exits(0);
1453e12c5d1SDavid du Colombier 			print("%.0f\n", temp);
146*0be94c91SDavid du Colombier //			if(limit >= big)
147*0be94c91SDavid du Colombier //				exits(0);
1483e12c5d1SDavid du Colombier 		}
1493e12c5d1SDavid du Colombier 		nn += tsiz8;
1503e12c5d1SDavid du Colombier 	}
1513e12c5d1SDavid du Colombier }
1523e12c5d1SDavid du Colombier 
1533e12c5d1SDavid du Colombier void
mark(double nn,long k)1543e12c5d1SDavid du Colombier mark(double nn, long k)
1553e12c5d1SDavid du Colombier {
1563e12c5d1SDavid du Colombier 	double t1;
1573e12c5d1SDavid du Colombier 	long j;
1583e12c5d1SDavid du Colombier 
1593e12c5d1SDavid du Colombier 	modf(nn/k, &t1);
1603e12c5d1SDavid du Colombier 	j = k*t1 - nn;
1613e12c5d1SDavid du Colombier 	if(j < 0)
1623e12c5d1SDavid du Colombier 		j += k;
1633e12c5d1SDavid du Colombier 	for(; j < tsiz8; j += k)
1643e12c5d1SDavid du Colombier 		table[j>>3] |= bittab[j&07];
1653e12c5d1SDavid du Colombier }
166