Binary is cool. For me, learning binary was the "WOW" moment that got me hooked on programming. That moment I could see how HDDs worked, and how the whole machines were just running like clockwork. Anyhoo, so we have these bits, and we can do things with them, efficiently.
Lets imagine today was brought to you with the numbers 5 and 9.
//columns -> 8 4 2 1 var a = 5; // 0 1 0 1 var b = 9; // 1 0 0 1
Logical And operations look through each column and return true if both bits are true, and false if they're not:
(a & b); // = 1
Logical Or operations look through each column and return true if one or both columns are true:
(a | b); // = 13
XOR, exclusive or, or the "one and only". These operations look through each column and return true if one and only one of the columns are true.
(a ^ b); // = 12
Logical Not looks through columns and flips them. What the tilde actually does is this: -(x + 1). So the right hand operand has 1 added to it, and then is turned into a negative. ~5 becomes -6. ~-6 becomes 5.
We can use a double tide (NOT NOT) binary operator instead of using
var a = 5.34556 ~~a; //5 Math.floor(a); //5
It can also be used for indexOf. So instead of doing
myVar.indexOf("a") !== -1 you can do
~myVar.indexOf("a"). so if "a" is in myVar, say at index 0, and negated, so it gets +1, then negated, so -1 - which is true. If it is not in the index, its result is -1, which has 1 added to it, then negated, which takes it to 0 - which is false.
The left shift operator literally shifts the bits to the left by the value specified.
//double a << 1; //10
//quadruple a << 2; //10
The right shift operator, like the left shift, shifts the bits. In this case it shifts them to the right hand side.
20 >> 2 //5