|
1 | 1 | """Bit integer manipulation, both single bit and multi-bit list-like
|
2 | 2 | slicing functions ( get, set, insert, remove ) implemented with
|
3 | 3 | builtin bitwise operations.
|
4 |
| - |
| 4 | +
|
5 | 5 | See:
|
6 | 6 | https://high-python-ext-3-algorithms.readthedocs.io/ko/latest/chapter5.html#insert-bit
|
7 | 7 | https://en.wikipedia.org/wiki/Bit_manipulation#Bit_manipulation_operations
|
|
11 | 11 |
|
12 | 12 | bint:int
|
13 | 13 | The bit integer to be accessed or returned as modified.
|
14 |
| - |
| 14 | +
|
15 | 15 | index:int
|
16 | 16 | The offset into the bit position from right,
|
17 |
| - 0b010111 -> list [1,1,1,0,1,0]. big-endian -> little-endian |
| 17 | + 0b010111 -> list [1,1,1,0,1,0]. big-endian -> little-endian |
18 | 18 | For inserts, index is the position to the right of index,
|
19 |
| - index 0 -> right of rightmost bit. |
| 19 | + index 0 -> right of rightmost bit. |
20 | 20 | For gets, sets and removes, it is the position of the bit itself.
|
21 |
| - |
| 21 | +
|
22 | 22 | value:int
|
23 | 23 | Either [0,1] for single bit, or bit mask, bit_length(value) <= bitlen.
|
24 |
| - |
| 24 | +
|
25 | 25 | bitlen:int
|
26 | 26 | The effective mask length, spec. leading zeros
|
27 |
| - ( bitlen 4 value 1 -> 0001 ) |
28 |
| - |
29 |
| -The bitwise expressions may look convoluted, but basically, there are |
| 27 | + ( bitlen 4 value 1 -> 0001 ) |
| 28 | +
|
| 29 | +The bitwise expressions may look convoluted, but basically, there are |
30 | 30 | just three parts: left-hand side, value, right-hand side.
|
31 | 31 |
|
32 | 32 | For example, say you want to insert two ones in the middle of 0b101101,
|
|
41 | 41 | ( 0b101101 & 0b111 ) -> 0b101.
|
42 | 42 | - OR that into the working 0b10111000, that is, ( 0b10111000 | 0b101 )
|
43 | 43 | -> 0b10111101.
|
44 |
| - |
| 44 | +
|
45 | 45 | To remove the center two bits of 0b101101 -> 0b1001, the process is mostly
|
46 | 46 | the same.
|
47 | 47 |
|
|
50 | 50 | - The left shift of index produces 0b1000.
|
51 | 51 | - The original bint is ANDed with bitmask 0b11 producing 0b01 which is
|
52 | 52 | ORed with 0b1000 yielding the target 0b1001.
|
53 |
| - |
54 |
| -It's not so bad once you get the hang of it. |
55 |
| - |
| 53 | +
|
| 54 | +It's not so bad once you get the hang of it. |
| 55 | +
|
56 | 56 | Various bit insert/remove solutions exist using bin() string functions
|
57 | 57 | and slicing, but this bitwise implementation is significantly faster
|
58 | 58 | (about 3x) on Python for big ints (2^100).
|
59 |
| - |
60 |
| -See https://github.com/billbreit/BitWiseApps/blob/main/dev/time_ops.py |
61 |
| - |
62 |
| - """ |
| 59 | +
|
| 60 | +See https://github.com/billbreit/BitWiseApps/blob/main/dev/time_ops.py |
| 61 | +
|
| 62 | +""" |
63 | 63 |
|
64 | 64 | bit_length = int.bit_length
|
65 | 65 |
|
@@ -230,7 +230,6 @@ def multibit_remove(bint: int, index: int, bit_len: int) -> int:
|
230 | 230 |
|
231 | 231 |
|
232 | 232 | if __name__ == "__main__":
|
233 |
| - |
234 | 233 | import doctest
|
235 | 234 |
|
236 | 235 | doctest.testmod()
|
0 commit comments