trick_bag 0.56.0 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/RELEASE_NOTES.md +5 -0
- data/lib/trick_bag/numeric/bit_mapping.rb +124 -0
- data/lib/trick_bag/numeric/bitmap.rb +30 -133
- data/lib/trick_bag/version.rb +1 -1
- data/spec/trick_bag/numeric/bit_mapping_spec.rb +142 -0
- data/spec/trick_bag/numeric/bitmap_spec.rb +11 -142
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 012936fb2a08c5a0cf646ecf9e8895f8cb122aab
|
|
4
|
+
data.tar.gz: 11402a3ba146571b4648829b922db87aca0b62bd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 416fdc0e04db515bcec0a0462308165a49e4b5c8a6c250c8624ec2bcd00811da27fd784cabecb72830e1cd90d5492aad495f22ab4e54439544097511f9519735
|
|
7
|
+
data.tar.gz: ef625fb8bee7da8734ba483071f64c24d5b3c7abb3ca6a2a05c767b1d32f733e59ce7d5d3e07cc87a48d74843c5cdb8e6857b22bc2220f30c6ff4e7b8c80f11a
|
data/RELEASE_NOTES.md
CHANGED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
module TrickBag
|
|
2
|
+
module Numeric
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# Provides methods for converting between the various representations
|
|
6
|
+
# of a bitmap: number, binary encoded string, array, and sparse array.
|
|
7
|
+
#
|
|
8
|
+
# Where an array is used to represent bits, the first element (#0) will be the
|
|
9
|
+
# high bit and the last element will be the low (1's column) bit.
|
|
10
|
+
module BitMapping
|
|
11
|
+
|
|
12
|
+
module_function
|
|
13
|
+
|
|
14
|
+
# Converts from a binary string to a number, e.g. "\x01\x00" => 256
|
|
15
|
+
def binary_string_to_number(string)
|
|
16
|
+
string = string.clone.force_encoding(Encoding::ASCII_8BIT)
|
|
17
|
+
string.bytes.inject(0) do |number, byte|
|
|
18
|
+
number * 256 + byte.ord
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# Converts a number to a binary encoded string, e.g. 256 => "\x01\x00"
|
|
24
|
+
def number_to_binary_string(number, min_length = 0)
|
|
25
|
+
assert_non_negative(number)
|
|
26
|
+
binary_string = ''.force_encoding(Encoding::ASCII_8BIT)
|
|
27
|
+
|
|
28
|
+
while number > 0
|
|
29
|
+
byte_value = number & 0xFF
|
|
30
|
+
binary_string << byte_value
|
|
31
|
+
number >>= 8
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
binary_string.reverse.rjust(min_length, "\x00")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# Converts a number to an array of place values, e.g. 9 => [8, 0, 0, 1]
|
|
39
|
+
def number_to_place_value_array(number)
|
|
40
|
+
assert_non_negative(number)
|
|
41
|
+
array = []
|
|
42
|
+
bit_value = 1
|
|
43
|
+
while number > 0
|
|
44
|
+
array << ((number & 1 == 1) ? bit_value : 0)
|
|
45
|
+
number >>= 1
|
|
46
|
+
bit_value <<= 1
|
|
47
|
+
end
|
|
48
|
+
array.reverse
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# Converts from a value array to a number, e.g. [8, 0, 0, 1] => 9
|
|
53
|
+
def place_value_array_to_number(place_value_array)
|
|
54
|
+
place_value_array.inject(&:+)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# Converts a number to an array of bit values, e.g. 9 => [1, 0, 0, 1]
|
|
59
|
+
def number_to_bit_array(number)
|
|
60
|
+
assert_non_negative(number)
|
|
61
|
+
array = []
|
|
62
|
+
while number > 0
|
|
63
|
+
array << (number & 1)
|
|
64
|
+
number >>= 1
|
|
65
|
+
end
|
|
66
|
+
array.reverse
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# Converts an array of bit values, e.g. [1, 0, 0, 1], to a number, e.g. 9
|
|
71
|
+
def bit_array_to_number(bit_array)
|
|
72
|
+
return nil if bit_array.empty?
|
|
73
|
+
multiplier = 1
|
|
74
|
+
bit_array.reverse.inject(0) do |result, n|
|
|
75
|
+
result += n * multiplier
|
|
76
|
+
multiplier *= 2
|
|
77
|
+
result
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# Converts a number to a sparse array containing bit positions that are set/true/1.
|
|
83
|
+
# Note that these are bit positions, e.g. 76543210, and not bit column values
|
|
84
|
+
# such as 128/64/32/16/8/4/2/1.
|
|
85
|
+
def number_to_set_bit_positions_array(number)
|
|
86
|
+
assert_non_negative(number)
|
|
87
|
+
array = []
|
|
88
|
+
position = 0
|
|
89
|
+
while number > 0
|
|
90
|
+
array << position if number & 1 == 1
|
|
91
|
+
position += 1
|
|
92
|
+
number >>= 1
|
|
93
|
+
end
|
|
94
|
+
array
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# Converts an array of bit position numbers to a numeric value, e.g. [0, 2] => 5
|
|
99
|
+
def set_bit_position_array_to_number(position_array)
|
|
100
|
+
return nil if position_array.empty?
|
|
101
|
+
position_array.inject(0) do |result, n|
|
|
102
|
+
result += 2 ** n
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
# Converts a binary string to an array of bit values, e.g. "\x0C" => [1, 1, 0, 0]
|
|
108
|
+
def binary_string_to_bit_array(string)
|
|
109
|
+
number = binary_string_to_number(string)
|
|
110
|
+
number_to_bit_array(number)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
# If number is negative, raises an ArgumentError; else does nothing.
|
|
115
|
+
def assert_non_negative(number)
|
|
116
|
+
unless number.is_a?(Integer) && number >= 0
|
|
117
|
+
raise ArgumentError.new(
|
|
118
|
+
"Parameter must be a nonnegative Integer (Fixnum, Bignum) " +
|
|
119
|
+
"but is #{number.inspect} (a #{number.class})")
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
require 'forwardable'
|
|
2
|
+
require_relative 'bit_mapping'
|
|
2
3
|
|
|
3
4
|
module TrickBag
|
|
4
5
|
module Numeric
|
|
5
6
|
|
|
6
7
|
|
|
7
|
-
#
|
|
8
|
-
# of a bitmap: number, binary encoded string, array, and sparse array.
|
|
9
|
-
#
|
|
10
|
-
# An instance can be created that will hold on to bitmap data and be used
|
|
8
|
+
# Instances of this class can be created that will hold on to bitmap data and be used
|
|
11
9
|
# to test bits and convert to other formats.
|
|
10
|
+
#
|
|
11
|
+
# Where an array is used to represent bits, the first element (#0) will be the
|
|
12
|
+
# high bit and the last element will be the low (1's column) bit.
|
|
12
13
|
class Bitmap
|
|
13
14
|
|
|
14
15
|
extend Forwardable
|
|
@@ -16,12 +17,14 @@ class Bitmap
|
|
|
16
17
|
# This is the internal representation of the bitmap value:
|
|
17
18
|
attr_reader :number
|
|
18
19
|
|
|
20
|
+
# Some instance methods can be delegated to this number:
|
|
19
21
|
[:&, :|, :^, :hash].each do |method_name|
|
|
20
22
|
def_delegator :@number, method_name
|
|
21
23
|
end
|
|
22
24
|
|
|
25
|
+
# Set a new value to number, validating first that it is nonnegative.
|
|
23
26
|
def number=(new_number)
|
|
24
|
-
self.
|
|
27
|
+
self.assert_non_negative(new_number)
|
|
25
28
|
@number = new_number
|
|
26
29
|
end
|
|
27
30
|
|
|
@@ -35,162 +38,58 @@ class Bitmap
|
|
|
35
38
|
private_class_method :new
|
|
36
39
|
|
|
37
40
|
|
|
38
|
-
# Class methods for converting between representations:
|
|
39
|
-
|
|
40
|
-
# Converts from a binary string to a number, e.g. "\x01\x00" => 256
|
|
41
|
-
def self.binary_string_to_number(string)
|
|
42
|
-
string = string.clone.force_encoding(Encoding::ASCII_8BIT)
|
|
43
|
-
string.bytes.inject(0) do |number, byte|
|
|
44
|
-
number * 256 + byte.ord
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
# Converts a number to a binary encoded string, e.g. 256 => "\x01\x00"
|
|
50
|
-
def self.number_to_binary_string(number, min_length = 0)
|
|
51
|
-
assert_nonnegative(number)
|
|
52
|
-
binary_string = ''.force_encoding(Encoding::ASCII_8BIT)
|
|
53
|
-
|
|
54
|
-
while number > 0
|
|
55
|
-
byte_value = number & 0xFF
|
|
56
|
-
binary_string << byte_value
|
|
57
|
-
number >>= 8
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
binary_string.reverse.rjust(min_length, "\x00")
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
# Converts a number to an array of place values, e.g. 9 => [8, 0, 0, 1]
|
|
65
|
-
def self.number_to_value_array(number)
|
|
66
|
-
assert_nonnegative(number)
|
|
67
|
-
array = []
|
|
68
|
-
bit_value = 1
|
|
69
|
-
while number > 0
|
|
70
|
-
array << ((number & 1 == 1) ? bit_value : 0)
|
|
71
|
-
number >>= 1
|
|
72
|
-
bit_value <<= 1
|
|
73
|
-
end
|
|
74
|
-
array.reverse
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
# Converts from a value array to a number, e.g. [8, 0, 0, 1] => 9
|
|
79
|
-
def self.value_array_to_number(value_array)
|
|
80
|
-
value_array.inject(&:+)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
# Converts a number to an array of bit values, e.g. 9 => [1, 0, 0, 1]
|
|
85
|
-
def self.number_to_bit_array(number)
|
|
86
|
-
assert_nonnegative(number)
|
|
87
|
-
array = []
|
|
88
|
-
while number > 0
|
|
89
|
-
array << (number & 1)
|
|
90
|
-
number >>= 1
|
|
91
|
-
end
|
|
92
|
-
array.reverse
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
# Converts an array of bit values, e.g. [1, 0, 0, 1], to a number, e.g. 9
|
|
97
|
-
def self.bit_array_to_number(bit_array)
|
|
98
|
-
return nil if bit_array.empty?
|
|
99
|
-
multiplier = 1
|
|
100
|
-
bit_array.inject(0) do |result, n|
|
|
101
|
-
result += n * multiplier
|
|
102
|
-
multiplier *= 2
|
|
103
|
-
result
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
# Converts a number to a sparse array containing bit positions that are set/true/1.
|
|
109
|
-
# Note that these are bit positions, e.g. 76543210, and not bit column values
|
|
110
|
-
# such as 128/64/32/16/8/4/2/1.
|
|
111
|
-
def self.number_to_set_bit_positions_array(number)
|
|
112
|
-
assert_nonnegative(number)
|
|
113
|
-
array = []
|
|
114
|
-
position = 0
|
|
115
|
-
while number > 0
|
|
116
|
-
array << position if number & 1 == 1
|
|
117
|
-
position += 1
|
|
118
|
-
number >>= 1
|
|
119
|
-
end
|
|
120
|
-
array
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
# Converts an array of bit position numbers to a numeric value, e.g. [0, 2] => 5
|
|
125
|
-
def self.set_bit_position_array_to_number(position_array)
|
|
126
|
-
return nil if position_array.empty?
|
|
127
|
-
position_array.inject(0) do |result, n|
|
|
128
|
-
result += 2 ** n
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
def self.binary_string_to_bit_value_array(string)
|
|
134
|
-
number = binary_string_to_number(string)
|
|
135
|
-
number_to_bit_array(number)
|
|
136
|
-
end
|
|
137
|
-
|
|
138
41
|
# Class methods to create instances from the various representation types
|
|
139
|
-
# handled in the
|
|
42
|
+
# handled in the BitMapping module's methods.
|
|
140
43
|
|
|
44
|
+
# Creates an instance from a nonnegative number.
|
|
141
45
|
def self.from_number(number)
|
|
142
46
|
new(number)
|
|
143
47
|
end
|
|
144
48
|
|
|
49
|
+
# Creates an instance from a binary string (e.g. "\x0C").
|
|
145
50
|
def self.from_binary_string(string)
|
|
146
|
-
new(binary_string_to_number(string))
|
|
51
|
+
new(BitMapping.binary_string_to_number(string))
|
|
147
52
|
end
|
|
148
53
|
|
|
149
|
-
|
|
150
|
-
|
|
54
|
+
# Creates an instance from a value array (e.g. [8, 0, 0, 1])
|
|
55
|
+
def self.from_place_value_array(array)
|
|
56
|
+
new(BitMapping.place_value_array_to_number(array))
|
|
151
57
|
end
|
|
152
58
|
|
|
59
|
+
# Creates an instance from a bit array (e.g. [1, 0, 0, 1])
|
|
153
60
|
def self.from_bit_array(array)
|
|
154
|
-
new(bit_array_to_number(array))
|
|
61
|
+
new(BitMapping.bit_array_to_number(array))
|
|
155
62
|
end
|
|
156
63
|
|
|
64
|
+
# Creates an instance from an array of positions for the bits that are set (e.g. [0, 3])
|
|
157
65
|
def self.from_set_bit_position_array(array)
|
|
158
|
-
new(set_bit_position_array_to_number(array))
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def self.from_number(number)
|
|
162
|
-
new(number)
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
def self.assert_nonnegative(number)
|
|
167
|
-
unless number.is_a?(Integer) && number >= 0
|
|
168
|
-
raise ArgumentError.new(
|
|
169
|
-
"Parameter must be a nonnegative Integer (Fixnum, Bignum) " +
|
|
170
|
-
"but is #{number.inspect} (a #{number.class})")
|
|
171
|
-
end
|
|
66
|
+
new(BitMapping.set_bit_position_array_to_number(array))
|
|
172
67
|
end
|
|
173
68
|
|
|
69
|
+
# Instance methods to convert the data to the various representation types:
|
|
174
70
|
|
|
71
|
+
# Returns the instance's value as a binary string (e.g. "\x0C")
|
|
175
72
|
def to_binary_string(min_length = 0)
|
|
176
|
-
|
|
73
|
+
BitMapping.number_to_binary_string(number, min_length)
|
|
177
74
|
end
|
|
178
75
|
|
|
179
|
-
|
|
180
|
-
|
|
76
|
+
# Returns the instance's value as an array of bit column values (e.g. [8, 0, 0, 1])
|
|
77
|
+
def to_place_value_array
|
|
78
|
+
BitMapping.number_to_place_value_array(number)
|
|
181
79
|
end
|
|
182
80
|
|
|
81
|
+
# Returns the instance's value as an array of bit column place values (e.g. [8, 0, 0, 1])
|
|
183
82
|
def to_bit_array
|
|
184
|
-
|
|
83
|
+
BitMapping.number_to_bit_array(number)
|
|
185
84
|
end
|
|
186
85
|
|
|
86
|
+
# Returns the instance's value as an array of positions for the bits that are set (e.g. [0, 3])
|
|
187
87
|
def to_set_bit_position_array
|
|
188
|
-
|
|
88
|
+
BitMapping.number_to_set_bit_positions_array(number)
|
|
189
89
|
end
|
|
190
90
|
|
|
191
|
-
|
|
192
91
|
def initialize(number)
|
|
193
|
-
|
|
92
|
+
BitMapping.assert_non_negative(number)
|
|
194
93
|
@number = number
|
|
195
94
|
end
|
|
196
95
|
|
|
@@ -200,5 +99,3 @@ class Bitmap
|
|
|
200
99
|
end
|
|
201
100
|
end
|
|
202
101
|
end
|
|
203
|
-
|
|
204
|
-
|
data/lib/trick_bag/version.rb
CHANGED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
require_relative '../../spec_helper'
|
|
2
|
+
|
|
3
|
+
require 'trick_bag/numeric/bit_mapping'
|
|
4
|
+
|
|
5
|
+
module TrickBag
|
|
6
|
+
module Numeric
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
describe BitMapping do
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
context '.binary_string_to_number' do
|
|
13
|
+
|
|
14
|
+
it 'computes byte values correctly' do
|
|
15
|
+
expect(BitMapping.binary_string_to_number("\xFF")).to eq(255)
|
|
16
|
+
expect(BitMapping.binary_string_to_number("\x0D")).to eq(13)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'considers the left-most byte most significant' do
|
|
20
|
+
expect(BitMapping.binary_string_to_number("\x01\x00")).to eq(256)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Unspecified encoding results in UTF-8 anyway, but this makes it explicit:
|
|
24
|
+
it 'correctly handles non-ASCII_8BIT strings' do
|
|
25
|
+
expect(BitMapping.binary_string_to_number("\x01\x00".force_encoding(Encoding::UTF_8))).to eq(256)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
context '.number_to_binary_string' do
|
|
32
|
+
|
|
33
|
+
specify '256 => "\x01\00"' do
|
|
34
|
+
expect(BitMapping.number_to_binary_string(256)).to eq("\x01\x00")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
specify 'a negative number should result in an error' do
|
|
38
|
+
expect { BitMapping.number_to_binary_string(-1) }.to raise_error(ArgumentError)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
specify 'when requested, zero padding will left pad with zeros' do
|
|
42
|
+
expect(BitMapping.number_to_binary_string(256, 8)).to eq("#{"\x00" * 6}\x01\x00")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
context '.number_to_place_value_array' do
|
|
48
|
+
|
|
49
|
+
specify '9 => [8, 0, 0, 1]' do
|
|
50
|
+
expect(BitMapping.number_to_place_value_array(9)).to eq([8, 0, 0, 1])
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
specify '256 => [256] + ([0] * 8)' do
|
|
54
|
+
expect(BitMapping.number_to_place_value_array(256)).to eq([256] + [0] * 8)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
specify 'a negative number should result in an error' do
|
|
58
|
+
expect { BitMapping.number_to_place_value_array(-1) }.to raise_error(ArgumentError)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context '.place_value_array_to_number' do
|
|
63
|
+
|
|
64
|
+
specify '[8, 0, 0, 1] => 9' do
|
|
65
|
+
expect(BitMapping.place_value_array_to_number([8, 0, 0, 1])).to eq(9)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
specify '[] => nil' do
|
|
69
|
+
expect(BitMapping.place_value_array_to_number([])).to eq(nil)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
context '.bit_array_to_number' do
|
|
74
|
+
|
|
75
|
+
specify '[1, 1, 0, 1] => 13' do
|
|
76
|
+
expect(BitMapping.bit_array_to_number([1, 1, 0, 1])).to eq(13)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
specify '[] => nil' do
|
|
80
|
+
expect(BitMapping.bit_array_to_number([])).to eq(nil)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
context '.number_to_bit_array' do
|
|
86
|
+
|
|
87
|
+
specify '13 => [1, 1, 0, 1]' do
|
|
88
|
+
expect(BitMapping.number_to_bit_array(13)).to eq([1, 1, 0, 1])
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
specify '256 => [1] + ([0] * 8)' do
|
|
92
|
+
expect(BitMapping.number_to_bit_array(256)).to eq([1] + [0] * 8)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
specify 'a negative number should result in an error' do
|
|
96
|
+
expect { BitMapping.number_to_bit_array(-1) }.to raise_error(ArgumentError)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
context '.binary_string_to_bit_array' do
|
|
102
|
+
it 'computes byte values correctly' do
|
|
103
|
+
expect(BitMapping.binary_string_to_bit_array("\xFF")).to eq([1] * 8)
|
|
104
|
+
expect(BitMapping.binary_string_to_bit_array("\x0D")).to eq([1, 1, 0, 1])
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it 'considers the left-most byte most significant' do
|
|
108
|
+
expect(BitMapping.binary_string_to_bit_array("\x01\x00")).to eq([1] + [0] * 8)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Unspecified encoding results in UTF-8 anyway, but this makes it explicit:
|
|
112
|
+
it 'correctly handles non-ASCII_8BIT strings' do
|
|
113
|
+
actual = BitMapping.binary_string_to_bit_array("\x01\x00".force_encoding(Encoding::UTF_8))
|
|
114
|
+
expect(actual).to eq([1] + [0] * 8)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
context '.number_to_set_bit_positions_array' do
|
|
120
|
+
|
|
121
|
+
specify '9 => [0, 3]' do
|
|
122
|
+
expect(BitMapping.number_to_set_bit_positions_array(9)).to eq([0, 3])
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
specify 'a negative number should result in an error' do
|
|
126
|
+
expect { BitMapping.number_to_set_bit_positions_array(-1) }.to raise_error(ArgumentError)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
context '.set_bit_position_array_to_number' do
|
|
132
|
+
|
|
133
|
+
specify '[0, 8] => 256' do
|
|
134
|
+
expect(BitMapping.set_bit_position_array_to_number([0, 8])).to eq(257)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
specify '[] => nil' do
|
|
138
|
+
expect(BitMapping.set_bit_position_array_to_number([])).to eq(nil)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
@@ -6,141 +6,11 @@ module TrickBag
|
|
|
6
6
|
module Numeric
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
describe Bitmap do
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
context '.binary_string_to_number' do
|
|
18
|
-
|
|
19
|
-
it 'computes byte values correctly' do
|
|
20
|
-
expect(Bitmap.binary_string_to_number("\xFF")).to eq(255)
|
|
21
|
-
expect(Bitmap.binary_string_to_number("\x0D")).to eq(13)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it 'considers the left-most byte most significant' do
|
|
25
|
-
expect(Bitmap.binary_string_to_number("\x01\x00")).to eq(256)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Unspecified encoding results in UTF-8 anyway, but this makes it explicit:
|
|
29
|
-
it 'correctly handles non-ASCII_8BIT strings' do
|
|
30
|
-
expect(Bitmap.binary_string_to_number("\x01\x00".force_encoding(Encoding::UTF_8))).to eq(256)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
context '.number_to_binary_string' do
|
|
37
|
-
|
|
38
|
-
specify '256 => "\x01\00"' do
|
|
39
|
-
expect(Bitmap.number_to_binary_string(256)).to eq("\x01\x00")
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
specify 'a negative number should result in an error' do
|
|
43
|
-
expect { Bitmap.number_to_binary_string(-1) }.to raise_error(ArgumentError)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
specify 'when requested, zero padding will left pad with zeros' do
|
|
47
|
-
expect(Bitmap.number_to_binary_string(256, 8)).to eq("#{"\x00" * 6}\x01\x00")
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
context '.number_to_value_array' do
|
|
53
|
-
|
|
54
|
-
specify '9 => [8, 0, 0, 1]' do
|
|
55
|
-
expect(Bitmap.number_to_value_array(9)).to eq([8, 0, 0, 1])
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
specify '256 => [256] + ([0] * 8)' do
|
|
59
|
-
expect(Bitmap.number_to_value_array(256)).to eq([256] + [0] * 8)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
specify 'a negative number should result in an error' do
|
|
63
|
-
expect { Bitmap.number_to_value_array(-1) }.to raise_error(ArgumentError)
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
context '.value_array_to_number' do
|
|
68
|
-
|
|
69
|
-
specify '[8, 0, 0, 1] => 9' do
|
|
70
|
-
expect(Bitmap.value_array_to_number([8, 0, 0, 1])).to eq(9)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
specify '[] => nil' do
|
|
74
|
-
expect(Bitmap.value_array_to_number([])).to eq(nil)
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
context '.bit_array_to_number' do
|
|
79
|
-
|
|
80
|
-
specify '[1, 0, 0, 1] => 9' do
|
|
81
|
-
expect(Bitmap.bit_array_to_number([1, 0, 0, 1])).to eq(9)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
specify '[] => nil' do
|
|
85
|
-
expect(Bitmap.bit_array_to_number([])).to eq(nil)
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
context '.number_to_bit_array' do
|
|
91
|
-
|
|
92
|
-
specify '9 => [1, 0, 0, 1]' do
|
|
93
|
-
expect(Bitmap.number_to_bit_array(9)).to eq([1, 0, 0, 1])
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
specify '256 => [1] + ([0] * 8)' do
|
|
97
|
-
expect(Bitmap.number_to_bit_array(256)).to eq([1] + [0] * 8)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
specify 'a negative number should result in an error' do
|
|
101
|
-
expect { Bitmap.number_to_bit_array(-1) }.to raise_error(ArgumentError)
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
context '.binary_string_to_bit_value_array' do
|
|
107
|
-
it 'computes byte values correctly' do
|
|
108
|
-
expect(Bitmap.binary_string_to_bit_value_array("\xFF")).to eq([1] * 8)
|
|
109
|
-
expect(Bitmap.binary_string_to_bit_value_array("\x0D")).to eq([1,1,0,1])
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
it 'considers the left-most byte most significant' do
|
|
113
|
-
expect(Bitmap.binary_string_to_bit_value_array("\x01\x00")).to eq([1] + [0] * 8)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
# Unspecified encoding results in UTF-8 anyway, but this makes it explicit:
|
|
117
|
-
it 'correctly handles non-ASCII_8BIT strings' do
|
|
118
|
-
expect(Bitmap.binary_string_to_bit_value_array("\x01\x00".force_encoding(Encoding::UTF_8))).to eq([1] + [0] * 8)
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
context '.number_to_set_bit_positions_array' do
|
|
124
|
-
|
|
125
|
-
specify '9 => [0, 3]' do
|
|
126
|
-
expect(Bitmap.number_to_set_bit_positions_array(9)).to eq([0, 3])
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
specify 'a negative number should result in an error' do
|
|
130
|
-
expect { Bitmap.number_to_set_bit_positions_array(-1) }.to raise_error(ArgumentError)
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
context '.set_bit_position_array_to_number' do
|
|
136
|
-
|
|
137
|
-
specify '[0, 8] => 256' do
|
|
138
|
-
expect(Bitmap.set_bit_position_array_to_number([0, 8])).to eq(257)
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
specify '[] => nil' do
|
|
142
|
-
expect(Bitmap.set_bit_position_array_to_number([])).to eq(nil)
|
|
143
|
-
end
|
|
12
|
+
specify 'the constructor should not permit being explicitly called outside the class' do
|
|
13
|
+
expect(-> { Bitmap.new }).to raise_error
|
|
144
14
|
end
|
|
145
15
|
|
|
146
16
|
|
|
@@ -154,12 +24,12 @@ module Numeric
|
|
|
154
24
|
expect(Bitmap.from_binary_string("\x01\x00").number).to eq(256)
|
|
155
25
|
end
|
|
156
26
|
|
|
157
|
-
specify '
|
|
158
|
-
expect(Bitmap.
|
|
27
|
+
specify 'from_place_value_array' do
|
|
28
|
+
expect(Bitmap.from_place_value_array([8, 0, 0, 1]).number).to eq(9)
|
|
159
29
|
end
|
|
160
30
|
|
|
161
31
|
specify 'from_bit_array' do
|
|
162
|
-
expect(Bitmap.from_bit_array([1,
|
|
32
|
+
expect(Bitmap.from_bit_array([1, 1, 0, 1]).number).to eq(13)
|
|
163
33
|
end
|
|
164
34
|
|
|
165
35
|
specify 'from_set_bit_position_array' do
|
|
@@ -167,6 +37,7 @@ module Numeric
|
|
|
167
37
|
end
|
|
168
38
|
end
|
|
169
39
|
|
|
40
|
+
|
|
170
41
|
context 'test output methods' do
|
|
171
42
|
|
|
172
43
|
specify 'to_binary_string' do
|
|
@@ -174,10 +45,9 @@ module Numeric
|
|
|
174
45
|
expect(bitmap.to_binary_string).to eq("\x01\x02")
|
|
175
46
|
end
|
|
176
47
|
|
|
177
|
-
specify '
|
|
48
|
+
specify 'to_place_value_array' do
|
|
178
49
|
bitmap = Bitmap.from_number(258)
|
|
179
|
-
|
|
180
|
-
expect(bitmap.to_value_array).to eq([256, 0, 0, 0, 0, 0, 0, 2, 0])
|
|
50
|
+
expect(bitmap.to_place_value_array).to eq([256, 0, 0, 0, 0, 0, 0, 2, 0])
|
|
181
51
|
end
|
|
182
52
|
|
|
183
53
|
specify 'to_bit_array' do
|
|
@@ -204,7 +74,6 @@ module Numeric
|
|
|
204
74
|
specify '3 ^ 2 => 1' do
|
|
205
75
|
expect(Bitmap.from_number(3) ^ 2).to eq(1)
|
|
206
76
|
end
|
|
207
|
-
|
|
208
77
|
end
|
|
209
78
|
|
|
210
79
|
context 'hash, ==' do
|
|
@@ -220,6 +89,6 @@ module Numeric
|
|
|
220
89
|
expect(Bitmap.from_number(1234).hash).to eq(Bitmap.from_number(1234).hash)
|
|
221
90
|
end
|
|
222
91
|
end
|
|
223
|
-
end
|
|
224
92
|
end
|
|
225
|
-
|
|
93
|
+
end
|
|
94
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: trick_bag
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.57.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Keith Bennett
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-01-
|
|
11
|
+
date: 2015-01-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: os
|
|
@@ -110,6 +110,7 @@ files:
|
|
|
110
110
|
- lib/trick_bag/io/temp_files.rb
|
|
111
111
|
- lib/trick_bag/io/text_mode_status_updater.rb
|
|
112
112
|
- lib/trick_bag/meta/classes.rb
|
|
113
|
+
- lib/trick_bag/numeric/bit_mapping.rb
|
|
113
114
|
- lib/trick_bag/numeric/bitmap.rb
|
|
114
115
|
- lib/trick_bag/numeric/multi_counter.rb
|
|
115
116
|
- lib/trick_bag/numeric/start_and_max.rb
|
|
@@ -138,6 +139,7 @@ files:
|
|
|
138
139
|
- spec/trick_bag/io/temp_files_spec.rb
|
|
139
140
|
- spec/trick_bag/io/text_mode_status_updater_spec.rb
|
|
140
141
|
- spec/trick_bag/meta/classes_spec.rb
|
|
142
|
+
- spec/trick_bag/numeric/bit_mapping_spec.rb
|
|
141
143
|
- spec/trick_bag/numeric/bitmap_spec.rb
|
|
142
144
|
- spec/trick_bag/numeric/multi_counter_spec.rb
|
|
143
145
|
- spec/trick_bag/numeric/start_and_max_spec.rb
|
|
@@ -190,6 +192,7 @@ test_files:
|
|
|
190
192
|
- spec/trick_bag/io/temp_files_spec.rb
|
|
191
193
|
- spec/trick_bag/io/text_mode_status_updater_spec.rb
|
|
192
194
|
- spec/trick_bag/meta/classes_spec.rb
|
|
195
|
+
- spec/trick_bag/numeric/bit_mapping_spec.rb
|
|
193
196
|
- spec/trick_bag/numeric/bitmap_spec.rb
|
|
194
197
|
- spec/trick_bag/numeric/multi_counter_spec.rb
|
|
195
198
|
- spec/trick_bag/numeric/start_and_max_spec.rb
|