- Notifications
You must be signed in to change notification settings - Fork 46.7k
/
Copy pathbinary_shifts.py
109 lines (94 loc) · 3.32 KB
/
binary_shifts.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# Information on binary shifts:
# https://docs.python.org/3/library/stdtypes.html#bitwise-operations-on-integer-types
# https://www.interviewcake.com/concept/java/bit-shift
deflogical_left_shift(number: int, shift_amount: int) ->str:
"""
Take in 2 positive integers.
'number' is the integer to be logically left shifted 'shift_amount' times.
i.e. (number << shift_amount)
Return the shifted binary representation.
>>> logical_left_shift(0, 1)
'0b00'
>>> logical_left_shift(1, 1)
'0b10'
>>> logical_left_shift(1, 5)
'0b100000'
>>> logical_left_shift(17, 2)
'0b1000100'
>>> logical_left_shift(1983, 4)
'0b111101111110000'
>>> logical_left_shift(1, -1)
Traceback (most recent call last):
...
ValueError: both inputs must be positive integers
"""
ifnumber<0orshift_amount<0:
raiseValueError("both inputs must be positive integers")
binary_number=str(bin(number))
binary_number+="0"*shift_amount
returnbinary_number
deflogical_right_shift(number: int, shift_amount: int) ->str:
"""
Take in positive 2 integers.
'number' is the integer to be logically right shifted 'shift_amount' times.
i.e. (number >>> shift_amount)
Return the shifted binary representation.
>>> logical_right_shift(0, 1)
'0b0'
>>> logical_right_shift(1, 1)
'0b0'
>>> logical_right_shift(1, 5)
'0b0'
>>> logical_right_shift(17, 2)
'0b100'
>>> logical_right_shift(1983, 4)
'0b1111011'
>>> logical_right_shift(1, -1)
Traceback (most recent call last):
...
ValueError: both inputs must be positive integers
"""
ifnumber<0orshift_amount<0:
raiseValueError("both inputs must be positive integers")
binary_number=str(bin(number))[2:]
ifshift_amount>=len(binary_number):
return"0b0"
shifted_binary_number=binary_number[: len(binary_number) -shift_amount]
return"0b"+shifted_binary_number
defarithmetic_right_shift(number: int, shift_amount: int) ->str:
"""
Take in 2 integers.
'number' is the integer to be arithmetically right shifted 'shift_amount' times.
i.e. (number >> shift_amount)
Return the shifted binary representation.
>>> arithmetic_right_shift(0, 1)
'0b00'
>>> arithmetic_right_shift(1, 1)
'0b00'
>>> arithmetic_right_shift(-1, 1)
'0b11'
>>> arithmetic_right_shift(17, 2)
'0b000100'
>>> arithmetic_right_shift(-17, 2)
'0b111011'
>>> arithmetic_right_shift(-1983, 4)
'0b111110000100'
"""
ifnumber>=0: # Get binary representation of positive number
binary_number="0"+str(bin(number)).strip("-")[2:]
else: # Get binary (2's complement) representation of negative number
binary_number_length=len(bin(number)[3:]) # Find 2's complement of number
binary_number=bin(abs(number) - (1<<binary_number_length))[3:]
binary_number= (
"1"+"0"* (binary_number_length-len(binary_number)) +binary_number
)
ifshift_amount>=len(binary_number):
return"0b"+binary_number[0] *len(binary_number)
return (
"0b"
+binary_number[0] *shift_amount
+binary_number[: len(binary_number) -shift_amount]
)
if__name__=="__main__":
importdoctest
doctest.testmod()