0x55555555 01010101010101010101010101010101
0x33333333 00110011001100110011001100110011
0x0f0f0f0f 00001111000011110000111100001111
这0和1还不一边长 (lll¬ω¬)
前n位和后n位进行或操作可前后换位,这要建立在其他位都是0的情况下才有效,这样才能确实保证是和0操作,否则其它位移动后和0或,又多一位。(非常经典的高低位交换) a = (a >> 8) | (a << 8);Java 没有无符号数哦
位操作进行二进制逆序将无符号数的二进制表示进行逆序,求取逆序后的结果。
如数34520的二进制表示: 10000110 11011000 逆序后则为: 00011011 01100001它的十进制为7009在字符串逆序过程中,可以从字符串的首尾开始,依次交换两端的数据。在二进制中使用位的高低位交换会更方便进行处理,这里我们分组进行多步处理。
归并: (右移n位|左移n位) 下面这个方法,找数字是非常繁琐的,底下有更好的。
第一步:以每 2 位为一组,组内进行高低位交换
交换前: 10 00 01 10 11 01 10 00 交换后: 01 00 10 01 11 10 01 00第二步:在上面的基础上,以每 4 位为 1 组,组内高低位进行交换
交换前: 0100 1001 1110 0100 交换后: 0001 0110 1011 0001第三步:以每 8 位为一组,组内高低位进行交换
交换前: 00010110 10110001 交换后: 01100001 00011011第四步:以每16位为一组,组内高低位进行交换
交换前: 0110000100011011 交换后: 0001101101100001对于上面的第一步,依次以 2 位作为一组,再进行组内高低位交换,这样处理起来比较繁琐,下面介绍另外一种方法进行处理。
先分别取原数 10000110 11011000 的奇数位和偶数位,将空余位用 0 填充:原数: 10000110 11011000 奇数位: 10000010 10001000 偶数位: 00000100 01010000 再将奇数位右移一位,偶数位左移一位,此时将两个数据相或即可以达到奇偶位上数据交换的效果:
原数: 10000110 11011000 奇数位右移一位: 0 10000010 1000100 偶数位左移一位:0000100 01010000 0 两数相或得到: 01001001 11100100上面的方法用位操作可以表示为: 取a的奇数位并用 0 进行填充可以表示为: a & 0xAAAA 取a的偶数为并用 0 进行填充可以表示为: a & 0x5555
因此,上面的第一步可以表示为: 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) 因此整个操作为:unsigned short a = 34520;
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); x^x=0; x^0=x; 数组中,只有一个数出现一次,剩下都出现两次,找出出现一次的数if(n & 1 == 1) 判断奇数偶数a ^ b 无进位加法a & b 进位标志