Where would I use a bitwise operator in JavaScript?
Example:
Parses hexadecimal value to get RGB color values.
var hex = 'ffaadd';var rgb = parseInt(hex, 16); // rgb is 16755421var red = (rgb >> 16) & 0xFF; // returns 255var green = (rgb >> 8) & 0xFF; // 170var blue = rgb & 0xFF; // 221
I heavily use bitwise operators for numerical convertions in production scripts, because sometimes they're much faster than their Math
or parseInt
equivalents.
The price I have to pay is code readability. So I usualy use Math
in development and bitwise in production.
You can find some performance tricks on jsperf.com.
As you can see, browsers don't optimize Math.ceil
and parseInt
for years, so I predict bitwise will be faster and shorter way to do things in furure as well.
Bonus: cheat sheet for | 0
: an easy and fast way to convert anything to integer:
( 3|0 ) === 3; // it does not change integers( 3.3|0 ) === 3; // it casts off the fractional part in fractionalal numbers( 3.8|0 ) === 3; // it does not round, but exactly casts off the fractional part( -3.3|0 ) === -3; // including negative fractional numbers( -3.8|0 ) === -3; // which have Math.floor(-3.3) == Math.floor(-3.8) == -4( "3"|0 ) === 3; // strings with numbers are typecast to integers( "3.8"|0 ) === 3; // during this the fractional part is cast off too( "-3.8"|0 ) === -3; // including negative fractional numbers( NaN|0 ) === 0; // NaN is typecast to 0( Infinity|0 ) === 0; // the typecast to 0 occurs with the Infinity( -Infinity|0 ) === 0; // and with -Infinity( null|0 ) === 0; // and with null,( (void 0)|0 ) === 0; // and with undefined( []|0 ) === 0; // and with an empty array( [3]|0 ) === 3; // but an array with one number is typecast to number( [-3.8]|0 ) === -3; // including the cast off of the fractional part( [" -3.8 "]|0 ) === -3; // including the typecast of strings to numbers( [-3.8, 22]|0 ) === 0 // but an Array with several numbers is typecast to 0( {}|0 ) === 0; // an empty object is typecast to 0( {'2':'3'}|0 ) === 0; // or a not empty object( (function(){})|0 ) === 0; // an empty function is typecast to 0 too( (function(){ return 3;})|0 ) === 0;
and some magic for me:
3 | '0px' === 3;
In JavaScript, you can use a double bitwise negation (~~n
) as a replacement for Math.floor(n)
(if n
is a positive number) or parseInt(n, 10)
(even if n
is negative). n|n
and n&n
always yield the same results as ~~n
.
var n = Math.PI;n; // 3.141592653589793Math.floor(n); // 3parseInt(n, 10); // 3~~n; // 3n|n; // 3n&n; // 3// ~~n works as a replacement for parseInt() with negative numbers…~~(-n); // -3(-n)|(-n); // -3(-n)&(-n); // -3parseInt(-n, 10); // -3// …although it doesn’t replace Math.floor() for negative numbersMath.floor(-n); // -4
A single bitwise negation (~
) calculates -(parseInt(n, 10) + 1)
, so two bitwise negations will return -(-(parseInt(n, 10) + 1) + 1)
.
It should be noted that of these three alternatives, n|n
appears to be the fastest.
Update: More accurate benchmarks here: http://jsperf.com/rounding-numbers-down
(As posted on Strangest language feature)