-
-
Notifications
You must be signed in to change notification settings - Fork 51.1k
add bit_manipulation: add parity, next_power_of_two, rotate_bits codes #13157
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7cf4aab
a6f0dd8
2e71bad
6882029
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| """ | ||
| Author : Basuki Nath | ||
| Date : 2025-10-04 | ||
|
|
||
| Utility to compute the next power of two greater than or equal to n. | ||
| """ | ||
|
|
||
|
|
||
| def next_power_of_two(n: int) -> int: | ||
| """ | ||
| Return the smallest power of two >= n for positive integers. | ||
|
|
||
| >>> next_power_of_two(1) | ||
| 1 | ||
| >>> next_power_of_two(2) | ||
| 2 | ||
| >>> next_power_of_two(3) | ||
| 4 | ||
| >>> next_power_of_two(5) | ||
| 8 | ||
| >>> next_power_of_two(1025) | ||
| 2048 | ||
| >>> next_power_of_two(0) | ||
| Traceback (most recent call last): | ||
| ... | ||
| ValueError: n must be positive | ||
| >>> next_power_of_two(-3) | ||
| Traceback (most recent call last): | ||
| ... | ||
| ValueError: n must be positive | ||
| """ | ||
| if n <= 0: | ||
| raise ValueError("n must be positive") | ||
| # If already a power of two, return it | ||
| if n & (n - 1) == 0: | ||
| return n | ||
| # Otherwise, fill bits to the right | ||
| v = n - 1 | ||
| v |= v >> 1 | ||
| v |= v >> 2 | ||
| v |= v >> 4 | ||
| v |= v >> 8 | ||
| v |= v >> 16 | ||
| # for very large ints, continue shifting using Python's arbitrary precision | ||
| shift = 32 | ||
| while (1 << shift) <= v: | ||
| v |= v >> shift | ||
| shift <<= 1 | ||
| return v + 1 | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| import doctest | ||
|
|
||
| doctest.testmod() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| """ | ||
| Author : Basuki Nath | ||
| Date : 2025-10-04 | ||
|
|
||
| Simple parity utility for integers. | ||
|
|
||
| The parity is 1 when the number of set bits is odd, otherwise 0. | ||
| """ | ||
|
|
||
|
|
||
| def parity(number: int) -> int: | ||
| """ | ||
| Return 1 if `number` has an odd number of set bits, otherwise 0. | ||
|
|
||
| >>> parity(0) | ||
| 0 | ||
| >>> parity(1) | ||
| 1 | ||
| >>> parity(2) # 10b -> one set bit | ||
| 1 | ||
| >>> parity(3) # 11b -> two set bits | ||
| 0 | ||
| >>> parity(1023) # 10 ones -> even | ||
| 0 | ||
| >>> parity(-1) | ||
| Traceback (most recent call last): | ||
| ... | ||
| ValueError: number must not be negative | ||
| """ | ||
| if number < 0: | ||
| raise ValueError("number must not be negative") | ||
| # Kernighan's algorithm toggling parity | ||
| p = 0 | ||
| while number: | ||
| p ^= 1 | ||
| number &= number - 1 | ||
| return p | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| import doctest | ||
|
|
||
| doctest.testmod() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| """ | ||
| Author : Basuki Nath | ||
| Date : 2025-10-04 | ||
|
|
||
| Bit rotation helpers for 32-bit unsigned integers. | ||
| """ | ||
|
|
||
|
|
||
| def rotate_left32(x: int, k: int) -> int: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide descriptive name for the parameter: Please provide descriptive name for the parameter: |
||
| """ | ||
| Rotate the lower 32 bits of x left by k and return result in 0..2**32-1. | ||
|
|
||
| >>> rotate_left32(1, 1) | ||
| 2 | ||
| >>> rotate_left32(1, 31) | ||
| 2147483648 | ||
| >>> rotate_left32(0x80000000, 1) | ||
| 1 | ||
| >>> rotate_left32(0x12345678, 4) | ||
| 591751041 | ||
| >>> rotate_left32(-1, 3) | ||
| Traceback (most recent call last): | ||
| ... | ||
| ValueError: x must be a non-negative integer | ||
| >>> rotate_left32(1, -1) | ||
| Traceback (most recent call last): | ||
| ... | ||
| ValueError: k must be non-negative | ||
| """ | ||
| if not isinstance(x, int) or x < 0: | ||
| raise ValueError("x must be a non-negative integer") | ||
| if not isinstance(k, int) or k < 0: | ||
| raise ValueError("k must be non-negative") | ||
| mask = (1 << 32) - 1 | ||
| k &= 31 | ||
| return ((x << k) & mask) | ((x & mask) >> (32 - k)) | ||
|
|
||
|
|
||
| def rotate_right32(x: int, k: int) -> int: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide descriptive name for the parameter: Please provide descriptive name for the parameter: |
||
| """ | ||
| Rotate the lower 32 bits of x right by k and return result in 0..2**32-1. | ||
|
|
||
| >>> rotate_right32(2, 1) | ||
| 1 | ||
| >>> rotate_right32(1, 1) | ||
| 2147483648 | ||
| >>> rotate_right32(0x12345678, 4) | ||
| 2166572391 | ||
| >>> rotate_right32(-1, 1) | ||
| Traceback (most recent call last): | ||
| ... | ||
| ValueError: x must be a non-negative integer | ||
| >>> rotate_right32(1, -3) | ||
| Traceback (most recent call last): | ||
| ... | ||
| ValueError: k must be non-negative | ||
| """ | ||
| if not isinstance(x, int) or x < 0: | ||
| raise ValueError("x must be a non-negative integer") | ||
| if not isinstance(k, int) or k < 0: | ||
| raise ValueError("k must be non-negative") | ||
| mask = (1 << 32) - 1 | ||
| k &= 31 | ||
| return ((x & mask) >> k) | ((x << (32 - k)) & mask) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| import doctest | ||
|
|
||
| doctest.testmod() | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please provide descriptive name for the parameter:
n