Bitwise operators in JavaScript

Bitwise operators act on the level of individual bits which allows for fast comparisons and calculations. I’ll be going over a couple of ways to use bitwise opeartors in JavaScript since it’s not entirely clear at first. Some of the examples shown are from various sources which I’ve accumlated over time in which I’m going to elaborate on them.

Bitwise AND

Return a one if the two bits are both one.

``````5 & 7 // 5

00000101 // 5
00000111 // 7
--------
00000101 // 5
``````

JSBin example

Check if number is even or odd:

``````((n & 1) === 0) // true if even

((1 & 1) === 0) // false
((2 & 1) === 0) // true

The how:

// 1 & 1
00000001 // 1
00000001 // 1
--------
00000001 // 1 (odd)

// 2 & 1
00000010 // 2
00000001 // 1
--------
00000000 // 0 (even)
``````

Get the difference between two hex values:

``````var a = 0xF0; // 240
var b = 0xFF; // 255

a & b // 240
~a & b // 15 is the difference

The how:

(240).toString(2) // "11110000"
(255).toString(2) // "11111111"

11110000 // 240
11111111 // 255
--------
11110000 // 240

(~240).toString(2) // "-11110001"
(~240 >>> 0).toString(2) // "11111111111111111111111100001111"

00001111 // ~240 = -241
11111111 // 255
--------
00001111 // 15

The tilde "~" is the bitwise NOT which inverts the bits.
">>>" is the zero-fill right shift operator which converts to a 32 bit unsigned value.

Another way to look at it:

NOT(F0) && FF = 0F && FF = 0F

(240 >>> 0).toString(16) // "f0"
(255 >>> 0).toString(16) // "ff"

~('0xF0' >>> 0) // -241
(-241 >>> 0).toString(16) // "ffffff0f"

FFFFFF0F // -241
000000FF // 255
--------
0000000F // 15
``````

JSBin example

Bitwise OR

Return a one if one of the two bits is a one.

``````5 | 7 // 7

The how:

00000101 // 5
00000111 // 7
--------
00000111 // 7
``````

JSBin example

Fast truncation:

``````1.4 | 0 // 1
-1.4 | 0 // -1
``````

``````var mask = 0x0003;
var flag = 0xFFF0;
var result = flag | mask; // 65523
result.toString(16); // "fff3"

The how:

0000000000000011 // 3
1111111111110000 // 65520
----------------
1111111111110011 // 65523

(65523).toString(16); // "fff3"
``````

JSBin example

``````var mask = 0x0003;
var flag = 0xFFFF;
var result = flag & ~mask;
result.toString(16); // "fffc"

The how:

(0x003 >>> 0).toString(2)
// 0000000000000000000000000000011

(~0x003 >>> 0).toString(2)
// 1111111111111111111111111111100

0000000000000011 // 0x003
1111111111111100 // ~0x003
-------------------------------
1111111111111100

1111111111110011 // 65523

parseInt('1111111111110011', 2); // 65523

(65523).toString(16); // "fffc"
``````

JSBin example

Bitwise XOR

Return a one if either bit is a one or zero but not both.

``````5 ^ 7 // 2

The how:

00000101 // 5
00000111 // 7
--------
00000010 // 2
``````

JSBin example

Variable swap:

``````var a = 1,
b = 2;

a = a ^ b;
b = b ^ a;
a = a ^ b;

// shorthand

a ^= b;
b ^= a;
a ^= b;

// b = 1, a = 2

The how:

'a'.charCodeAt(0) // 97
'b'.charCodeAt(0) // 98

(97).toString(2) // 1100001
(98).toString(2) // 1100010

// a ^= b;
1100001 // 97 (a)
1100010 // 98 (b)
-------
0000011 // 3 (a)

// b ^= a;
1100010 // 98 (b)
0000011 // 3 (a)
-------
1100001 // 97 (b)

// a ^= b;
0000011 // 3 (a)
1100001 // 97 (b)
-------
1100010 // 98 (a)

String.fromCharCode(97); // b = 'a'
String.fromCharCode(98); // a = 'b'
``````

JSBin example

Toggle switch:

``````var a = 1;

a = a ^ 1; // 0
a = a ^ 1; // 1
a = a ^ 1; // 0

// shorthand

a ^= 1; // 0
a ^= 1; // 1
a ^= 1; // 0

The how:

a ^= 1;
00000001 // 1 (a)
00000001 // 1
--------
00000000 // 0 (a)

a ^= 1;
00000000 // 1 (a)
00000001 // 1
--------
00000001 // 1 (a)

a ^= 1;
00000001 // 1 (a)
00000001 // 1
--------
00000000 // 0 (a)
``````

JSBin example

Determine if two integers have opposite signs:

``````var x = 1,
y = 1;

(x ^ y) < 0 // false

The how:

00000001 // x
00000001 // y
--------
00000000 // 0, so 0 < 0 = false

var x = 1,
y = -1;

((x ^ y) < 0); // true

The how:

0000000000000000000000000000001 // x = (1).toString(2)
1111111111111111111111111111110 // y = (~1 >>> 0).toString(2)
------------------------------- // ^ two's complement - flips bits and adds one
1111111111111111111111111111111 // -1, so -1 < 0 = true
``````

JSBin example

Bitwise NOT

Inverts the bits.

``````[x = -(x + 1)]

~5 // -6

The how:

-6 = -(5 + 1)

(5).toString(2)
00000101

// two's complement
(~5 >>> 0).toString(2)
11111111111111111111111111111010
``````

JSBin example

Shorthand `indexOf`:

``````!!~[1].indexOf(2) // false
!!~[1].indexOf(1) // true

The how:

[1].indexOf(2) // -1
[1].indexOf(1) // 0

~-1 // 0
~0 // -1

!!0 // false
!!-1 // true
``````

JSBin example

Bitwise double NOT

Fast truncation:

``````// for positive numbers it can be a faster substitute for Math.floor()
~~(5.3) // 5

// negative truncation
~~(-5.3) // -5

// If it can't be parsed to a number than result will always be zero
~~('foo') // 0
~~({}) // 0
``````

Shift operators

Shift bits a specified number of bit positions.

``````8 >> 1 // 4
8 >> 2 // 2

8 << 1 // 16
8 << 2 // 32

The how:

// 8 >> 1
00001000 // 8
00000100 // 4

// 8 >> 2
00001000 // 8
00000010 // 2

// 8 << 1
00001000 // 8
00010000 // 16

// 8 << 2
00001000 // 8
00100000 // 32
``````

JSBin example

Bitwise left shift operator can be a replacement for `Math.pow()` when dealing with bases of 2:

``````Math.pow(2,24) === 1<<24 // true
``````

JSPerf test

Decimal to Integer:

``````4.12 >> 0 // 4
4.12 << 0 // 4

-4.12 >> 0 // -4
-4.12 << 0 // -4
``````

JSBin example

Integer multiplication and division:

``````// 20 * 2
20.5 << 1 // 40

// 20 / 2
20.5 >> 1 // 10
``````

JSBin example

Hex to RGB:

``````var hex = '00FF99';
var dec = parseInt(hex, 16); // 65433

var rgb = {};
rgb.r = (dec >> 16) & 0xFF; // 0
rgb.g = (dec >> 8) & 0xFF; // 255
rgb.b = (dec) & 0xFF; // 153

The how:

// rgb.b
(65433).toString(2)
1111111110011001

parseInt('ff', 16) // 255
00000000011111111

1111111110011001 // 65433
0000000011111111 // 255
---------------
0000000010011001

parseInt('10011001', 2) // 153
``````

JSBin example

RGB to Hex:

``````var r = 0, g = 255, b = 153;

var hex = '#' +
(
(1 << 24) +
(r << 16) +
(g << 8) + b
)
.toString(16)
.substr(1);

hex // "#00ff99"
``````

JSBin example

Zero-fill Right Bit Shifting

Shifts the operand a specified number of bits to the right and zero bits are shifted in from the left. Sign bit is zero so result is always a 32-bit unsigned integer.

``````5 >>> 0 // 5
"5" >>> 0 // 5
"hello" >>> 0 // 0
-2 >>> 0 // 4294967294
3.6 >>> 0 // 3
true >>> 0 // 1
0xFF >>> 1 // 127

The how:

5 >>> 0
00000101 // 5

(-2 >>> 0).toString(2)
'11111111111111111111111111111110' // 4294967294

0xFF >>> 1
parseInt('0xFF', 16).toString(2)
111111111 // 255
011111111 // 127
``````

JSBin example

Getting creative

Finding the smallest number:

``````var x = 9;
var y = 5;

var smallest = y ^ ((x ^ y) & -(x < y));

smallest // 5

The how:

00001001 // x = (9 >>> 0).toString(2)
00000101 // y = (5 >>> 0).toString(2)

(x ^ y)
00001001
00000101
--------
00001100 // parseInt('00001100', 2) = 12

-(x < y)
-(false)
-0
0

5 ^ (12 & 0)

(12 & 0)
00001100 // (12 >>> 0).toString(2)
00000000 // 0
--------
00000000 // 0

(5 ^ 0)
00000101 // 5
00000000 // 0
--------
00000101 // parseInt('00000101', 2) = 5
``````

Finding the largest number:

``````var x = 9;
var y = 5;

var largest = x ^ ((x ^ y) & -(x < y));

largest // 5

The how:

00001001 // x = (9 >>> 0).toString(2)
00000101 // y = (5 >>> 0).toString(2)

(x ^ y)
00001001
00000101
--------
00001100 // parseInt('00001100', 2) = 12

-(x < y)
-(false)
-0
0

9 ^ (12 & 0)

(12 & 0)
00001100 // (12 >>> 0).toString(2)
00000000 // 0
--------
00000000 // 0

(9 ^ 0)
00001001 // 9
00000000 // 0
--------
00001001 // parseInt('00001001', 2) = 9
``````

If number is power of 2:

``````var v = 8;

var isPowerOf2 = v && !(v & (v - 1));

isPowerOf2 // true

The how:

(v - 1)
(8 - 1)
7

(v & 7)
00001000 // (8).toString(2)
00000111 // (7).toString(2)
--------
00000000

!(0)
true

v && 0
(8 && true)
(!!8 && true)
(true && true)
true
``````

JSBin examples

Examples stolen from Bit Twiddling Hacks by Sean Eron Anderson.

Create array of bits of a number:

``````var index, bitMask;
var num = 5;

var array = [];
array.push((bitMask & num ? 1 : 0 ));
}

array // [0, 0, 0, 0, 0, 1, 0, 1]
``````

JSBin example

Stolen from Getting Bitwise with JavaScript by Rebecca Murphey.

Conversions

Binary to Decimal:

``````function binaryToDecimal(binaryString) {
return parseInt(binaryString, 2);
}

binaryToDecimal('11111111'); // 255
``````

JSBin example

Decimal to Binary:

``````function decimalToBinary(decimal) {
return (decimal >>> 0).toString(2);
}

decimalToBinary(255); // "11111111"
``````

JSBin example

``````function decimalToHex(decimal) {
return (decimal).toString(16);
}

decimalToHex(255); // "FF"
``````

JSBin example

``````function hexToDecimal(hex) {
return parseInt(hex, 16);
}

hexToDecimal('FF'); // 255
``````

JSBin example

``````function binaryToHex(binaryString) {
return parseInt(binaryString, 2).toString(16);
}

binaryToHex('11111111'); // "ff"
``````

JSBin example

``````function hexToBinary(hex) {
return (parseInt(hex, 16)).toString(2);
}

hexToBinary('FF'); // "11111111"
``````

JSBin example

Binary to Character:

``````function binaryToChar(binaryString) {
return String.fromCharCode(parseInt(binaryString, 2));
}

binaryToChar('01000001'); // "A"
``````

JSBin example

Character to Binary:

``````function charToBinary(char) {
return (char.charCodeAt(0)).toString(2);
}

charToBinary('A'); // "01000001"
``````

JSBin example

Conclusion

There are definitely some interesting things you can do with bitwise operators. They are not commonly used due to how hard it can be to wrap your head around them, but bitwise operators can definitely improve performance of your application since they are technically faster than using built in methods. The only downside is it makes the code a little less unreadable. But it might be worth it depending on your needs.

I’d love to see other creative uses of bitwise operators, share if you may.