Skip to content

Commit 9a51e83

Browse files
committed
feat(bit_manipulation): add swap_bits function with doctests and validation
1 parent 3cea941 commit 9a51e83

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
"""
2+
Swap two bits at given positions in a non-negative integer using bitwise operators.
3+
4+
Wikipedia reference:
5+
https://en.wikipedia.org/wiki/Bit_manipulation
6+
"""
7+
8+
9+
def swap_bits(number: int, i: int, j: int) -> int:
10+
"""
11+
Swap the bits at the position i and j (0-indexed from right side)
12+
13+
Arguments:
14+
number (int): Non-negative integer whose bits are to be swapped.
15+
i (int): Index of 1st bit to swap.
16+
j (int): Index of 2nd bit to swap.
17+
18+
Returns:
19+
int: Integer obtained after swapping of bits.
20+
21+
Raises:
22+
TypeError: If argument is not an Integer
23+
ValueError: Invalid argument or bit positions.
24+
25+
Examples:
26+
>>> swap_bits(28, 0, 2) # 11100 -> swap rightmost bits 0 and 2
27+
25
28+
>>> swap_bits(15, 1, 2) # 1111 -> swapping the bits 1 and 2
29+
15
30+
>>> swap_bits(10, 0, 3) # 1010 -> swap the bits 0 and 3
31+
3
32+
>>> swap_bits(10.5, 0, 3)
33+
Traceback (most recent call last):
34+
...
35+
TypeError: All arguments MUST be integers!
36+
>>> swap_bits(-5, 1, 3)
37+
Traceback (most recent call last):
38+
...
39+
ValueError: The number MUST be non-negative!
40+
>>> swap_bits(10, -1, 2)
41+
Traceback (most recent call last):
42+
...
43+
ValueError: Bit positions MUST be non-negative!
44+
"""
45+
if not all(isinstance(x, int) for x in (number, i, j)):
46+
raise TypeError("All arguments MUST be integers!")
47+
48+
if number < 0:
49+
raise ValueError("The number MUST be non-negative!")
50+
51+
if i < 0 or j < 0:
52+
raise ValueError("Bit positions MUST be non-negative!")
53+
54+
# Extraction of Bits
55+
bit_first = (number >> i) & 1
56+
bit_second = (number >> j) & 1
57+
58+
# If bits differ swap them
59+
if bit_first != bit_second:
60+
number ^= (1 << i) | (1 << j)
61+
62+
return number
63+
64+
65+
if __name__ == "__main__":
66+
import doctest
67+
68+
doctest.testmod()

0 commit comments

Comments
 (0)