java中的位运算

因为工作需要,我重新学习了位运算符的相关内容,在碰到问题时,查询百度却发现没有找到我想要的内容。在查阅相关文档,弄清这部分内容后,将我的理解记录一下,希望对新的朋友有所帮助。不正确的地方欢迎指正。
首先点明一点,在进行位运算的时候,所有的运算都是使用补码来计算的!!
这里对补码的获取做一个简单的介绍,以方便下文的理解。
首先,计算机中有三种码:原码,反码,补码
原码:即“原有的二进制码”。即十进制数换算为二进制后得到的码。如十进制数字8,换算为二进制之后即为“0000 1000”,这个码即为数字8的原码。
反码:正数的反码为原码本身。
负数的反码为,将除符号位的其他各位均取反,得到的新的二进制数。
PS:符号位:二进制中,认为第一位为符号位,0代表正数,1代表负数。
补码:正数的补码为其本身。(即正数三码相同)。
负数的补码为其反码加一。
例如,对于正数8来讲,它的三码均为“0000 1000”;
对于负数-5(1000 0101)来讲,它的反码为:“1111 1010”,它的补码为:“1111 1011”。
若仍不懂得同学,可参考https://jingyan.baidu.com/article/1e5468f90a9568484861b77c.html

java中的位位运算符,一共有七种,我会在下文中逐一讲解。

位运算符的基本规则
1,位运算符都是针对整数的二进制数字形式而进行的。
2,按位与运算基本规则(规则表):
1 & 1 ==> 1
1 & 0 ==> 0
0 & 1 ==> 0
0 & 0 ==> 0;
3, 按位或运算基本规则
1 | 1 ==> 1;
1 | 0 ==> 1;
0 | 1 ==> 1
0 | 0 ==> 0
4,按位非运算:
~ 1 ==> 0
~ 0 ==> 1
5,按位异或运算:
1 ^ 1 ==> 0
0 ^ 0 ==> 0
1 ^ 0 ==> 1
0 ^ 1 ==> 1
规律:相同就是0,不同就是1
1. 按位非(~)
按位非,即将二进制码的每一位进行取反后得到的数。(牢记计算时均用补码)
例如,十进制数字60,其二进制码为:“0011 1100”,对其取反得到“1100 0011”,这即为60进行按位非计算后得到的数(补码)。换算成十进制,“1100 0011”符号位为1,表明为负数,负数取补码的逻辑为:先取反,再加一,符号位不动。(取补码和取原码的计算过程相同)。所以,“1100 0011”取反为 “1011 1100”,末位加一得“1011 1101”,换算成十进制为-61.
2. 按位与(&)
形式:A & B; //A和B都是数字,其实是常规的10进制数字,但内部会按二进制进行计算
含义:将A和B的二进制形式的每一个位上的二进制数字进行按位与(&)运算之后的结果。
说明:一个数字的二进制形式通常是32位的0和1的组合,也可能是64位,但为了说明问题,我们通常只用8位。
举例:
result = 9 & 13; //9的二进制是“1001”,13的二进制是“1101”
结果是“00001001”,即9
3. 按位或(|)
形式:A | B; //A和B都是数字,其实是常规的10进制数字,但内部会按二进制进行计算
含义:将A和B的二进制形式的每一个位上的二进制数字进行按位或(|)运算之后的结果。
举例:
result = 18 | 10; //18的二进制是“10010”,10的二进制是“1010”
结果是“00011010”,即26
4. 按位异或(^)
按位异或的结果即为,对操作的两个数的每一位进行异或运算后得到的数。
5. 左移(<<)
形式: A << n; //A是一个要被移动的数字,同样可以是普通数字,但按二进制去运算,n是一个指定要移动的位数
含义:将数字A的二进制形式的每一个位上的数字往左边移动指定的位数n,则最左边的n位移出去了就不管了,最右边空出来的n位,补0就可以。
举例:
int a=60;”0011 1100”,a<<2后得到“1111 0000”,即为240.
6. 右移(>>)
形式: A >> n; //A是一个要被移动的数字,同样可以是普通数字,但按二进制去运算,n是一个指定要移动的位数
含义:将数字A的二进制形式的每一个位上的数字往右边移动指定的位数n,最右边的n位移出去了直接去掉,最左边空出来的n位,按照原符号位的数字,进行补位。
举例:
java右移位时,因为涉及到左边补位的情况,所以要参照java中数据类型所占内存长度来理解(个人理解),若简写以8位数表示,容易混淆。
例如求-5>>2的值。
-5的二进制表示为“10000000 00000000 00000000 00000101”,其补码为:“11111111 11111111 11111111 00001011”,右移两位后,右边两位直接去掉,左边两位补符号位后得到“11111111 11111111 11111111 00001110”,即为-2.
7. 无符号右移(>>>)
无符号右移与右移的区别为,在进行右移位后,右移(>>)左边空出来的位用符号位来补齐,而无符号右移(>>>)则不管符号位,均以0来补齐。
举例:
求-5>>>2的值。
-5的二进制表示为“10000000 00000000 00000000 00000101”,其补码为:“11111111 11111111 11111111 00001011”,无符号右移两位后得到:“00111111 11111111 11111111 11000010”,其值为:1073741822。(所以java中建议将int的4个字节补满计算)。

**总结**:在进行位运算的时候,首先需要了解位运算的计算逻辑,如1|0=1等。第二点是比较容易忘记的,计算机中进行位运算时,使用的均是**补码**,在进行实际运算时,要时刻牢记补码的概念,牢记对数值进行补码运算,尤其是对负数进行运算的时候。

猜你喜欢

转载自blog.csdn.net/oucfsb/article/details/80167993