[pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci
This commit is contained in:
pre-commit-ci[bot] 2024-05-29 01:51:06 +00:00
parent 01be0441d6
commit 23956f55f3

View File

@ -15,9 +15,9 @@ All parameters must be must be int >= 0, referred to as a 'bit integer'.
index:int index:int
The offset into the bit position from right, The offset into the bit position from right,
0b010111 -> list [1,1,1,0,1,0]. big-endian -> little-endian 0b010111 -> list [1,1,1,0,1,0]. big-endian -> little-endian
For inserts, index is the position to the right of index, For inserts, index is the position to the right of index,
index 0 -> right of rightmost bit. index 0 -> right of rightmost bit.
For gets, sets and removes, it is the position of the bit itself. For gets, sets and removes, it is the position of the bit itself.
value:int value:int
@ -25,7 +25,7 @@ All parameters must be must be int >= 0, referred to as a 'bit integer'.
bitlen:int bitlen:int
The effective mask length, spec. leading zeros The effective mask length, spec. leading zeros
( bitlen 4 value 1 -> 0001 ) ( bitlen 4 value 1 -> 0001 )
The bitwise expressions may look convoluted, but basically, there are The bitwise expressions may look convoluted, but basically, there are
just three parts: left-hand side, value, right-hand side. just three parts: left-hand side, value, right-hand side.
@ -51,16 +51,16 @@ the same.
- The left shift of index produces 0b1000. - The left shift of index produces 0b1000.
- The original bint is ANDed with bitmask 0b11 producing 0b01 which is - The original bint is ANDed with bitmask 0b11 producing 0b01 which is
ORed with 0b1000 yielding the target 0b1001. ORed with 0b1000 yielding the target 0b1001.
It's not so bad once you get the hang of it. It's not so bad once you get the hang of it.
Various bit insert/remove solutions exist using bin() string functions Various bit insert/remove solutions exist using bin() string functions
and slicing, but this bitwise implementation is significantly faster and slicing, but this bitwise implementation is significantly faster
(about 3x) on Python for big ints (2^100). (about 3x) on Python for big ints (2^100).
See https://github.com/billbreit/BitWiseApps/blob/main/dev/time_ops.py See https://github.com/billbreit/BitWiseApps/blob/main/dev/time_ops.py
""" """
bit_length = int.bit_length bit_length = int.bit_length
@ -68,164 +68,169 @@ bit_length = int.bit_length
and for bit_length(value) > bit_len, which can cause silent errors. and for bit_length(value) > bit_len, which can cause silent errors.
Anything like int(None) is going to cause a loud error. """ Anything like int(None) is going to cause a loud error. """
def bit_get(bint: int, index: int): def bit_get(bint: int, index: int):
"""Get value of bit at index in bint. """Get value of bit at index in bint.
>>> bit_get(15, 0) >>> bit_get(15, 0)
1 1
>>> bit_get(15, 4) >>> bit_get(15, 4)
0 0
>>> bit_get(0, 4) >>> bit_get(0, 4)
0 0
>>> bit_get(-1, 2) is None >>> bit_get(-1, 2) is None
True True
>>> bit_get(0, -1) is None >>> bit_get(0, -1) is None
True True
""" """
return multibit_get(bint, index, 1)
return multibit_get(bint, index, 1)
def bit_set(bint: int, index: int, value: int = 1): def bit_set(bint: int, index: int, value: int = 1):
"""Set bit at index to value 1 or 0, like set() or unset(). """Set bit at index to value 1 or 0, like set() or unset().
>>> bit_set(15, 0, 0) >>> bit_set(15, 0, 0)
14 14
>>> bit_set(15, 4, 1) >>> bit_set(15, 4, 1)
31 31
>>> bit_set(31, 6, 0) >>> bit_set(31, 6, 0)
31 31
>>> bit_set(31, 6, 3) is None >>> bit_set(31, 6, 3) is None
True True
""" """
if value not in [0, 1]: if value not in [0, 1]:
return None # error return None # error
return multibit_set(bint, index, 1, value)
return multibit_set(bint, index, 1, value)
def bit_insert(bint: int, index: int, value: int = 1): def bit_insert(bint: int, index: int, value: int = 1):
"""Insert bit value before index. """Insert bit value before index.
>>> bit_insert(15, 0, 0) >>> bit_insert(15, 0, 0)
30 30
>>> bit_insert(15, 0, 1) >>> bit_insert(15, 0, 1)
31 31
>>> bit_insert(15, 4, 1) >>> bit_insert(15, 4, 1)
31 31
>>> bit_insert(31, 6, 0) >>> bit_insert(31, 6, 0)
31 31
""" """
if value not in [0, 1]: if value not in [0, 1]:
return None # error return None # error
return multibit_insert(bint, index, 1, value)
return multibit_insert(bint, index, 1, value)
def bit_remove(bint: int, index: int) -> int: def bit_remove(bint: int, index: int) -> int:
"""Remove the bit at index from bint. """Remove the bit at index from bint.
>>> bit_remove(15, 0) >>> bit_remove(15, 0)
7 7
>>> bit_remove(15, 1) >>> bit_remove(15, 1)
7 7
>>> bit_remove(31, 4) >>> bit_remove(31, 4)
15 15
>>> bit_remove(31, 6) >>> bit_remove(31, 6)
31 31
""" """
return multibit_remove(bint, index, 1)
return multibit_remove(bint, index, 1)
def multibit_get(bint: int, index: int, bit_len: int) -> int: def multibit_get(bint: int, index: int, bit_len: int) -> int:
"""Get bit_len number of bits starting from index. """Get bit_len number of bits starting from index.
819 = 1100110011. 819 = 1100110011.
>>> multibit_get(0, 1, 1) >>> multibit_get(0, 1, 1)
0 0
>>> multibit_get(15, 0, 3) >>> multibit_get(15, 0, 3)
7 7
>>> multibit_get(819, 2, 4) >>> multibit_get(819, 2, 4)
12 12
>>> multibit_get(819, 4, 6) >>> multibit_get(819, 4, 6)
51 51
""" """
if bint < 0 or index < 0 or bit_len < 0: if bint < 0 or index < 0 or bit_len < 0:
return None # error return None # error
return (bint >> index) & ((1 << bit_len) - 1)
return (bint >> index) & ((1 << bit_len) - 1)
def multibit_set(bint: int, index: int, bit_len: int, value: int) -> int: def multibit_set(bint: int, index: int, bit_len: int, value: int) -> int:
"""Overlay bint at index with value for bit_len bits. """Overlay bint at index with value for bit_len bits.
>>> multibit_set(0, 1, 1, 0) >>> multibit_set(0, 1, 1, 0)
0 0
>>> multibit_set(15, 0, 2, 0) >>> multibit_set(15, 0, 2, 0)
12 12
>>> multibit_set(22, 0, 1, 1) >>> multibit_set(22, 0, 1, 1)
23 23
>>> multibit_set(22, 2, 1, 0) >>> multibit_set(22, 2, 1, 0)
18 18
>>> multibit_set(22, 2, 1, 3) is None >>> multibit_set(22, 2, 1, 3) is None
True True
""" """
if bint < 0 or index < 0 or bit_len < 0 or value < 0: if bint < 0 or index < 0 or bit_len < 0 or value < 0:
return None # error return None # error
if bit_length(value) > bit_len: if bit_length(value) > bit_len:
return None return None
return ((((bint >> (index + bit_len)) << bit_len) | value) << index) | ( return ((((bint >> (index + bit_len)) << bit_len) | value) << index) | (
bint & (1 << index) - 1 bint & (1 << index) - 1
) )
def multibit_insert(bint: int, index: int, bit_len: int, value: int) -> int: def multibit_insert(bint: int, index: int, bit_len: int, value: int) -> int:
"""Insert before index-th slot """Insert before index-th slot
>>> multibit_insert(0, 1, 1, 1) >>> multibit_insert(0, 1, 1, 1)
2 2
>>> multibit_insert(15, 1, 2, 0) >>> multibit_insert(15, 1, 2, 0)
57 57
>>> multibit_insert(22, 0, 1, 1) >>> multibit_insert(22, 0, 1, 1)
45 45
>>> multibit_insert(22, 2, 1, 0) >>> multibit_insert(22, 2, 1, 0)
42 42
>>> multibit_insert(22, 2, 1, 3) is None >>> multibit_insert(22, 2, 1, 3) is None
True True
""" """
if bint < 0 or index < 0 or bit_len < 0 or value < 0: if bint < 0 or index < 0 or bit_len < 0 or value < 0:
return None # error return None # error
if bit_length(value) > bit_len: if bit_length(value) > bit_len:
return None return None
return ((((bint >> index) << bit_len) | value) << index) | bint & ((1 << index) - 1) return ((((bint >> index) << bit_len) | value) << index) | bint & ((1 << index) - 1)
def multibit_remove(bint: int, index: int, bit_len: int) -> int: def multibit_remove(bint: int, index: int, bit_len: int) -> int:
"""Remove bits in bint from index to index+bit_len. """Remove bits in bint from index to index+bit_len.
>>> multibit_remove(3, 1, 1) >>> multibit_remove(3, 1, 1)
1 1
>>> multibit_remove(15, 1, 2) >>> multibit_remove(15, 1, 2)
3 3
>>> multibit_remove(22, 0, 1) >>> multibit_remove(22, 0, 1)
11 11
>>> multibit_remove(22, 2, 2) >>> multibit_remove(22, 2, 2)
6 6
>>> multibit_remove(22, 2, 6) >>> multibit_remove(22, 2, 6)
2 2
""" """
if bint < 0 or index < 0: if bint < 0 or index < 0:
return None # error return None # error
return ((bint >> index + bit_len) << index) | bint & ((1 << index) - 1) return ((bint >> index + bit_len) << index) | bint & ((1 << index) - 1)
if __name__ == "__main__": if __name__ == "__main__":
import doctest
import doctest doctest.testmod()
doctest.testmod()