Skip to content

Instantly share code, notes, and snippets.

@lfalanga
Last active December 22, 2019 07:03
Show Gist options
  • Save lfalanga/2f5b1226948862b435b40559c687406a to your computer and use it in GitHub Desktop.
Save lfalanga/2f5b1226948862b435b40559c687406a to your computer and use it in GitHub Desktop.
# Example 1: Basic bitwise operations
print 5 >> 4 # Right Shift
# => 0
print 5 << 1 # Left Shift
# => 10
print 8 & 5 # Bitwise AND
# => 0
print 9 | 4 # Bitwise OR
# => 13
print 12 ^ 42 # Bitwise XOR
# => 38
print ~88 # Bitwise NOT
# => -89
# Example 2: The Base 2 Number System
"""
NOTE:
When we count, we usually do it in base 10. That means that each place in a
number can hold one of ten values, 0-9. In binary we count in base two, where
each place can hold one of two values: 0 or 1. The counting pattern is the same
as in base 10 except when you carry over to a new column, you have to carry
over every time a place goes higher than one (as opposed to higher than 9 in
base 10).
For example, the numbers one and zero are the same in base 10 and base 2. But
in base 2, once you get to the number 2 you have to carry over the one,
resulting in the representation “10”. Adding one again results in “11” (3) and
adding one again results in “100” (4).
Contrary to counting in base 10, where each decimal place represents a power of
10, each place in a binary number represents a power of two (or a bit). The
rightmost bit is the 1’s bit (two to the zero power), the next bit is the 2’s
bit (two to the first), then 4, 8, 16, 32, and so on.
The binary number ‘1010’ is 10 in base 2 because the 8’s bit and the 2’s bit
are “on”:
8's bit 4's bit 2's bit 1's bit
1 0 1 0
8 + 0 + 2 + 0 = 10
In Python, you can write numbers in binary format by starting the number with
0b. When doing so, the numbers can be operated on like any other number!
"""
print 0b1, #1
print 0b10, #2
print 0b11, #3
print 0b100, #4
print 0b101, #5
print 0b110, #6
print 0b111 #7
print "******"
print 0b1 + 0b11
print 0b11 * 0b11
""" Printed out result
1 2 3 4 5 6 7
******
4
9
"""
# Example 3: Couting in binary
"""
NOTE:
2 ** 0 = 1
2 ** 1 = 2
2 ** 2 = 4
2 ** 3 = 8
2 ** 4 = 16
2 ** 5 = 32
2 ** 6 = 64
2 ** 7 = 128
2 ** 8 = 256
2 ** 9 = 512
2 ** 10 = 1024
"""
one = 0b1
two = 0b10
three = 0b11
four = 0b100
five = 0b101
six = 0b110
seven = 0b111
eight = 0b1000
nine = 0b1001
ten = 0b1010
eleven = 0b1011
twelve = 0b1100
# Example 4: Using bin() funtion to get a binary representation of the number
print bin(1)
print bin(2)
print bin(3)
print bin(4)
print bin(5)
""" Printed out result
0b1
0b10
0b11
0b100
0b101
"""
# Example 5: Getting the base 10 equivalent using int() function
print int("1",2)
print int("10",2)
print int("111",2)
print int("0b100",2)
print int(bin(5),2)
# Print out the decimal equivalent of the binary 11001001.
print int("11001001",2)
""" Printed out result
1
2
7
4
5
201
"""
# Example 6: Shift operators (<< and >>)
"""
NOTE:
Shift operations are similar to rounding down after dividing and multiplying
by 2 (respectively) for every time you shift, but it’s often easier just to
think of it as shifting all the 1s and 0s left or right by the specified number
of slots.
Note that you can only do bitwise operations on an integer. Trying to do them
on strings or floats will result in nonsensical output!
"""
# Left Bit Shift (<<)
0b000001 << 2 == 0b000100 (1 << 2 = 4) # = 1 * 2 * 2 = 1 * (2^2)
0b000101 << 3 == 0b101000 (5 << 3 = 40) # = 5 * 2 * 2 * 2 = 5 * (2^3)
# Right Bit Shift (>>)
0b0010100 >> 3 == 0b000010 (20 >> 3 = 2) # = 20 / 2 / 2 / 2 = 20 / (2^3)
0b0000010 >> 2 == 0b000000 (2 >> 2 = 0) # = 2 / 2 / 2 = 2 / (2^2)
# Example 7: Shifting binary numbers
shift_right = 0b1100
shift_left = 0b1
# Your code here!
shift_right = shift_right >> 2
shift_left = shift_left << 2
print bin(shift_right)
print bin(shift_left)
""" Printed out result
0b11
0b100
"""
# Example 8: AND (&) operation
"""
NOTE:
The bitwise AND (&) operator compares two numbers on a bit level and returns a
number where the bits of that number are turned on if the corresponding bits
of both numbers are 1. For example:
a: 00101010 42
b: 00001111 15
===================
a & b: 00001010 10
As you can see, the 2’s bit and the 8’s bit are the only bits that are on in
both a and b, so a & b only contains those bits. Note that using the & operator
can only result in a number that is less than or equal to the smaller of the
two values.
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
Therefore,
0b111 (7) & 0b1010 (10) = 0b10
"""
print bin(0b1110 & 0b101)
# => 0b100
print 0b1110 & 0b101
# => 4
# Example 9: OR (|) operation
"""
NOTE:
The bitwise OR (|) operator compares two numbers on a bit level and returns a
number where the bits of that number are turned on if either of the
corresponding bits of either number are 1. For example:
a: 00101010 42
b: 00001111 15
================
a | b: 00101111 47
Note that the bitwise | operator can only create results that are greater than
or equal to the larger of the two integer inputs.
So remember, for every given bit in a and b:
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
Meaning
110 (6) | 1010 (10) = 1110 (14)
"""
print bin(0b1110 | 0b101) # => 0b1111
print 0b1110 | 0b101 # => 15
# Example 10: XOR (^) operation
"""
NOTE:
The XOR (^) or exclusive or operator compares two numbers on a bit level and
returns a number where the bits of that number are turned on if either of the
corresponding bits of the two numbers are 1, but not both.
a: 00101010 42
b: 00001111 15
================
a ^ b: 00100101 37
Keep in mind that if a bit is off in both numbers, it stays off in the result.
Note that XOR-ing a number with itself will always result in 0.
So remember, for every given bit in a and b:
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
Therefore:
111 (7) ^ 1010 (10) = 1101 (13)
"""
print bin(0b1110 ^ 0b101) # => 0b1011
print 0b1110 ^ 0b101 # => 11
# Example 11: NOT (~) operation
"""
NOTE:
The bitwise NOT operator (~) just flips all of the bits in a single number.
What this actually means to the computer is actually very complicated, so we’re
not going to get into it. Just know that mathematically, this is equivalent to
adding one to the number and then making it negative.
And with that, you’ve seen all of the basic bitwise operators! We’ll see what
we can do with these in the next section.
"""
print ~1
print ~2
print ~3
print ~42
print ~123
print ~-1
print ~-2
""" Printed out result
-2
-3
-4
-43
-124
0
1
"""
# Example 12: Bit masking
"""
A bit mask is just a variable that aids you with bitwise operations. A bit mask
can help you turn specific bits on, turn others off, or just collect data from
an integer about which bits are on or off.
"""
num = 0b1100
mask = 0b0100
desired = num & mask
if desired > 0:
print "Bit was on"
def check_bit4(input):
if input & 0b1000 == 0b1000:
return 'on'
else:
return 'off'
# Example 13: Turning on a bit using OR (|)
"""
NOTE:
You can also use masks to turn a bit in a number on using |. For example, let’s
say I want to make sure the rightmost bit of number a is turned on. I could do
this:
a = 0b110 # 6
mask = 0b1 # 1
desired = a | mask # 0b111, or 7
Using the bitwise | operator will turn a corresponding bit on if it is off and
leave it on if it is already on.
"""
a = 0b10111011
mask = 0b00000100
print bin(a | mask) # => 0b10111111
# Example 14: Flipping bits using XOR (^)
"""
Using the XOR (^) operator is very useful for flipping bits. Using ^ on a bit
with the number one will return a result where that bit is flipped.
For example, let’s say I want to flip all of the bits in a. I might do this:
a = 0b110 # 6
mask = 0b111 # 7
desired = a ^ mask # 0b1
"""
a = 0b11101110
mask = 0b11111111 # This mask will flip all the bits in 'a' variable
print bin(a ^ mask)
# => 0b10001
# Example 15: Slip and Slide
"""
Finally, you can also use the left shift (<<) and right shift (>>) operators
to slide masks into place.
a = 0b101
# Tenth bit mask
mask = (0b1 << 9) # One less than ten
desired = a ^ mask
Let’s say that I want to turn on the 10th bit from the right of the integer a.
Instead of writing out the entire number, we slide a bit over using the <<
operator.
We use 9 because we only need to slide the mask nine places over from the first
bit to reach the tenth bit.
"""
def flip_bit(number, n):
mask = (0b1 << (n-1))
result = number ^ mask
return bin(result)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment