|
31 | 31 | just three parts: left-hand side, value, right-hand side.
|
32 | 32 |
|
33 | 33 | For example, say you want to insert two ones in the middle of 0b101101,
|
34 |
| -that is -> 0b10111101. Index is 2 ( 0 ,1, 2 from the right ) and the |
| 34 | +that is -> 0b10111101. Index is 3 ( 0 ,1, 2, 3 from the right ) and the |
35 | 35 | value is 3 (0b11) with a bit length of 2.
|
36 | 36 |
|
37 | 37 | - Shift >> index right to produce 0b101
|
|
44 | 44 | -> 0b10111101.
|
45 | 45 |
|
46 | 46 | To remove the center two bits of 0b101101 -> 0b1001, the process is mostly
|
47 |
| -the same. |
| 47 | +the same. Index is 2 for the remove operation on the right-center bit |
| 48 | +rather than 3 for inserting, because we are referring to the bit itself |
| 49 | +rather the position to the right of the bit index. |
48 | 50 |
|
49 |
| -- The initial right shift is index(2) + bit_length(2), taking out the two |
| 51 | +- The initial right shift is index (2 ) + bit_length(2), taking out the two |
50 | 52 | middle bits and producing 0b10.
|
51 | 53 | - The left shift of index produces 0b1000.
|
52 | 54 | - The original bint is ANDed with bitmask 0b11 producing 0b01 which is
|
53 | 55 | ORed with 0b1000 yielding the target 0b1001.
|
54 | 56 |
|
55 |
| -It's not so bad once you get the hang of it. |
| 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. |
56 | 62 |
|
57 | 63 | Various bit insert/remove solutions exist using bin() string functions
|
58 | 64 | and slicing, but this bitwise implementation is significantly faster
|
|
64 | 70 |
|
65 | 71 | bit_length = int.bit_length
|
66 | 72 |
|
67 |
| -"""The only consistent error checking is for bint < 0 or index < 0 etc., |
68 |
| - and for bit_length(value) > bit_len, which can cause silent errors. |
69 |
| - Anything like int(None) is going to cause a loud error. """ |
70 |
| - |
71 | 73 |
|
72 | 74 | def bit_get(bint: int, index: int) -> int:
|
73 | 75 | """Get value of bit at index in bint.
|
@@ -197,7 +199,7 @@ def multibit_set(bint: int, index: int, bit_len: int, value: int) -> int:
|
197 | 199 |
|
198 | 200 |
|
199 | 201 | def multibit_insert(bint: int, index: int, bit_len: int, value: int) -> int:
|
200 |
| - """Insert before index-th slot |
| 202 | + """Insert value before index-th slot |
201 | 203 |
|
202 | 204 | >>> multibit_insert(0, 1, 1, 1)
|
203 | 205 | 2
|
@@ -245,6 +247,7 @@ def multibit_remove(bint: int, index: int, bit_len: int) -> int:
|
245 | 247 |
|
246 | 248 |
|
247 | 249 | if __name__ == "__main__":
|
| 250 | + |
248 | 251 | import doctest
|
249 | 252 |
|
250 | 253 | doctest.testmod()
|
0 commit comments