# Method to set the bits to "on" in an interval in a bit array.
# Returns the number of bits set.
def interval_set(start, stop)
- raise BitArrayError, "interval start < 0 (#{start} < 0)" if start < 0
- raise BitArrayError, "interval stop > bit array size (#{stop} > #{self.size})" if stop > self.size
- raise BitArrayError, "interval stop < interval start (#{stop} < #{start})" if stop < start
+ raise BitArrayError, "interval start < 0 (#{start} < 0)" if start < 0
+ raise BitArrayError, "interval stop > bit array size - 1 (#{stop} > #{self.size - 1})" if stop > self.size - 1
+ raise BitArrayError, "interval stop < interval start (#{stop} < #{start})" if stop < start
- mask = (2 ** BitsInChar) - 1 # 11111111
+ byte_start = start / BitsInChar
+ byte_stop = stop / BitsInChar
bits_start = start % BitsInChar
bits_stop = stop % BitsInChar
- mask_start = mask >> bits_start
- mask_stop = mask << (BitsInChar - bits_stop)
-
- self.byte_array[start / BitsInChar] |= mask_start if (stop / BitsInChar) != (start / BitsInChar)
- self.byte_array[stop / BitsInChar] |= mask_stop
+ mask = (2 ** BitsInChar) - 1 # 11111111
+
+ if byte_start == byte_stop
+ self.byte_array[byte_start] |= ((mask >> bits_start) & (mask << (BitsInChar - bits_stop - 1)))
+ else
+ if bits_start != 0
+ self.byte_array[byte_start] |= (mask >> bits_start)
+ byte_start += 1
+ end
- byte_start = (start + BitsInChar - bits_start) / BitsInChar
- byte_stop = stop / BitsInChar
+ self.byte_array[byte_stop] |= (mask << (BitsInChar - bits_stop - 1))
- (byte_start ... byte_stop).each do |pos|
- self.byte_array[pos] |= mask
+ if byte_start != byte_stop
+ self.byte_array[byte_start ... byte_stop] = mask
+ end
end
- stop - start
+ stop - start + 1
end
# Method to set the bits to "off" in an interval in a bit array.
# Returns the number of bits unset.
def interval_unset(start, stop)
- raise BitArrayError, "interval start < 0 (#{start} < 0)" if start < 0
- raise BitArrayError, "interval stop > bit array size (#{stop} > #{self.size})" if stop > self.size
- raise BitArrayError, "interval stop < interval start (#{stop} < #{start})" if stop < start
+ raise BitArrayError, "interval start < 0 (#{start} < 0)" if start < 0
+ raise BitArrayError, "interval stop > bit array size - 1 (#{stop} > #{self.size - 1})" if stop > self.size - 1
+ raise BitArrayError, "interval stop < interval start (#{stop} < #{start})" if stop < start
+
+ byte_start = start / BitsInChar
+ byte_stop = stop / BitsInChar
- (start ... stop).each do |pos|
- self.bit_unset(pos)
+ bits_start = start % BitsInChar
+ bits_stop = stop % BitsInChar
+
+ mask = (2 ** BitsInChar) - 1 # 11111111
+
+ if byte_start == byte_stop
+ self.byte_array[byte_start] &= ~((mask >> bits_start) & (mask << (BitsInChar - bits_stop - 1)))
+ else
+ if bits_start != 0
+ self.byte_array[byte_start] &= ~(mask >> bits_start)
+ byte_start += 1
+ end
+
+ self.byte_array[byte_stop] &= ~(mask << (BitsInChar - bits_stop - 1))
+
+ if byte_start != byte_stop
+ self.byte_array[byte_start ... byte_stop] = ~mask
+ end
end
- stop - start
+ stop - start + 1
end
# Method to locate intervals of bits set to "on" in a bit array.