primes.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <bio.h>
  12. double big = 9.007199254740992e15;
  13. int pt[] =
  14. {
  15. 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
  16. 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
  17. 73, 79, 83, 89, 97,101,103,107,109,113,
  18. 127,131,137,139,149,151,157,163,167,173,
  19. 179,181,191,193,197,199,211,223,227,229,
  20. };
  21. double wheel[] =
  22. {
  23. 10, 2, 4, 2, 4, 6, 2, 6, 4, 2,
  24. 4, 6, 6, 2, 6, 4, 2, 6, 4, 6,
  25. 8, 4, 2, 4, 2, 4, 8, 6, 4, 6,
  26. 2, 4, 6, 2, 6, 6, 4, 2, 4, 6,
  27. 2, 6, 4, 2, 4, 2,10, 2,
  28. };
  29. uint8_t table[1000];
  30. uint8_t bittab[] =
  31. {
  32. 1, 2, 4, 8, 16, 32, 64, 128,
  33. };
  34. enum {
  35. ptsiz = nelem(pt),
  36. whsiz = nelem(wheel),
  37. tabsiz = nelem(table),
  38. tsiz8 = tabsiz*8,
  39. };
  40. void mark(double nn, int32_t k);
  41. void
  42. usage(void)
  43. {
  44. fprint(2, "usage: %s [start [finish]]\n", argv0);
  45. exits("limits");
  46. }
  47. void
  48. ouch(void)
  49. {
  50. fprint(2, "limits exceeded\n");
  51. exits("limits");
  52. }
  53. void
  54. main(int argc, char *argv[])
  55. {
  56. int i;
  57. double k, temp, v, limit, nn;
  58. char *l;
  59. Biobuf bin;
  60. ARGBEGIN{
  61. default:
  62. usage();
  63. break;
  64. }ARGEND;
  65. nn = 0;
  66. limit = big;
  67. switch (argc) {
  68. case 0:
  69. Binit(&bin, 0, OREAD);
  70. while ((l = Brdline(&bin, '\n')) != nil) {
  71. if (*l == '\n')
  72. continue;
  73. nn = atof(l);
  74. if(nn < 0)
  75. sysfatal("negative start");
  76. break;
  77. }
  78. Bterm(&bin);
  79. break;
  80. case 2:
  81. limit = atof(argv[1]);
  82. if(limit < nn)
  83. exits(0);
  84. if(limit > big)
  85. ouch();
  86. /* fallthrough */
  87. case 1:
  88. nn = atof(argv[0]);
  89. break;
  90. default:
  91. usage();
  92. break;
  93. }
  94. if(nn < 0 || nn > big)
  95. ouch();
  96. if(nn == 0)
  97. nn = 1;
  98. if(nn < 230) {
  99. for(i=0; i<ptsiz; i++) {
  100. if(pt[i] < nn)
  101. continue;
  102. if(pt[i] > limit)
  103. exits(0);
  104. print("%d\n", pt[i]);
  105. // if(limit >= big)
  106. // exits(0);
  107. }
  108. nn = 230;
  109. }
  110. modf(nn/2, &temp);
  111. nn = 2*temp + 1;
  112. /*
  113. * clear the sieve table.
  114. */
  115. for(;;) {
  116. for(i = 0; i < tabsiz; i++)
  117. table[i] = 0;
  118. /*
  119. * run the sieve.
  120. */
  121. v = sqrt(nn+tsiz8);
  122. mark(nn, 3);
  123. mark(nn, 5);
  124. mark(nn, 7);
  125. for(i = 0, k = 11; k <= v; k += wheel[i]) {
  126. mark(nn, k);
  127. i++;
  128. if(i >= whsiz)
  129. i = 0;
  130. }
  131. /*
  132. * now get the primes from the table
  133. * and print them.
  134. */
  135. for(i = 0; i < tsiz8; i += 2) {
  136. if(table[i>>3] & bittab[i&07])
  137. continue;
  138. temp = nn + i;
  139. if(temp > limit)
  140. exits(0);
  141. print("%.0f\n", temp);
  142. // if(limit >= big)
  143. // exits(0);
  144. }
  145. nn += tsiz8;
  146. }
  147. }
  148. void
  149. mark(double nn, int32_t k)
  150. {
  151. double t1;
  152. int32_t j;
  153. modf(nn/k, &t1);
  154. j = k*t1 - nn;
  155. if(j < 0)
  156. j += k;
  157. for(; j < tsiz8; j += k)
  158. table[j>>3] |= bittab[j&07];
  159. }