public void andNot(BitSet set) { // a & !a is false if (this == set) { // all falses result in an empty BitSet clear(); return; } // trim the second set to avoid extra work trimToSize(array); int length = array.length(); // truth table // // case | a | b | !b | a & !b | change? // 1 | false | false | true | false | a is already false // 2 | false | true | false | false | a is already false // 3 | true | false | true | true | a is already true // 4 | true | true | false | false | set a to false // // we only need to change something in case 4 // whenever b is true, a should be false, so iterate over set b int index = 0; while ((index = nextSetWord(set.array, index)) != -1) { setWord(array, index, getWord(array, index) & ~set.array.get(index)); if (++index >= length) { // nothing further will affect anything break; } } }
public void and(BitSet set) { // a & a is just a if (this == set) { return; } // trim the second set to avoid extra work trimToSize(set.array); // check if the length is longer than otherLength int otherLength = set.array.length(); if (array.length() > otherLength) { // shrink the array, effectively ANDing those bits to false setLengthWords(array, otherLength); } // truth table // // case | a | b | a & b | change? // 1 | false | false | false | a is already false // 2 | false | true | false | a is already false // 3 | true | false | false | set a to false // 4 | true | true | true | a is already true // // we only need to change something in case 3, so iterate over set a int index = 0; while ((index = nextSetWord(array, index)) != -1) { setWord(array, index, array.get(index) & getWord(set.array, index)); index++; } }
// clears one bit private static void clear(JsArrayInteger array, int bitIndex) { int index = wordIndex(bitIndex); int word = getWord(array, index); if (word != 0) { // mask the correct bit out setWord(array, index, word & ~(1 << (bitOffset(bitIndex)))); } }
// flips all bits stored at a certain index private static void flipWord(JsArrayInteger array, int index) { int word = getWord(array, index); if (word == 0) { array.set(index, 0xffffffff); } else { word = ~word; setWord(array, index, word); } }
// flips all bits stored at a certain index within the given range private static void flipMaskedWord(JsArrayInteger array, int index, int from, int to) { if (from == to) { return; } // get the bits int word = getWord(array, index); // adjust "to" so it will shift out those bits to = 32 - to; // create a mask and XOR it in word ^= (((0xffffffff >>> from) << from) << to) >>> to; ; setWord(array, index, word); }
// flips one bit private static void flip(JsArrayInteger array, int bitIndex) { // calculate index and offset int index = wordIndex(bitIndex); int offset = bitOffset(bitIndex); // figure out if the bit is on or off int word = getWord(array, index); if (((word >>> offset) & 1) == 1) { // if on, turn it off setWord(array, index, word & ~(1 << offset)); } else { // if off, turn it on array.set(index, word | (1 << offset)); } };
// sets all bits to false at a certain index within the given bit range private static void maskOutWord(JsArrayInteger array, int index, int from, int to) { int word = getWord(array, index); // something only happens if word has bits set if (word != 0) { // create a mask int mask; if (from != 0) { mask = 0xffffffff >>> (32 - from); } else { mask = 0; } // shifting by 32 is the same as shifting by 0 if (to != 32) { mask |= 0xffffffff << to; } // mask it out word &= mask; setWord(array, index, word); } }
public void or(BitSet set) { // a | a is just a if (this == set) { return; } // truth table // // case | a | b | a | b | change? // 1 | false | false | false | a is already false // 2 | false | true | true | set a to true // 3 | true | false | true | a is already true // 4 | true | true | true | a is already true // // we only need to change something in case 2 // case 2 only happens when b is true, so iterate over set b int index = 0; while ((index = nextSetWord(set.array, index)) != -1) { setWord(array, index, getWord(array, index) | set.array.get(index)); index++; } }
public void xor(BitSet set) { // a ^ a is false if (this == set) { // this results in an empty BitSet clear(); return; } // truth table // // case | a | b | a ^ b | change? // 1 | false | false | false | a is already false // 2 | false | true | true | set a to true // 3 | true | false | true | a is already true // 4 | true | true | false | set a to false // // we need to change something in cases 2 and 4 // cases 2 and 4 only happen when b is true, so iterate over set b int index = 0; while ((index = nextSetWord(set.array, index)) != -1) { setWord(array, index, getWord(array, index) ^ set.array.get(index)); index++; } }