From f58157c60be2cf0c5a409cb11ac4625f0b84f416 Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 27 Jun 2007 01:10:27 +0000 Subject: [PATCH] fix bugs when high bits on --- panda/src/putil/bitMask.I | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/panda/src/putil/bitMask.I b/panda/src/putil/bitMask.I index 993c35128a..e684b4c320 100644 --- a/panda/src/putil/bitMask.I +++ b/panda/src/putil/bitMask.I @@ -496,10 +496,16 @@ get_highest_off_bit() const { template INLINE int BitMask:: 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; - if (_word & ((WordType)1 << low_bit)) { + if (is_on) { // low_bit is 1. Get the next higher 0 bit. To do this, invert // the word and the get the next higher 1 bit. w = ~_word; @@ -508,20 +514,25 @@ get_next_higher_different_bit(int low_bit) const { w = _word; } - // Shift out all of the low bits. - w >>= (low_bit + 1); + // Mask out all of the bits below low_bit. Since we already know + // 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) { - // No more bits. - return low_bit; + // All higher bits in the word have the same value. Since every + // 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 { // Now determine the lowest 1 bit in the remaining word. This // operation will clear out all bits except for the lowest 1 bit. w = (w & (~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); } }