文章目录
位运算针对二进制0,1
1.位运算
-
&:按位与(11得1,10、01、00得0)
-
|:按位或(00得0, 10、01、11得1)
-
^:异或(相同得0,不同得1)
2.有符号整数、无符号整数
有符号整数,最高位是符号位,0为正数符号,1为负数符号
-
0000 1010
:表示一个正数,左边最高位0表示它是一个正数 -
1000 1010
:表示一个负数,坐标最高位1表示它是一个负数
Java中btye(8位),short(16位),int(32位),long(64位)都是有符号整数,整数一般使用补码表示。
3.原码,反码,补码
3.1 原码
假如给定一个整数10,在java中一般用32位二进制来表示:00000000 00000000 00000000 00001010
因为10是一个正数,最高位0就表示的是一个正数,所以它的二进制就是它的原码,-10的原码把最高位变成1即可。
10的原码:00000000 00000000 00000000 00001010
-10的原码:10000000 00000000 00000000 00001010
3.2 反码
正整数补码 = 原码
10的反码:00000000 00000000 00000000 00001010
负整数反码就是在原码的基础上符号位不变,其他位取反
-10的反码:11111111 11111111 11111111 11110101
3.3 补码
正整数补码 = 原码
10的补码:00000000 00000000 00000000 00001010
负整数补码 = 反码+ 1
-10的补码:11111111 11111111 11111111 11110110
技巧一:知道了10的补码,如果求-10的补码记住可以这样计算:将10连同符号位取反再加1即可。
技巧二:知道一个负整数的补码,要求原码先减1再取反
和 先取反再加1
效果是一样的
技巧三:知道一个负整数的补码,那么求给定的这个补码的补码
就是要求的原码。
4.为什么使用补码
4.1 统一数字0的表示
比如对于数字0:
+0的补码: 0000 0000 0000 0000 0000 0000 0000 0000
-0的补码:-0的反码加1
1111 1111 1111 1111 1111 1111 1111 1111 + 1
= 0000 0000 0000 0000 0000 0000 0000 0000
可以发现不管是+0
还是-0
都是 0000 0000 0000 0000 0000 0000 0000 0000
4.2 简化整数的加减法计算
假设我们要计算6+5,先使用原码计算:
计算结果是正确的的,但是如果是-6+5呢?
会发现结果是不正确的,此时如果使用补码的话,如下:
最后计算的结果:1111 1111 1111 1111 1111 1111 1111 1111
是补码,转换成原码对应的整数就是-1
5. 有符号整数二进制规律
假如这里先用4个二进制位表示0到7的数字:
0000 0 0001 1
0010 2 0011 3
0100 4 0101 5
0110 6 0111 7
那么1000
按道理应该表示的是一个负数,那么究竟是负多少呢?这里的1000
是以补码的形式存在的,先计算出它的原码(按照负整数补码 = 反码+1先计算出反码,再按照反码就是在原码的基础上符号位不变,其他位取反)得出原码是1000
,所以是-8,
再来看看0到7的范围:
0000 0 1111 -1
1110 -2 1101 -3
1100 -4 1011 -5
1010 -6 1001 -7
6. 位运算
6.1 按位取反:~
正数:~9 = ? 9的原码是: 0000 1001
计算步骤:
1.先对正数求补码:0000 1001
2.然后对补码取反,包括符号位:1111 0110
3.最后进行一个补码求原码的的过程:先减1得反码1111 0101
,取反得原码(反码和原码是一个相对的概念,对反码取反就是原码。取反过程符号位是不变的哦)1111 1010
,前面四个对应的符号位,最后转十进制位是-10
负数: ~10 = ? -10的原码是1111 1010
计算步骤:
1.先求-10的反码:1111 0101
(符号位不变按位取反)
2.然后求补码:1111 0110
(符号位不变,末位+1)
3.补码取反:0000 1001
(符号位一起取反)
转换成十进制就是9
6.2 左移(<<)
举例:
正数左移:1往左边移动
4: 0000 0000 0000 0000 0000 0000 0000 0100
4<<2:0000 0000 0000 0000 0000 0000 0001 0000
负数左移:-4的32位表示要清楚前面的28位1都是符号位,将最后四位中的1向后做移动即可
-4: 1111 1111 1111 1111 1111 1111 1111 1100
-4<<2: 1111 1111 1111 1111 1111 1111 1111 0000
1111 1111 1111 1111 1111 1111 1111 0000
表示的是多少呢?这里存储的是补码形式,所以
先减1得:
1111 1111 1111 1111 1111 1111 1110 1111
再取反:1000 0000 0000 0000 0000 0000 0001 0000
,转成十进制就是-16
左移与符号没有关系
6.3 右移(>>)
正数右移:有符合和无符号是一样的
15: 0000 0000 0000 0000 0000 0000 0000 1111
有符号右移15>>2:0000 0000 0000 0000 0000 0000 0000 0011
无符号右移15>>>2:0000 0000 0000 0000 0000 0000 0000 0011
负数右移:负数有符号右移高位补1,而无符号右移高位补0
-15:1111 1111 1111 1111 1111 1111 1111 0001
有符号-15>>2所有1向右移两位,高位补1,移完之后是这样:11 1111 1111 1111 1111 1111 1111 1100
,高位有1补:1111 1111 1111 1111 1111 1111 1111 1100
要知道这个值等于多少先减一再取反:1000 0000 0000 0000 0000 0000 0000 0100
; 有符号-15>>2所有1向右移两位,高位补1,移完之后是这样:11 1111 1111 1111 1111 1111 1111 1100
,高位有1补:1111 1111 1111 1111 1111 1111 1111 1100
要知道这个值等于多少先减一再取反:1000 0000 0000 0000 0000 0000 0000 0100
emsp; 无符号右移:0011 1111 1111 1111 1111 1111 1111 1100
,因为无符号这就是一个二进制原码,转成十进制: 2^2 + 2^3 + 2^4 + .... + 2^30 = 1073741820