Bitwise Operators in a Nutshell

Amirata Khodaparast
3 min readAug 15, 2018

--

A friend of mine sent me a link to an article in which I found a Ruby code snippet that was doing something like this: x =| y which was new to me. So I did some research about in and found out that | is an OR bitwise operator. Then I learned about other bitwise operators and decided to write a blog post about them.

What are bitwise operators?

Bitwise operators are just like regular operators, i.g., “&&”, “+”, “||”, etc. The only difference is they deal with the integers at the binary level, i.e., they look at the integers as binary digits or bits.

There’s a lot of bitwise operators, however Ruby only supports six:

Image from https://www.calleerlandsson.com/posts/rubys-bitwise-operators/

In order to be able to convert an integer to its binary equivalent we’ll use Ruby’s to_s method and pass 2 as an argument like this:

10.to_s(2) # => "1010"

Now that we have the binary equivalent, let’s see how each operator works:

Bitwise AND “&”

The bitwise AND operator goes through the binary representation of integers and compares the two binary equivalents bit by bit. In order for the returning bit to be 1 both bits being compared have to be 1.

10.to_s(2) # => "1010"
# Since the first string is shorter than the second one we can add an imaginary "0" in front of it just so it would visualize the comparison better.
# => "01010"
20.to_s(2) # => "10100"
(10 & 20).to_s(2) # => "0"

Another example:

10.to_s(2)         # => "01010" This is not the actual return value.
22.to_s(2) # => "10100"
(10 & 22).to_s(2) # => "10"

Bitwise OR “|”

It works the same way as bitwise AND. The difference is it returns 1 if at least one bit is 1.

example:

10.to_s(2)         # => "01010" This is not the actual return value.
24.to_s(2) # => "11000"
(10 | 24).to_s(2) # => "11010"

Bitwise XOR “^”

It operates just like the previous two, but now it returns 1 if one and only one bit is 1.

example:

10.to_s(2)         # => "01010" This is not the actual return value.
24.to_s(2) # => "11000"
(10 ^ 24).to_s(2) # => "10010"

Bitwise NOT “~”

Bitwise NOT negates the binary representation of an integer, bit by bit. So, it returns 1 for every 0 and 0 for every 1.

10.to_s(2)    # => "1010"
~10 # => -11
(~10).....* # => "0101"
#* We can't use the .to_s method here

Bitwise left shift “<<” and right shift “>>”

Bitwise left shift and right shift, shift the binary number to the left and right by the given number(the number to the right).

Right shift adds zeroes to the right and left shift removes the bits from the end.

Read more on how the shift works here.

25.to_s(2)        # => "11001"
(25 << 2).to_s(2) # => "1100100"
25.to_s(2) # => "11001"
(25 >> 2).to_s(2) # => "110"

Practical Examples

Bitwise operations are necessary particularly in lower-level programming such as device drivers, low-level graphics, communications protocol packet assembly, and decoding. — Wikipedia

I found these other usages as well as the ones mentioned above

  1. It is usually faster than regular operators, such as “*”, “/”, etc.
(7 << 3) + 7 # Does the same as 7 * 9
# => 63

2. If you apply XOR twice it’ll undo the the first change.

example:

x = 10
y = 24
z = x ^ y
z # => 18z ^ y # => You'll get x which is 10z ^ x # => You'll get y which is 24

This can be used in graphics programming for selection highlighting.

References:

Rapid TablesUsed for binary to decimal conversions

Wikipedia — Arithmetic Shift

Real World Use Cases of Bitwise Operators Stack Over Flow

Ruby’s Bitwise Operators Calle Erlandsson’s blog

What is the use or benefit of bitwise operators — Quora

Bitwise OperationWikipedia

--

--