位运算优先级
( + - ) > ( << >> ) > ( ~ & ^ | )
右边第k位系列###
var x = 18; // 10010
// 取右边第k位
// x >> (k - 1) & 1
console.log(x >> (2 - 1) & 1); // 1
// 把右边第k位变为0
// x & ~(1 << (k - 1))
console.log(x & ~(1 << (2 - 1))); // 16
// 把右边第k位变为1
// x | (1 << (k - 1))
console.log(x | (1 << (1 - 1))); // 19
// 把右边第k位取反
// x ^ (1 << (k - 1))
console.log(x ^ (1 << (3 - 1))); // 22
末k位系列###
var x = 18; // 10010
// 求末k位
// x & (1 << k) - 1
console.log(x & (1 << 3) - 1); // 2
// 把末k位变0
// x & ~((1 << k) - 1)
console.log(x & ~((1 << 3) - 1)); // 16
// 把末k位变1
// x | (1 << k) - 1
console.log(x | (1 << 4) - 1); // 31
// // 把末k位取反
// x ^ (1 << k) - 1
console.log(x ^ (1 << 4) - 1); // 29
右边连续0或者1系列###
var x = 19; // 10011
// 把右边连续的1变为0
// x & (x + 1)
console.log(x & (x + 1)); // 16
// 取右边连续的1
// (x ^ (x + 1)) >> 1
console.log((x ^ (x + 1)) >> 1); // 3
var y = 16; // 10000
// 把右边连续的0变为1
// x | (x - 1)
console.log(y | (y - 1)); // 31
// 去除右边连续的0
var a = 40; // 101000
a = a >> (Math.log(a & (-a)) / Math.log(2));
console.log(a); // 5 (101)
右边第一个0或者1系列###
var x = 18; // 10010
// 把右边第一个1变为0
// x & (x - 1)
console.log(x & (x - 1)); // 16
// 取出右边第一个1
// x & (-x)
console.log(x & (-x)); // 2
// 把右边第一个0变为1
// x | (x + 1)
console.log(x | (x + 1)); // 19
简单应用###
// 乘2的幂 除2的幂
console.log(63 >> 1); // 31
console.log(1 << 4); // 16
// 判断奇偶
var a = 10;
console.log(a & 1); // 0偶 1奇
// 小数向下取整
var b = 1.25
, c = -1.25;
console.log(b | 0); // 1
console.log(~~b); // 1
console.log(b << 0); // 1
console.log(b >> 0); // 1
console.log(c | 0); // -1
console.log(~~c); // -1
console.log(c << 0); // -1
console.log(c >> 0); // -1
// 交换数字
var a = 10, b = 20;
a = a ^ b;
b = a ^ b;
a = a ^ b;
console.log(a, b); // 20 10
// 正负转换
var a = 10, b = -5;
console.log(~a + 1); // -10
console.log(~b + 1); // 5
console.log((a ^ -1) + 1); // -10
console.log((b ^ -1) + 1); // -5
// 模2的幂
var a = 153;
console.log(a % 16); // 9
console.log(a & (1 << 4) - 1); // 9
// 判断两数符号是否相同 (注意有0的情况)
var sign = a * b > 0;
var sign = (a ^ b) > 0;
// 取绝对值
// 写法1
i = x < 0 ? -x : x;
// 写法2
i = (x ^ (x >> 31)) - (x >> 31);
// 写法3
i= x ^ ( ~(x >> 31) + 1) + (x >> 31);
// 判断是不是2的幂
var isPowerOfTwo = function(n) {
return (!(n & (n - 1)) && n > 0);
};
常用的二进制数###
0xAAAAAAAA 10101010101010101010101010101010
0x55555555 01010101010101010101010101010101
0xCCCCCCCC 11001100110011001100110011001100
0x33333333 00110011001100110011001100110011
0xF0F0F0F0 11110000111100001111000011110000
0x0F0F0F0F 00001111000011110000111100001111
0xFF00FF00 11111111000000001111111100000000
0x00FF00FF 00000000111111110000000011111111
0xFFFF0000 11111111111111110000000000000000
0x0000FFFF 00000000000000001111111111111111
枚举集合子集###
枚举出一个集合的子集。设原集合为mask,则下面的代码就可以列出它的所有子集:
var mask = 5; // 1101
for (i = mask; i; i = (i - 1) & mask) {
console.log(i); // 5 4 1
}