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)

JSBin example / JSPerf test

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 = 0 F && FF = 0 F ( 240 >>> 0 ).toString( 16 ) // "f0" ( 255 >>> 0 ).toString( 16 ) // "ff" ~ ( '0xF0' >>> 0 ) // -241 ( - 241 >>> 0 ).toString( 16 ) // "ffffff0f" FFFFFF0F // -241 000000 FF // 255 -------- 0000000 F // 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

JSBin example / JSPerf test

Mask a flag additively:

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

Mask a flag subtractively:

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

JSBin example / jsPerf test

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

JSBin example / JSPerf test

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

JSBin example / JSPerf test

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 = []; for (bitMask = 128 , index = 0 ; bitMask > 0 ; bitMask >>= 1 , index ++ ) { 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

Decimal to Hexadecimal:

function decimalToHex(decimal) { return (decimal).toString( 16 ); } decimalToHex( 255 ); // "FF"

JSBin example

Hexadecimal to Decimal:

function hexToDecimal(hex) { return parseInt (hex, 16 ); } hexToDecimal( 'FF' ); // 255

JSBin example

Binary to Hexadecimal:

function binaryToHex(binaryString) { return parseInt (binaryString, 2 ).toString( 16 ); } binaryToHex( '11111111' ); // "ff"

JSBin example

Hexadecimal to Binary:

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.