diff --git a/lib/bitarray-array.rb b/lib/bitarray-array.rb deleted file mode 100644 index 2191ffb..0000000 --- a/lib/bitarray-array.rb +++ /dev/null @@ -1,51 +0,0 @@ -class BitArray - attr_reader :size - attr_reader :field - include Enumerable - - VERSION = "1.3.0" - ELEMENT_WIDTH = 32 - - def initialize(size, field = nil) - @size = size - @field = field || Array.new(((size - 1) / ELEMENT_WIDTH) + 1, 0) - end - - # Set a bit (1/0) - def []=(position, value) - if value == 1 - @field[position / ELEMENT_WIDTH] |= 1 << (position % ELEMENT_WIDTH) - elsif (@field[position / ELEMENT_WIDTH]) & (1 << (position % ELEMENT_WIDTH)) != 0 - @field[position / ELEMENT_WIDTH] ^= 1 << (position % ELEMENT_WIDTH) - end - end - - # Read a bit (1/0) - def [](position) - @field[position / ELEMENT_WIDTH] & 1 << (position % ELEMENT_WIDTH) > 0 ? 1 : 0 - end - - # Iterate over each bit - def each - return to_enum unless block_given? - @size.times { |position| yield self[position] } - end - - # Returns the field as a string like "0101010100111100," etc. - def to_s - @field.collect{|ea| ("%0#{ELEMENT_WIDTH}b" % ea).reverse}.join[0..@size-1] - end - - # Iterate over each byte - def each_byte - return to_enum(:each_byte) unless block_given? - @field.each { |byte| yield byte } - end - - # Returns the total number of bits that are set - # Use Brian Kernighan's way, see - # https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan - def total_set - @field.each_byte.inject(0) { |a, byte| (a += 1; byte &= byte - 1) while byte > 0 ; a } - end -end diff --git a/lib/bitarray.rb b/lib/bitarray.rb index 992d753..e70e66c 100644 --- a/lib/bitarray.rb +++ b/lib/bitarray.rb @@ -1,59 +1 @@ -class BitArray - attr_reader :size - attr_reader :field - include Enumerable - - VERSION = "1.3.0" - - def initialize(size, field = nil, reverse_byte: true) - @size = size - @field = field || "\0" * (size / 8 + 1) - @reverse_byte = reverse_byte - end - - # Set a bit (1/0) - def []=(position, value) - if value == 1 - @field.setbyte(position >> 3, @field.getbyte(position >> 3) | (1 << (byte_position(position) % 8))) - else - @field.setbyte(position >> 3, @field.getbyte(position >> 3) & ~(1 << (byte_position(position) % 8))) - end - end - - # Read a bit (1/0) - def [](position) - (@field.getbyte(position >> 3) & (1 << (byte_position(position) % 8))) > 0 ? 1 : 0 - end - - # Iterate over each bit - def each - return to_enum(:each) unless block_given? - @size.times { |position| yield self[position] } - end - - # Returns the field as a string like "0101010100111100," etc. - def to_s - if @reverse_byte - @field.bytes.collect { |ea| ("%08b" % ea).reverse }.join[0, @size] - else - @field.bytes.collect { |ea| ("%08b" % ea) }.join[0, @size] - end - end - - # Iterates over each byte - def each_byte - return to_enum(:each_byte) unless block_given? - @field.bytes.each{ |byte| yield byte } - end - - # Returns the total number of bits that are set - # Use Brian Kernighan's way, see - # https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan - def total_set - @field.each_byte.inject(0) { |a, byte| (a += 1; byte &= byte - 1) while byte > 0 ; a } - end - - def byte_position(position) - @reverse_byte ? position : 7 - position - end -end +require_relative "bitarray/bit_array" diff --git a/lib/bitarray/bit_array.rb b/lib/bitarray/bit_array.rb new file mode 100644 index 0000000..476c34a --- /dev/null +++ b/lib/bitarray/bit_array.rb @@ -0,0 +1,58 @@ +class BitArray + attr_reader :field, :reverse_byte, :size + include Enumerable + + VERSION = "1.3.0" + + def initialize(size, field = nil, reverse_byte: true) + @size = size + @field = field || "\0" * (size / 8 + 1) + @reverse_byte = reverse_byte + end + + # Set a bit (1/0) + def []=(position, value) + if value == 1 + @field.setbyte(position >> 3, @field.getbyte(position >> 3) | (1 << (byte_position(position) % 8))) + else + @field.setbyte(position >> 3, @field.getbyte(position >> 3) & ~(1 << (byte_position(position) % 8))) + end + end + + # Read a bit (1/0) + def [](position) + (@field.getbyte(position >> 3) & (1 << (byte_position(position) % 8))) > 0 ? 1 : 0 + end + + # Iterate over each bit + def each + return to_enum(:each) unless block_given? + @size.times { |position| yield self[position] } + end + + # Returns the field as a string like "0101010100111100," etc. + def to_s + if @reverse_byte + @field.bytes.collect { |ea| ("%08b" % ea).reverse }.join[0, @size] + else + @field.bytes.collect { |ea| ("%08b" % ea) }.join[0, @size] + end + end + + # Iterates over each byte + def each_byte + return to_enum(:each_byte) unless block_given? + @field.bytes.each{ |byte| yield byte } + end + + # Returns the total number of bits that are set + # Use Brian Kernighan's way, see + # https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan + def total_set + @field.each_byte.inject(0) { |a, byte| (a += 1; byte &= byte - 1) while byte > 0 ; a } + end + + private def byte_position(position) + @reverse_byte ? position : 7 - position + end +end diff --git a/test/test_bitarray.rb b/test/test_bit_array.rb similarity index 100% rename from test/test_bitarray.rb rename to test/test_bit_array.rb