fix bugs when high bits on

This commit is contained in:
David Rose 2007-06-27 01:10:27 +00:00
parent f19a1c7584
commit f58157c60b

View File

@ -496,10 +496,16 @@ get_highest_off_bit() const {
template<class WType, int nbits> template<class WType, int nbits>
INLINE int BitMask<WType, nbits>:: INLINE int BitMask<WType, nbits>::
get_next_higher_different_bit(int low_bit) const { get_next_higher_different_bit(int low_bit) const {
nassertr(low_bit >= 0 && low_bit < num_bits, low_bit); // We are allowed to call this method with low_bit == num_bits,
// which is the highest value this method will return.
nassertr(low_bit >= 0, low_bit);
if (low_bit >= num_bits) {
return low_bit;
}
bool is_on = (_word & ((WordType)1 << low_bit));
WordType w; WordType w;
if (_word & ((WordType)1 << low_bit)) { if (is_on) {
// low_bit is 1. Get the next higher 0 bit. To do this, invert // low_bit is 1. Get the next higher 0 bit. To do this, invert
// the word and the get the next higher 1 bit. // the word and the get the next higher 1 bit.
w = ~_word; w = ~_word;
@ -508,20 +514,25 @@ get_next_higher_different_bit(int low_bit) const {
w = _word; w = _word;
} }
// Shift out all of the low bits. // Mask out all of the bits below low_bit. Since we already know
w >>= (low_bit + 1); // that low_bit is 0, we can use (1 << low_bit) instead of (1 <<
// (low_bit + 1)), which becomes undefined when (low_bit + 1) == 32.
w &= ~((1 << low_bit) - 1);
if (w == 0) { if (w == 0) {
// No more bits. // All higher bits in the word have the same value. Since every
return low_bit; // bit after the topmost bit is 0, we either return the topmost
// bit + 1 to indicate the next 0 bit, or low_bit to indicate we
// have reached the end of the number of bits.
return is_on ? num_bits : low_bit;
} else { } else {
// Now determine the lowest 1 bit in the remaining word. This // Now determine the lowest 1 bit in the remaining word. This
// operation will clear out all bits except for the lowest 1 bit. // operation will clear out all bits except for the lowest 1 bit.
w = (w & (~w + 1)); w = (w & (~w + 1));
// And the answer is the number of bits in (w - 1). // And the answer is the number of bits in (w - 1).
return count_bits_in_word(w - 1) + low_bit + 1; return count_bits_in_word(w - 1);
} }
} }