54
54
- The original bint is ANDed with bitmask 0b11 producing 0b01 which is
55
55
ORed with 0b1000 yielding the target 0b1001.
56
56
57
- It's not so bad once you get the hang of it, although it can still be a
58
- bear to debug. In the insert example above, the result of inserting 0b11
59
- in the center ( index=3 ) or to the right ( index=2 ) produces the same
60
- correct result despite the misspecification. These algorithms are very
61
- fast but can be touchy at times.
57
+ Bit manipulation operations can be tricky to debug. In the insert example
58
+ above, the result of inserting 0b11 in the center ( index=3 ) or to the
59
+ right ( index=2 ) produces the same correct result despite the unintended
60
+ misspecification. Why is it worling sometimes and not others ? Frequently,
61
+ it's the result of inserting at the wrong index, for the hundredth time !
62
62
63
63
Various bit insert/remove solutions exist using bin() string functions
64
64
and slicing, but this bitwise implementation is significantly faster
@@ -83,11 +83,11 @@ def bit_get(bint: int, index: int) -> int:
83
83
>>> bit_get(-1, 2)
84
84
Traceback (most recent call last):
85
85
...
86
- ValueError: All input values must be positive integers.
86
+ ValueError: multi_get -> All input values must be positive integers.
87
87
>>> bit_get(0, -1)
88
88
Traceback (most recent call last):
89
89
...
90
- ValueError: All input values must be positive integers.
90
+ ValueError: multi_get -> All input values must be positive integers.
91
91
"""
92
92
93
93
return multibit_get (bint , index , 1 )
@@ -105,11 +105,11 @@ def bit_set(bint: int, index: int, value: int = 1) -> int:
105
105
>>> bit_set(31, 6, 3)
106
106
Traceback (most recent call last):
107
107
...
108
- ValueError: Input value must be 1 or 0.
108
+ ValueError: bit_set -> Input value must be 1 or 0.
109
109
"""
110
110
111
111
if value not in [0 , 1 ]:
112
- raise ValueError ("Input value must be 1 or 0." )
112
+ raise ValueError ("bit_set -> Input value must be 1 or 0." )
113
113
114
114
return multibit_set (bint , index , 1 , value )
115
115
@@ -128,7 +128,7 @@ def bit_insert(bint: int, index: int, value: int = 1) -> int:
128
128
"""
129
129
130
130
if value not in [0 , 1 ]:
131
- raise ValueError ("Input value must be 1 or 0." )
131
+ raise ValueError ("bit_insert -> Input value must be 1 or 0." )
132
132
133
133
return multibit_insert (bint , index , 1 , value )
134
134
@@ -164,7 +164,7 @@ def multibit_get(bint: int, index: int, bit_len: int) -> int:
164
164
"""
165
165
166
166
if bint < 0 or index < 0 or bit_len < 0 :
167
- raise ValueError ("All input values must be positive integers." )
167
+ raise ValueError ("multi_get -> All input values must be positive integers." )
168
168
169
169
return (bint >> index ) & ((1 << bit_len ) - 1 )
170
170
@@ -183,14 +183,14 @@ def multibit_set(bint: int, index: int, bit_len: int, value: int) -> int:
183
183
>>> multibit_set(22, 2, 1, 3) is None
184
184
Traceback (most recent call last):
185
185
...
186
- ValueError: Bit length of value can not be greater than specified bit length.
186
+ ValueError: multi_set -> Bit length of value can not be greater than specified bit length.
187
187
"""
188
188
189
189
if bint < 0 or index < 0 or bit_len < 0 or value < 0 :
190
- raise ValueError ("All input values must be positive integers." )
190
+ raise ValueError ("multi_set -> All input values must be positive integers." )
191
191
if bit_length (value ) > bit_len :
192
192
raise ValueError (
193
- "Bit length of value can not be greater than specified bit length."
193
+ "multi_set -> Bit length of value can not be greater than specified bit length."
194
194
)
195
195
196
196
return ((((bint >> (index + bit_len )) << bit_len ) | value ) << index ) | (
@@ -209,17 +209,19 @@ def multibit_insert(bint: int, index: int, bit_len: int, value: int) -> int:
209
209
45
210
210
>>> multibit_insert(22, 2, 1, 0)
211
211
42
212
+ >>> multibit_insert(22, 2, 0, 0)
213
+ 22
212
214
>>> multibit_insert(22, 2, 1, 3)
213
215
Traceback (most recent call last):
214
216
...
215
- ValueError: Bit length of value can not be greater than specified bit length.
217
+ ValueError: multi_insert -> Bit length of value can not be greater than specified bit length.
216
218
"""
217
219
218
220
if bint < 0 or index < 0 or bit_len < 0 or value < 0 :
219
- raise ValueError ("All input values must be positive integers." )
221
+ raise ValueError ("multi_insert -> All input values must be positive integers." )
220
222
if bit_length (value ) > bit_len :
221
223
raise ValueError (
222
- "Bit length of value can not be greater than specified bit length."
224
+ "multi_insert -> Bit length of value can not be greater than specified bit length."
223
225
)
224
226
225
227
return ((((bint >> index ) << bit_len ) | value ) << index ) | bint & ((1 << index ) - 1 )
@@ -241,12 +243,13 @@ def multibit_remove(bint: int, index: int, bit_len: int) -> int:
241
243
"""
242
244
243
245
if bint < 0 or index < 0 or bit_len < 0 :
244
- raise ValueError ("All input values must be positive integers." )
246
+ raise ValueError ("multi_remove -> All input values must be positive integers." )
245
247
246
248
return ((bint >> index + bit_len ) << index ) | bint & ((1 << index ) - 1 )
247
249
248
250
249
251
if __name__ == "__main__" :
252
+
250
253
import doctest
251
254
252
255
doctest .testmod ()
0 commit comments