This is an introduction to using bitwise operators and you'd learn how to do magical stuffs with them. So basically bit operations are used to manipulate bits (binary numbers) and here are the signs used:
&
A bitwise AND is a binary operation that takes two bits and performs the logical AND operation on them. If the bits compared are 1, then bit in the resulting binary representation is 1 (1 & 1 = 1)
; otherwise, the result is 0 (1 & 0 = 0 and 0 & 0 = 0)
source.
Here is a typical example:
A | B | A & B |
---|---|---|
0 | 0 | 0 |
1 | 0 | 0 |
0 | 1 | 0 |
1 | 1 | 1 |
5 & 4 | 1 0 1
5 = 101 | & 1 0 0
4 = 100 = 1 0 0 => 4
|
A bitwise OR is a binary operation that takes two bits and performs the inclusive OR operation on them. If the bits compared are 0, the bit in the resulting binary representation is 1 (0 | 0 = 0)
; otherwise, the result is 0 (1 | 0 = 1 and 0 | 1 = 1)
source.
Here is a typical example:
A | B | A | B |
---|---|---|
0 | 0 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
1 | 1 | 1 |
5 | 4 | 1 0 1
5 = 101 | | 1 0 0
4 = 100 = 1 0 1 => 5
^
A bitwise XOR is a binary operation that takes two bits and performs the logical exclusive OR operation on them. If the bits compared are different, then bit in the resulting binary representation is 1 (1 ^ 0 = 1)
; otherwise, the result is 0 (1 ^ 1 = 0 and 0 ^ 0 = 0)
source.
Here is a typical example:
A | B | A ^ B |
---|---|---|
0 | 0 | 0 |
1 | 0 | 1 |
0 | 1 | 0 |
1 | 1 | 0 |
5 ^ 4 | 1 0 1
5 = 101 | ^ 1 0 0
4 = 100 = 0 0 1 => 1
<<
In a left arithmetic shift, zeros are shifted in on the right; and the bits on the left are discarded source.
Here is a typical example:
5 << 2
5 = 101 | [1] 0 1 0 << 1 (first shift)
| | ^ added
| |------|
| removed
|
| [0] 1 0 0 << 2 (second shift)
| | ^ added
| |------|
| removed
| 5 << 2 = 1 0 0 = 20
Tip: a << b
= a * (2**b)
>>
In a right arithmetic shift, zeros are shifted in on the left; and the bits on the right are discarded source.
Here is a typical example:
5 >> 2
5 = 101 | 0 1 0 [1] >> 1 (first shift)
| added ^ |
| |------|
| removed
|
| 0 0 1 [0] >> 1 (second shift)
| added ^ |
| |------|
| removed
| 5 >> 2 = 0 0 1 = 1
Tip: a >> b
= a / (2**b)
~
The Not operator flips a bit i.e switching 1s to 0s and 0s to 1s.
Here is a typical example:
~ 103 | ~ 0000000001100111
| = 1111111110011000 = -104
It's fast, especially when compaired to operations like /
, *
and %
. Operations like /
and *
take too much time (O(%
(modulus) operator takes (O(
Given you have a configuration for a simple website, where you can show choose what kind of theme you want (dark or light theme) and an option to open links in a new tab or same page.
There are 2 different selections and 4 different options given as:
Most implementations, people would store these values on 2 different cookie slots in the browser and here we want to just store them in just one cookie since we have an understanding of bitwise operations.
Both options can be binary because we'd represent 0 for light-mode and 1 for dark-mode in the case of storing the theme.
cookie = 00 | 0 0 # 2 bits
| ^ ^
| Theme Open Links
cookie = 0 # 0b00
def set_darkmode(value):
"""Sets the theme slot in the cookie
Args:
value (bool): sets the theme to dark if `True`
else sets it to light
"""
global cookie
if value:
cookie = cookie | (1 << 1) # sets theme to dark mode
else:
cookie = cookie & ~(1 << 1) # unsets dark mode
def set_openlinks(value):
"""Sets the openlink slot in the cookie
Args:
value (bool): sets the openlink to new-tab if `True`
else sets it to same-page
"""
global cookie
if value:
cookie = cookie | 1 # sets openlink to new-tab
else:
cookie = cookie & ~1 # unsets new-tab
def get_mode():
# checks if the dark mode is set
return "dark" if (cookie >> 1) & 1 else "light"
def get_openlinks():
# checks if the new-tab bit is set
return "new tab" if (cookie & 1) == 1 else "same page"
print(get_mode()) # light
print(get_openlinks()) # same page
set_openlinks(True)
set_darkmode(True)
print(get_mode()) # dark
print(get_openlinks()) # new tab
Also check out a much broader example in my previous article.
If you found this helpful, consider following me on Twitter @0xosas.