123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- /*
- * I use 0 to represent prime and 1 to represent not prime,
- * because a byte[] is initialized to all 0.
- *
- * Stores prime/not prime in all 8 bits in each byte.
- */
-
- import java.util.ArrayList;
-
- class Sieve {
- public byte[] arr;
- public int maxNum;
- public boolean smallPrimesGenerated = false;
-
- private int sqrtNum;
- private int numPrimes = 0;
- private int[] primes = null;
-
- Sieve(int maxNum, byte[] arr) {
- this.maxNum = maxNum;
- this.sqrtNum = (int)Math.ceil(Math.sqrt(maxNum));
- this.arr = arr;
- }
- Sieve(int maxNum) {
- this(maxNum, new byte[(maxNum / 16) + 1]);
- }
-
- public int[] getPrimes() {
- if (primes == null) {
- primes = new int[(maxNum / ((int)Math.log(maxNum) - 1)) + 1];
-
- int i = 0;
- primes[i++] = 2;
- for (int p = 3; p < maxNum; p += 2) {
- if (isPrime(p))
- primes[i++] = p;
- }
- }
-
- return primes;
- }
-
- // Find all prime numbers.
- public void generatePrimes(int step, int offset) {
- if (!smallPrimesGenerated)
- generateSmallPrimes();
-
- for (int i = 2 + offset; i <= sqrtNum; i += (step * 2)) {
- if (isPrime(i)) {
- setNotPrimes(i, maxNum);
- }
- }
- }
- public void generatePrimes() {
- generatePrimes(1, 1);
- }
-
- // Set all multiples of i as not primes
- private void setBigPrimes(int i) {
- int j = 1;
- }
-
- // Find the first sqrt(n) prime numbers, and set them
- // as not prime.
- public void generateSmallPrimes() {
- smallPrimesGenerated = true;
- for (int i = 3; i <= sqrtNum; i += 2) {
- if (isPrime(i))
- setNotPrimes(i, sqrtNum);
- }
- }
-
- // Check whether a number is prime (aka if its bit is 0)
- public boolean isPrime(int i) {
- if (i == 2)
- return true;
- if ((i & 1) == 0)
- return false;
-
- byte b = arr[byteIndex(i)];
- return (b & (1 << bitIndex(i))) == 0;
- }
-
- // Set all multiples of i under sqrt(n) as not primes
- private void setNotPrimes(int min, int max) {
- int j = min;
- min *= 2;
- int mul = 3;
- while (min <= max) {
- setNotPrime(min);
- min = j * mul;
- mul += 2;
- }
- }
-
- // Get the byte a number's bit is in
- private int byteIndex(int i) {
- return i >> 4;
- }
-
- // Get what bit in the byte a number is in
- private int bitIndex(int i) {
- return (i % 16) >> 1;
- }
-
- // Set a number to be not prime (aka set its bit to 1)
- private void setNotPrime(int i) {
-
- // No need to store even numbers
- if (i % 2 == 0)
- return;
-
- int bi = byteIndex(i);
- arr[bi] = (byte)(arr[bi] | (1 << bitIndex(i)));
- }
- }
|