巧用位运算

1.字节翻转
a=0x12345678 -> 0x78563412
 
a=(a>>>24)|((a>>8)&0xFF00)|((a<<8)&0xFF0000)|(a<<24)
 
解释:
a>>>24
将最高为字节移到最低位处,得到0x00000012
a>>8&0xFF00
将左边第二位字节移动到右边第二位,a>>8得0x00123456,再&0xFF00,保留了右边第二位字节,得0x00003400
a<<8&0xFF0000
将右边第二位字节移动到左边第二位
a<<24
将最低位字节移动到最高位
 
 
2.位翻转
a= 00010010 00110100 01010110 01111000 -> 00011110 01101010 00101100 01001000
 
a=(a&0xAAAAAAAA)>>>1|(a&0x55555555)<<1;
a=(a&0xCCCCCCCC)>>>2|(a&0x33333333)<<2;
a=(a&0xF0F0F0F0)>>>4|(a&0x0F0F0F0F)<<4;
a=(a&0xFF00FF00)>>>8|(a&0x00FF00FF)<<8;
a=(a&0xFFFF0000)>>>16|(a&0x0000FFFF)<<16;
 
解释:
 
先交换相邻的一位,再交换相邻的两位,接着交换相邻的4位,交换相邻的8位,交换相邻的16位。
适用二进制和十进制
 
a=(a&0xAAAAAAAA)>>>1|(a&0x55555555)<<1;
A=1010,5=0101
分别代表偶数位和奇数位,将偶数位左移,奇数位右移是的相邻一位交换
以下同理
 
 
3.得到不小于a的且为2的整数次幂的最小数
a|=a>>1;
a|=a>>2;
a|=a>>4;
a|=a>>8;
a|=a>>16;
a++;

  

 
解释:
假设a=00101101;
那么我们最后得到希望得到01000000,就是00111111+1
所以我们要做的就是去掉里面的0
 
a|=a>>1;
将a左移一位且或啊,可以消除一个与1相邻的0 
a|=a>>2;
在>>1的基础上,与0相邻的必然是两个以上连续的1,可以消除两个0
a|=a>>4;
在以上的基础上,与0相邻的必然是四个以上连续的1,可以消除4个0
以下同理
 
运算符优先级口诀:
单目乘除为关系,逻辑三目后赋值。
 
 
 
posted @ 2018-05-09 12:33  变得很厉害的阿长  阅读(71)  评论(0)    收藏  举报