Juggling bits in JavaScript
Bitwise operators
| | OR |
& | AND |
^ | XOR |
~ | NOT |
>> | RIGHT SHIT |
<< | LEFT SHIFT |
>>> | 0-FILL RIGTH SHIFT |
[ | ] OR
logical inclusive OR operation on each pair of corresponding bits.
The result in each position is 0 if both bits are 0, while otherwise the result is 1
0101 (decimal 5)
OR 0011 (decimal 3)
= 0111 (decimal 7)
Most common usage in JavaScript
// Rounding (floor'ing)
var myFloat = 3.14;
var rounded = myFloat | 0;
[ & ] AND
Performs the logical AND operation on each pair of the corresponding bits, by multiplying them.
Thus, if both bits in the compared position are 1, the bit in the resulting binary representation is 1
0101 (decimal 5)
AND 0011 (decimal 3)
= 0001 (decimal 1)
Usage
- bitmasks
- (semi)complex algorithms
[ ^ ] XOR
Performs the logical exclusive OR operation on each pair of corresponding bits. The result in each position is 1 if only the first bit is 1 or only the second bit is 1, but will be 0 if both are 0 or both are 1.
0101 (decimal 5)
XOR 0011 (decimal 3)
= 0110 (decimal 6)
Usage
// swapping variables
var a = 5;
var b = 6;
a^=b, b^=a, a^=b;
console.log('a', a); // 6
console.log('b', b); // 5
// XOR variable swap explained:
x1 = x0 xor y0
y2 = x1 xor y0
x2 = x1 xor y2
// Substituting:
x1 = x0 xor y0
y2 = (x0 xor y0) xor y0
x2 = (x0 xor y0) xor ((x0 xor y0) xor y0)
// Associativity and commutativity
y2 = x0 xor (y0 xor y0)
x2 = (x0 xor x0) xor (y0 xor y0) xor y0
// Since x xor x == 0 for any x,
y2 = x0 xor 0
x2 = 0 xor 0 xor y0
// And since x xor 0 == x for any x,
y2 = x0
x2 = y0
XOR swap explanation
let a = 1;
a ^= 1; // 0
a ^= 1; // 1
a ^= 1; // 0
Toggle switch
[ ~ ] NOT
Unary operation that performs logical negation on each bit, forming the ones' complement of the given binary value. Bits that are 0 become 1, and those that are 1 become 0.
NOT 0111 (decimal 7)
= 1000 (decimal −8)
Usage
// Rounding (faster Math.floor() )
~~3.14; // 3
// Converts a number to -(N+1)
'rinat'.indexOf('z') // -1
~'rinat'.indexOf('z') // 0 - falsy
[ >> ] RIGHT SHIFT
Shifts bits to the right, discarding bits shifted off.
10010111 (decimal −105) RIGHT-SHIFT
= 11001011 (decimal −53)
Common usage
// Division by the power of 2
8 >> 1; // 4
8 >> 2; // 2
[ << ] LEFT SHIFT
Shifts bits to the left, shifting in zeroes from the right.
00010111 (decimal +23) LEFT-SHIFT
= 00101110 (decimal +46)
Common usage
// Multiplication by the power of 2
8 << 1; // 16
8 << 2; // 32
// Decimal to integer
3.14 << 0 // 3
[ >>>] 0-FILL RIGHT SHIFT
Shifts bits to the right, discarding bits shifted off, and shifting in zeroes from the left.
1010100 LEFT-SHIFT
= 0001010
Common usage
// Division by the power of 2, not for negatives
8 >> 1; // 4
8 >> 2; // 2
Simple hash
String.prototype.simpleHash = function () {
return this.split('').map(function(char){
return char.charCodeAt();
}).join('');
}
HashCode()
In the Java programming language, every class implicitly or explicitly provides a hashCode() method, which digests the data stored in an instance of the class into a single hash value (a 32-bit signed integer).
where terms are summed using 32-bit int addition, s[i] denotes the ith character of the string, and n is the length of s.
From Java 1.2, java.lang.String class implements its hashCode() using a product sum algorithm over the entire text of the string.
HashCode() continued
String.prototype.hashCode = function () {
var hash = 0;
this.split('').map(function(char){
var code = char.charCodeAt();
hash = ((hash<<5)-hash)+code;
hash = hash & hash; // Convert to 32bit integer
});
return hash;
}
Book recomendation
Juggling with bits in JavaScript
By Rinat U
Juggling with bits in JavaScript
- 754