1 5 6 9 10 package java.math; 11 12 32 class BitSieve { 33 36 private long bits[]; 37 38 41 private int length; 42 43 47 private static BitSieve smallSieve = new BitSieve (); 48 49 60 private BitSieve() { 61 length = 150 * 64; 62 bits = new long[(unitIndex(length - 1) + 1)]; 63 64 set(0); 66 int nextIndex = 1; 67 int nextPrime = 3; 68 69 do { 71 sieveSingle(length, nextIndex + nextPrime, nextPrime); 72 nextIndex = sieveSearch(length, nextIndex + 1); 73 nextPrime = 2*nextIndex + 1; 74 } while((nextIndex > 0) && (nextPrime < length)); 75 } 76 77 82 BitSieve(BigInteger base, int searchLen) { 83 90 bits = new long[(unitIndex(searchLen-1) + 1)]; 91 length = searchLen; 92 int start = 0; 93 94 int step = smallSieve.sieveSearch(smallSieve.length, start); 95 int convertedStep = (step *2) + 1; 96 97 MutableBigInteger r = new MutableBigInteger (); 99 MutableBigInteger q = new MutableBigInteger (); 100 do { 101 r.copyValue(base.mag); 103 r.divideOneWord(convertedStep, q); 104 start = r.value[r.offset]; 105 106 start = convertedStep - start; 108 if (start%2 == 0) 109 start += convertedStep; 110 sieveSingle(searchLen, (start-1)/2, convertedStep); 111 112 step = smallSieve.sieveSearch(smallSieve.length, step+1); 114 convertedStep = (step *2) + 1; 115 } while (step > 0); 116 } 117 118 121 private static int unitIndex(int bitIndex) { 122 return bitIndex >>> 6; 123 } 124 125 128 private static long bit(int bitIndex) { 129 return 1L << (bitIndex & ((1<<6) - 1)); 130 } 131 132 135 private boolean get(int bitIndex) { 136 int unitIndex = unitIndex(bitIndex); 137 return ((bits[unitIndex] & bit(bitIndex)) != 0); 138 } 139 140 143 private void set(int bitIndex) { 144 int unitIndex = unitIndex(bitIndex); 145 bits[unitIndex] |= bit(bitIndex); 146 } 147 148 153 private int sieveSearch(int limit, int start) { 154 if (start >= limit) 155 return -1; 156 157 int index = start; 158 do { 159 if (!get(index)) 160 return index; 161 index++; 162 } while(index < limit-1); 163 return -1; 164 } 165 166 171 private void sieveSingle(int limit, int start, int step) { 172 while(start < limit) { 173 set(start); 174 start += step; 175 } 176 } 177 178 181 BigInteger retrieve(BigInteger initValue, int certainty) { 182 int offset = 1; 184 for (int i=0; i<bits.length; i++) { 185 long nextLong = ~bits[i]; 186 for (int j=0; j<64; j++) { 187 if ((nextLong & 1) == 1) { 188 BigInteger candidate = initValue.add( 189 BigInteger.valueOf(offset)); 190 if (candidate.primeToCertainty(certainty)) 191 return candidate; 192 } 193 nextLong >>>= 1; 194 offset+=2; 195 } 196 } 197 return null; 198 } 199 } 200 | Popular Tags |