Module: TrickBag::Numeric::BitMapping
- Defined in:
- lib/trick_bag/numeric/bit_mapping.rb
Overview
Provides methods for converting between the various representations of a bitmap: number, binary encoded string, array, and sparse array.
Where an array is used to represent bits, the first element (#0) will be the high bit and the last element will be the low (1’s column) bit.
Class Method Summary collapse
-
.assert_non_negative(number) ⇒ Object
If number is negative, raises an ArgumentError; else does nothing.
-
.binary_string_to_bit_array(string, minimum_binary_places = 0) ⇒ Object
Converts a binary string to an array of bit values, e.g.
-
.binary_string_to_number(string) ⇒ Object
Converts from a binary string to a number, e.g.
-
.bit_array_to_number(bit_array) ⇒ Object
Converts an array of bit values, e.g.
-
.number_to_binary_string(number, min_length = 0) ⇒ Object
Converts a number to a binary encoded string, e.g.
-
.number_to_bit_array(number, minimum_binary_places = 0) ⇒ Object
Converts a number to an array of bit values, e.g.
-
.number_to_place_value_array(number) ⇒ Object
Converts a number to an array of place values, e.g.
-
.number_to_set_bit_positions_array(number) ⇒ Object
Converts a number to a sparse array containing bit positions that are set/true/1.
-
.place_value_array_to_number(place_value_array) ⇒ Object
Converts from a value array to a number, e.g.
-
.reverse_binary_string_bits(binary_string) ⇒ Object
Reverses a binary string.
-
.set_bit_position_array_to_number(position_array) ⇒ Object
Converts an array of bit position numbers to a numeric value, e.g.
Class Method Details
.assert_non_negative(number) ⇒ Object
If number is negative, raises an ArgumentError; else does nothing.
118 119 120 121 122 123 124 |
# File 'lib/trick_bag/numeric/bit_mapping.rb', line 118 def assert_non_negative(number) unless number.is_a?(Integer) && number >= 0 raise ArgumentError.new( "Parameter must be a nonnegative Integer (Fixnum, Bignum) " + "but is #{number.inspect} (a #{number.class})") end end |
.binary_string_to_bit_array(string, minimum_binary_places = 0) ⇒ Object
Converts a binary string to an array of bit values, e.g. “x0C” => [1, 1, 0, 0]
111 112 113 114 |
# File 'lib/trick_bag/numeric/bit_mapping.rb', line 111 def binary_string_to_bit_array(string, minimum_binary_places = 0) number = binary_string_to_number(string) number_to_bit_array(number, minimum_binary_places) end |
.binary_string_to_number(string) ⇒ Object
Converts from a binary string to a number, e.g. “x01x00” => 256
15 16 17 18 19 20 |
# File 'lib/trick_bag/numeric/bit_mapping.rb', line 15 def binary_string_to_number(string) string = string.clone.force_encoding(Encoding::ASCII_8BIT) string.bytes.inject(0) do |number, byte| number * 256 + byte.ord end end |
.bit_array_to_number(bit_array) ⇒ Object
Converts an array of bit values, e.g. [1, 0, 0, 1], to a number, e.g. 9
74 75 76 77 78 79 80 81 82 |
# File 'lib/trick_bag/numeric/bit_mapping.rb', line 74 def bit_array_to_number(bit_array) return nil if bit_array.empty? multiplier = 1 bit_array.reverse.inject(0) do |result, n| result += n * multiplier multiplier *= 2 result end end |
.number_to_binary_string(number, min_length = 0) ⇒ Object
Converts a number to a binary encoded string, e.g. 256 => “x01x00”
24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/trick_bag/numeric/bit_mapping.rb', line 24 def number_to_binary_string(number, min_length = 0) assert_non_negative(number) binary_string = ''.force_encoding(Encoding::ASCII_8BIT) while number > 0 byte_value = number & 0xFF binary_string << byte_value number >>= 8 end binary_string.reverse.rjust(min_length, "\x00") end |
.number_to_bit_array(number, minimum_binary_places = 0) ⇒ Object
Converts a number to an array of bit values, e.g. 9 => [1, 0, 0, 1]
59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/trick_bag/numeric/bit_mapping.rb', line 59 def number_to_bit_array(number, minimum_binary_places = 0) assert_non_negative(number) array = [] while number > 0 array << (number & 1) number >>= 1 end array.reverse! zero_pad_count = minimum_binary_places - array.size zero_pad_count.times { array.unshift(0) } array end |
.number_to_place_value_array(number) ⇒ Object
Converts a number to an array of place values, e.g. 9 => [8, 0, 0, 1]
39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/trick_bag/numeric/bit_mapping.rb', line 39 def number_to_place_value_array(number) assert_non_negative(number) array = [] bit_value = 1 while number > 0 array << ((number & 1 == 1) ? bit_value : 0) number >>= 1 bit_value <<= 1 end array.reverse end |
.number_to_set_bit_positions_array(number) ⇒ Object
Converts a number to a sparse array containing bit positions that are set/true/1. Note that these are bit positions, e.g. 76543210, and not bit column values such as 128/64/32/16/8/4/2/1.
88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/trick_bag/numeric/bit_mapping.rb', line 88 def number_to_set_bit_positions_array(number) assert_non_negative(number) array = [] position = 0 while number > 0 array << position if number & 1 == 1 position += 1 number >>= 1 end array end |
.place_value_array_to_number(place_value_array) ⇒ Object
Converts from a value array to a number, e.g. [8, 0, 0, 1] => 9
53 54 55 |
# File 'lib/trick_bag/numeric/bit_mapping.rb', line 53 def place_value_array_to_number(place_value_array) place_value_array.inject(&:+) end |
.reverse_binary_string_bits(binary_string) ⇒ Object
Reverses a binary string. Note that it is not enough to reverse the string itself because although the bytes would be reversed, the bits within each byte would not.
129 130 131 132 133 134 |
# File 'lib/trick_bag/numeric/bit_mapping.rb', line 129 def reverse_binary_string_bits(binary_string) binary_place_count = binary_string.size * 8 reversed_bit_array = binary_string_to_bit_array(binary_string, binary_place_count).reverse number = bit_array_to_number(reversed_bit_array) number_to_binary_string(number) end |
.set_bit_position_array_to_number(position_array) ⇒ Object
Converts an array of bit position numbers to a numeric value, e.g. [0, 2] => 5
102 103 104 105 106 107 |
# File 'lib/trick_bag/numeric/bit_mapping.rb', line 102 def set_bit_position_array_to_number(position_array) return nil if position_array.empty? position_array.inject(0) do |result, n| result += 2 ** n end end |