1、位运算的常用基础知识(资料) 掌握位运算对了解计算机本身具有很大的帮助,下面介绍在位运算方面应该知道的一些常用方法。 (红色语句为口诀,本人自己总结,阅览者看清楚“前”在例子中有标注,两个数操作其实就是前一个数的对应位置的意思) AND运算: (按位与 : & ) 遇1为前,遇0为0 AND一般都是用来做清“零”操作, 如果我想获得它的前4位: 0101 1111 (前) AND 1111 0000 =0101 0000 同理,后四位: 0101 1001 (前)
2、 AND 0000 1111 =0000 1001 还有时会用AND运算来判断一个数是奇数还是偶数,很简单只要跟1比较就可以了。 for(int i = 0;i < 100; i++){ if((i & 1) == 0) System.out.println("偶数:" + i); } 例子: 5&3=1 遇1为自己 遇0为0 ; 0000 0000 0000 0000 0000 0000 0000 0101 0000 000
3、0 0000 0000 0000 0000 0000 0011 0000 0000 0000 0000 0000 0000 0000 0001 -5&3=3 遇1为自己 遇0为0 ; 1111 1111 1111 1111 1111 1111 1111 1011 0000 0000 0000 0000 0000 0000 0000 0011 0000 0000 0000 0000 0000 0000 0000 0011 OR运算:(按位或: | ) 遇0为前, 遇1为1; 任何数跟“0”运算或者跟自己运算都是自己。 其主
4、要用来将位的值置为“1”,例如将后四位置为1。 1000 1001 (前) OR 0000 1111 =1000 1111 同理将前四位置为“1” 0001 1001 (前) OR 1111 0000 =1111 1001 5|3=7 遇0为自己, 遇1为1; 0000 0000 0000 0000 0000 0000 0000 0101 0000 0000 0000 0000 0000 0000 0000 0011 0000 0000 0
5、000 0000 0000 0000 0000 0111 -5|3=-5 遇0为自己, 遇1为1; 1111 1111 1111 1111 1111 1111 1111 1011 0000 0000 0000 0000 0000 0000 0000 0011 1111 1111 1111 1111 1111 1111 1111 1011 XOR运算:(按位异或 : ^) 相同为0 不同为1 5^3=6 相同为0 不同为1 0000 0000 0000 0000 0000 0000 0000 0101 0000 0000 0000 0000 0
6、000 0000 0000 0011 0000 0000 0000 0000 0000 0000 0000 0110 -5^3=-8 相同为0 不同为1 1111 1111 1111 1111 1111 1111 1111 1011 0000 0000 0000 0000 0000 0000 0000 0011 1111 1111 1111 1111 1111 1111 1111 1000 某公司出的面试题,说交换A,B两个值不使用第三者变量。其实XOR用起来很简单: A = A ^ B B = B ^ A A = A
7、 ^ B 任何两个相等的值XOR运算后都等于零,上面的等式拆开来就是: A = A^B B = B ^ (A ^ B) B被清掉 A = (A ^ B)^ (B ^ A ^ B) 剩下个B 如果等号两边同时具有相同的数,就不用去拆开了: B = B ^ (A ^ B) A = A ^ (B ^ A) A 0101 1001 B 0001 1100 (1) A 0100 0101 (A = A ^ B) B 0001 1100 (2) A 0100 0101 B
8、 0101 1001 (B = B ^ A) (3) A 0001 1100 (A = A ^ B) NOT运算:(按位取反: ~) 0变1,1变0 ~5=-6 0变1,1变0 0000 0000 0000 0000 0000 0000 0000 0101 1111 1111 1111 1111 1111 1111 1111 1010 ~-5=4 0变1,1变0 1111 1111 1111 1111 1111 1111 1111 1011 0000 0000 0000 0000 0000 0000 0000 0100
9、 移位运算符 包括: “>> 右移”;“<< 左移”;“>>> 无符号右移” <<运算: 就是乘2的N次方运算: 3 << 2 = 3 * 2^2 = 12 -3 << 2 = -3 * 2^2 = -12 >>运算: 除2的N次方运算: 16 >> 2 = 16 / 2^2 = 4 -16 >> 2 = -16 / 2^2 = -4 如果不同长度的两个数据进行运算,系统自动将两者的长度对其,高端为补"零",有符号的数符号位始终为"1"。 例子
10、 -5>>3=-1 1111 1111 1111 1111 1111 1111 1111 1011 1111 1111 1111 1111 1111 1111 1111 1111 其结果与 Math.floor((double)-5/(2*2*2)) 完全相同。 -5<<3=-40 1111 1111 1111 1111 1111 1111 1111 1011 1111 1111 1111 1111 1111 1111 1101 1000 其结果与 -5*2*2*2 完全相同。 5>>3=0 0000 0000 0000 0000 0000 0000 0000 0
11、101 0000 0000 0000 0000 0000 0000 0000 0000 其结果与 5/(2*2*2) 完全相同。 5<<3=40 0000 0000 0000 0000 0000 0000 0000 0101 0000 0000 0000 0000 0000 0000 0010 1000 其结果与 5*2*2*2 完全相同。 -5>>>3=536870911 1111 1111 1111 1111 1111 1111 1111 1011 0001 1111 1111 1111 1111 1111 1111 1111 无论正数、负数,它们的右
12、移、左移、无符号右移 32 位都是其本身,比如 -5<<32=-5、-5>>32=-5、-5>>>32=-5。 一个有趣的现象是,把 1 左移 31 位再右移 31 位,其结果为 -1。 0000 0000 0000 0000 0000 0000 0000 0001 1000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1111 1111 1111 1111 对于10进制的数字,左移一位就是在末尾加上一个0,数值变大10倍。 同理,对于二进制数字,左移一位是在末尾加上一个0,数值变大2被。 所以 x <<
13、3,x就变大 2^3 倍,就是 8*x 右移同理 byte a = 7; // 0000 0111 byte b = ~a;//1111 1000(补)-1 b: (反) 1111 0111 b: (原) 1000 1000 -8 byte d = 19;// 0001 0011 byte e = ~d; //1110 1100(补)-1 e: (反) 1110 1011 e: (原) 1001 0100 -20 byte f = -19; //1001 0011>1110 1100 >1110 1101 ~>0001 0010 > 18






