不断的学习,我们才能不断的前进
一个好的程序员是那种过单行线马路都要往两边看的人

位运算

与 & 操作

两个同时为1, 结果为1, 否则为0 .

1&1=1; 0&0=0; 1&0=0;  

n&(n-1) 的结果是把最低位1变成0;
n&1 可以判断n是奇数还是偶数.

或 | 操作

两个操作有一个为1, 结果为1.

0|0=0;  0|1=1;  1|0=1;   1|1=1;

异或 ^ 操作

两个操作 相同则为0, 不同则为1

0^0=0;  0^1=1;  1^0=1;   1^1=0

a^b^b=a; a^b^a=b;
a^0=a;

取反 ~ 操作

把0变成1, 把1 变成0
~a + 1: 整数取反加1,正好变成其对应的负数(补码表示);负数取反加一,则变为其原码,即正数

左移 <<

向左进行移位操作,高位丢弃,低位补 0

右移 >>

右移运算,向右进行移位操作,对无符号数,高位补 0对于有符号数,高位补符号位.

技巧

反转二进制

//把10000110 11011000 反转后的结果为: 00011011 01100001;
//思路: 先反转奇偶位置上的数, 然后奇数左移一位,偶数右移一位, 结果相或为:01001001 11100100 
// 反转 两个位置上的奇偶位,然后奇数左移2位,偶数右移2位,结果相或为: 00010110 10110001
// 反转 4个位置上的奇偶位,然后奇数左移4位,偶数右移4位,结果相或为: 01100001 00011011
// 再反转8个位置上的奇偶位,然后奇数左移8位,偶数右移8位,结果相或为 00011011 01100001
a=10000110 11011000
a = ((a & 0xAAAA) >>> 1) | ((a & 0x5555) << 1)
a = ((a & 0xCCCC) >>> 2) | ((a & 0x3333) << 2)
a = ((a & 0xF0F0) >>> 4) | ((a & 0x0F0F) << 4)
a = ((a & 0xFF00) >>> 8) | ((a & 0x00FF) << 8)
// 0xAAAA 表示每个偶数位为1, 0x5555表示每个奇数位为1
// 0xCCCC 表示把两个位子看成一个位子,然后每个偶数位为1, 0x3333表示每个奇数位为1

PS:右移要用>>> 表示无符号右移,高位补充0


目录