How to be a bitWiser

Paul Ly
7 min readOct 27, 2018

Understanding bits and bitwise operators in JavaScript a bit better!

Vat is a bit?

Bit is actually an abbreviation for binary digit. Binary can be defined as relating to, composed of, or involving two things — computers use 0 and 1’s to communicate, convey information and complete actions. It is the computer language. All programming languages are broken down into 0 and 1’s for the computer to understand.

The binary digit 10110101 can be broken down as follows:

https://blog.penjee.com/wp-content/uploads/2015/03/binary-floating-point-binary-number-with-decimal-values.png

Resulting in the computation 128 + 32 + 16 + 4 + 1 and the sum is 181.

Try these on for size if you want a better understanding:

1     -->     00000001
2 --> 00000010
3 --> 00000011
4 --> 00000100
5 --> 00000101
12 --> 00001100
18 --> 00010010
25 --> 00011001
60 --> 00111100
178 --> 10110010

JavaScript

is a programming language and the master of web development. With the introduction and use of JavaScript, the web is now as we know it! While HTML is a markup language and the skeleton of a website and CSS being the clothes and fashion of an individual providing style and flair, JavaScript is communication itself. It allows one to interact with websites — you could go as far as to say it is a website’s behavior.

Negative Numbers

There are three techniques for dealing with negative people, I mean negative numbers — Signed Magnitude, One’s Complement, and Two’s Complement.

Signed Magnitude

is the notion that a binary digit can tell us whether or not it’s positive or negative with its leftmost digit. Take the aforementioned 10110101.

“JavaScript treats their operands as a sequence of 32 bits…” — 10110101 is actually being treated as 00000000000000000000000010110101.

Therefore the leftmost digit is 0, telling us this is a positive number. The opposite is true where 1 refers to negative numbers.

If we take the number 12 and turn it into binary, it would be 00001100. What would -12 be then? It would be 10001100.

Note: too lazy, and unnecessary to make these into 32 bit sequences to drive this point home.

One’s Complement

is the technique where you convert a binary digit to its completely opposite form — 10110101 would then become 01001010. The 0’s change into 1’s and vice-versa.

Two’s Complement

is a technique to negate a number, turn a positive into a negative and turn a negative into a positive.

5 --> 0101     // as 4 bit0101 --> 1010  // take the complement// add one
1010
+ 0001
------
1011
1011 may look like
8 + 2 + 1 = 11
but it's actually
-8 + 2 + 1 = -5 // remember Signed Magnitude from above

By using this technique, you can change a subtraction equation into an addition equation. Just like in math, or maths like our English friends across the pond like to say, you can reflect addition and subtraction equations as follows:

12 - 5
12 + -5
-5 + 12

The result, 7, remains the same and true regardless how you prefer to look at it! Therefore it would look like this for binary digits:

12 - 5
1100 - 101 // binary forms
1100 + 010 // take 5’s binary's complement

The addition from here is as we all know:

 1100
+ 010
------
1110

The exception now is that we take the first digit, 1, remove it here and add it:

 110
+ 1
-----
111 --> 4 + 2 + 1 --> 7

Bitwise Logical Operators

The operators are &, |, ^, and ~.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators

& or AND, is much like the more familiar && and returns only if both are the same, or true.

| or OR, as you might’ve guessed, is like || and returns 1 or false whenever it is present.

^ compares and returns true or 0 if both are the same and 1 if they aren’t.

~ or NOT, converts 0 into 1 and 1 into 0.

Bitwise Shift Operators

We have the left shift (<<), right shift (>>), and zero-fill right shift (>>>) operators.

If you’re familiar with Ruby then these may look familiar and are known as the shovel operator — “shovel” may still be a good term to keep in mind as you are moving, shifting or shoveling the order around.

Left

As the name suggests by using <<, you are shifting or moving the order of a binary digit to the left, to the left.

  1. Converts the digit to its binary form
  2. Shifts everything to the left x times, and fills the emptiness with 0's
  3. Converts the new binary digit to its decimal form
Operation           Computation                   Result
15 << 2 => 1111 + 00 = 111100 --> 60

The left shift operator effectively multiplies the digit by 2 as a result.

15 << 0  =   15
15 << 1 = 30
15 << 2 = 60
15 << 3 = 120
15 << 4 = 240

Right

The side where one believes they’re in, but their partner in crime always refutes.

Operation           Computation                  Result
15 >> 2 => 01111 --> 011
00 + 11 = 0011 --> 3
  1. Converts the digit to its binary form
  2. Removes x spaces from the right
  3. Fills the emptiness with the leftmost bit
  4. Converts the new binary digit to its decimal form

The right shift operator is also known for its sign-propagating. Why? Because you keep the leftmost digit the same, thus the sign (+ / -) is also the same.

Zero-Fill Right

The same as the right shift operator, but instead of filling in empty spaces with the leftmost digit, you fill it in with 0's.

Operation         Computation              Result
9 >>> 2 1001 --> 0010 2
-9 >>> 2 11111111111111111111111111110111
-->
00111111111111111111111111111101
1073741821

How can any of this actually be helpful?

You could use this to determine if a number is odd or even:

const x = 5.toString(2)  // convert a number into binary
x[x.length - 1] === '1' // checks the last digit
// => true AKA it's an odd number

Or more handily, you can use this to better determine combinations of true/false statements using flags and masks.

You can read more about that here, and here.

Some Fun

It’s funny bc I just finished watching The Crown

I wanted to manually do some maths — it’s supposed to make sense since it’s short for mathematics, but i digress — with bits and JavaScript:

function digitToBinary(n) {
return n.toString(2)
}
function binaryPad(n, len) {
return n.padStart(len, '0')
}
function binarySetup(n1, n2) { let b1 = digitToBinary(n1)
let b2 = digitToBinary(n2)
let len = b1.length > b2.length ? b1.length : b2.length
if (b1.length !== len) {
b1 = binaryPad(b1, len)
}
if (b2.length !== len) {
b2 = binaryPad(b2, len)
}
return [b1, b2]
}
function binaryComplement(b) {
return b.split('').map(n => {
if (n === '0') {
return '1'
}
if (n === '1') {
return '0'
}
}).join('')
}
function addBits(b1, b2) { constlen = b1.length
const s1 = b1.split('')
const s2 = b2.split('')
let bitSum = ''
for (let i = len - 1; i >= 0; i--) { let sum = parseInt(s1[i], 10) + parseInt(s2[i], 10) if (sum === 0 || sum === 2) {
bitSum = '0' + bitSum
}
if (sum === 1 || sum === 3) {
bitSum = '1' + bitSum
}
if (sum === 2 || sum === 3) { if (i !== 0) {
s1[i - 1] = parseInt(s1[i - 1], 10) + 1
} else {
bitSum = "1" + bitSum;
}
}
}
return bitSum
}
function subtractBits(b1, b2) { b2 = binaryComplement(b2) let subtotal = addBits(b1, b2)
subtotal = subtotal.slice(1)

const negative = binaryPad('1', subtotal.length)
const total = addBits(subtotal, negative)
return total
}
function addNumbers(n1, n2) { const [b1, b2] = binarySetup(n1, n2)
const binarySum = addBits(b1, b2)
return parseInt(binarySum, 2)
}
function subtractNumbers(n1, n2) { const [b1, b2] = binarySetup(n1, n2)
const binaryDiff = subtractBits(b1, b2)
return parseInt(binaryDiff, 2)
}

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Paul Ly
Paul Ly

Written by Paul Ly

Full-Stack Web Developer - Former JPM Analyst, ESL Teacher, and Expat

No responses yet

Write a response