# Method to set a bit to 1 at a given position in the bit array.
def bit_set(pos)
- raise BitArrayError, "Position #{pos} must be an integer." unless pos.is_a? Fixnum
- raise BitArrayError, "Position #{pos} outside of range: 0 ... #{@size}" unless (0 ... @size ).include? pos
+ raise BitArrayError, "Position #{pos} must be an integer." unless pos.is_a? Fixnum
+ raise BitArrayError, "Position #{pos} outside of range: 0 ... #{@size - 1}" unless (0 ... @size ).include? pos
@byte_array[byte_pos(pos)] = @byte_array[byte_pos(pos)] | bit_pos(pos)
end
# Method to set a bit to 0 at a given position in the bit array.
def bit_unset(pos)
- raise BitArrayError, "Position #{pos} must be an integer." unless pos.is_a? Fixnum
- raise BitArrayError, "Position #{pos} outside of range: 0 ... #{@size}" unless (0 ... @size ).include? pos
+ raise BitArrayError, "Position #{pos} must be an integer." unless pos.is_a? Fixnum
+ raise BitArrayError, "Position #{pos} outside of range: 0 ... #{@size - 1}" unless (0 ... @size ).include? pos
mask = bit_pos(pos)
mask = ~mask
# Method to check if a bit at a given position in the bit array is set.
def bit_set?(pos)
- raise BitArrayError, "Position #{pos} must be an integer." unless pos.is_a? Fixnum
- raise BitArrayError, "Position #{pos} outside of range: 0 ... #{@size}" unless (0 ... @size ).include? pos
+ raise BitArrayError, "Position #{pos} must be an integer." unless pos.is_a? Fixnum
+ raise BitArrayError, "Position #{pos} outside of range: 0 ... #{@size - 1}" unless (0 ... @size ).include? pos
(@byte_array[byte_pos(pos)] & bit_pos(pos)) != 0
end
# Method to locate intervals of bits set to "on" in a bit array.
# BitArray.each_interval -> Array
# BitArray.each_interval { |start, stop| } -> Fixnum
- def each_interval
+ def each_interval_old
intervals = []
- start = 0
- stop = 0
+ bit_start = 0
+ bit_stop = 0
- while start < self.size
- if self.bit_set?(start)
- stop = start
+ while bit_start < self.size
+ bit_start += 1 while bit_start < self.size and not self.bit_set?(bit_start)
+ bit_stop = bit_start
+ bit_stop += 1 while bit_stop < self.size and self.bit_set?(bit_stop)
- while stop < self.size and self.bit_set?(stop)
- stop += 1
- end
+ if block_given?
+ yield bit_start, bit_stop
+ else
+ intervals << [bit_start, bit_stop]
+ end
+
+ bit_start = bit_stop + 1
+ end
+
+ return intervals unless block_given?
+ end
+
+ # Method to locate intervals of bits set to "on" in a bit array.
+ # BitArray.each_interval -> Array
+ # BitArray.each_interval { |start, stop| } -> Fixnum
+ def each_interval
+ intervals = []
+ byte_start = 0
+ bit_start = 0
+
+ while bit_start < self.size
+# puts "0 byte_start: #{byte_start} bit_start: #{bit_start}"
+ byte_start += 1 while byte_start < self.byte_array.size and self.byte_array[byte_start] == 0
+ bit_start += byte_start * BitsInChar
+ bit_start += 1 while bit_start < self.size and not self.bit_set?(bit_start)
+
+# puts "1 byte_start: #{byte_start} bit_start: #{bit_start}"
+
+ if bit_start < self.size
+ bit_stop = bit_start
+ byte_stop = byte_start
+# puts "1.5 byte_stop: #{byte_stop} bit_stop: #{bit_stop}"
+ byte_stop += 1 while byte_stop < self.byte_array.size and self.byte_array[byte_stop] == ~0
+ bit_stop += (byte_stop - byte_start) * BitsInChar
+# puts "1.5 byte_stop: #{byte_stop} bit_stop: #{bit_stop}"
+ bit_stop += 1 while bit_stop < self.size and self.bit_set?(bit_stop)
+
+# puts "2 byte_stop: #{byte_stop} bit_stop: #{bit_stop}"
if block_given?
- yield start, stop
+ yield bit_start, bit_stop - 1
else
- intervals << [start, stop]
+ intervals << [bit_start, bit_stop - 1]
end
- end
- stop > start ? start = stop : start += 1
+ byte_start = byte_stop
+ bit_start = bit_stop + 1
+ end
end
return intervals unless block_given?