Last active
January 1, 2016 22:59
-
-
Save liamgriffiths/8213572 to your computer and use it in GitHub Desktop.
bit shifting hacks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var bitwiseOR = function() { | |
// for each bit, if there is a "1" in the place, then the bit becomes "1" | |
var a = parseInt('00001111', 2); | |
var b = parseInt('11110000', 2); | |
var c = a | b; | |
c.toString(2); // '11111111' | |
// when the binary number is not the same length, 0's are added to the front | |
var d = parseInt('11110000', 2); | |
var e = parseInt('1100', 2); // becomes '00001100' | |
var f = d | e; | |
f.toString(2); // '11111100' | |
}; | |
var bitwiseAND = function() { | |
// for each bit, if there is a "1" in both place, then the bit becomes "1" | |
var a = parseInt('00001111', 2); | |
var b = parseInt('11110000', 2); | |
var c = a & b; | |
c.toString(2); // '0', or '00000000' | |
var d = parseInt('11110000', 2); | |
var e = parseInt('11000000', 2); | |
var f = d & e; | |
f.toString(2); // '11000000' | |
}; | |
var bitwiseXOR = function() { | |
// for each bit, if there is a '1' in one place but not both, then '1' | |
var a = parseInt('00001111', 2); | |
var b = parseInt('11110001', 2); | |
var c = a ^ b; | |
c.toString(2); // '11111110' | |
}; | |
var bitwiseNOT = function() { | |
// inverts each bit, including the "sign bit" | |
var a = parseInt('10101010', 2); | |
var b = ~a; | |
b.toString(2); // '-10101011' | |
}; | |
var rightShift = function() { | |
// shifts the bits to the right, forget the bits pushed too far to the right | |
var a = parseInt('11110000', 2); | |
var b = 4; | |
var c = a >> b; | |
c.toString(2); // '1111' | |
var d = parseInt('11110101', 2); | |
var e = 4; | |
f = d >> e; | |
f.toString(2); // '1111' | |
}; | |
var leftShift = function() { | |
var a = parseInt('1111', 2); | |
var b = 4; | |
var c = a << b; | |
c.toString(2); // '11110000' | |
var d = parseInt('11110000', 2); | |
var e = 4; | |
var f = d << e; | |
f.toString(2); // '111100000000' | |
}; | |
var zeroFilledRightShift = function() { | |
// shifts the bits to the right, forget the bits pushed too far to the right | |
var a = parseInt('1111', 2); | |
var b = 2; | |
var c = a >>> b; | |
c.toString(2); // '0011', '11' | |
}; | |
var flooring = function() { | |
// you can use bitwise operations as an alternative to Math.floor(); | |
// but you probably shouldn't, small gains for low readability | |
// http://jsperf.com/jsfvsbitnot/2 | |
// http://jsperf.com/jsfvsbitnot/12 | |
var a = 3.141592653589793; | |
a.toString(2); // '11.001001000011111101101010100010001000010110100011' | |
var b = a | 0; // '3' | |
b.toString(2); // '11' | |
var c = 3.141592653589793; | |
c.toString(2); // '11.001001000011111101101010100010001000010110100011' | |
var d = c >> 0; // '3' | |
d.toString(2); // '11' | |
var e = 3.141592653589793; | |
e.toString(2); // '11.001001000011111101101010100010001000010110100011' | |
var f = ~~e; // '3' | |
f.toString(2); // '11' | |
}; | |
var minmax = function() { | |
// this is a bit faster than the builtin min/max, but not readable at all | |
// http://jsperf.com/math-min-max-vs-ternary-vs-if/9 | |
var a = 10; | |
var b = 20; | |
// max function | |
var c = a ^ ((a ^ b) & -(a < b)); // 20 | |
// c = a ^ ((a ^ b) & -(true)); | |
// c = a ^ ((a ^ b) & -1)); | |
// c = a ^ (('01010' ^ '10100') & -1)); | |
// c = a ^ ('11110' & '-1')); | |
// c = a ^ ('11110'); | |
// c = '01010' ^ '11110'; | |
// c = '11110' | |
// min function | |
var d = b ^ ((a ^ b) & -(a < b)); // 10 | |
}; | |
var swappingXORs = function() { | |
// way cool, but not efficient for JS | |
// https://en.wikipedia.org/wiki/XOR_swap_algorithm | |
// http://jsperf.com/xor-swap | |
var a = 10; | |
var b = 300; | |
a ^= b, b ^= a, a ^= b; | |
// a => 000001010 == 10 | |
// b => 10010110 == 300 | |
// 000001010 ^= 100101100 => 100100110 == 294 | |
// 100101100 ^= 100100110 => 000001010 == 10 | |
// 100100110 ^= 000001010 => 100101100 == 294 ^ 10 == 300 | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment