位运算符注意事项:
两个操作数均以补码参与计算,得到的结果为补码,需将结果转为原码才是最终答案
原码、补码、反码基础概念
计算机中的有符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同
1.原码
原码 是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位):符号位为“0”时表示正数,符号位为“1”时表示负数(0有两种表示:+0和-0),其余位表示数值的大小。
以8位机器数举例:
[+1] (原码) = 0000 0001
[-1] (原码) = 1000 0001
原码的整数“0”的表示形式有2种
[+0] (原码) = 0000 0000
[-0] (原码) = 1000 0000
2.反码
注意:符号位始终不变,根据符号位为0或1判断数据正负
对于正数:补码 = 反码 = 原码
对于负数:反码 = 原码 符号位不变,其余各位取反
[+1] = [0000 0001](原码)= [0000 0001](反码)
[-1] = [1000 0001](原码)= [1111 1110](反码)
3.补码
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理 。
补码的表示方法是:正数的补码就是其本身,负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1 (即在反码的基础上+1)。
[+1] = [0000 0001](原码) = [0000 0001](反码) = [0000 0001](补码)
[-1] = [1000 0001](原码) = [1111 1110](反码) = [1111 1111](补码)
& 按位与
- 规则: 1&1=1 、 1&0=0 、 0&1=0 、 0&0=0
举例:
9 & 5:
[0000 1001](补码)& [0000 0101](补码)= [0000 0001](补码)= 1
结果0000 0001符号位为0,正数,则原码为0000 0001 = 1
-9 & -5:
[1111 0111](补码)& [1111 1011](补码)= [1111 0011](补码)= -13
结果1111 0011符号位为1,负数,则原码 = 补码 -1 再整体取反
[1111 0011](补码) = [1111 0010](反码) = [1000 1101](原码)= -13
| 按位或
- 只要对应的二个二进位有一个为1时,结果位就为1。
- 规则: 1|1=1 、 1|0=1 、 0|1=1 、 0|0=0
举例:
9 | 5:
0000 1001 | 0000 0101 = [0000 1101] = 13
结果符号位为0,正数,则原码为0000 1101 = 13
-9 | -5:
1111 0111 | 1111 1011 = [1111 1111] = -1
结果符号位为1,负数,则原码 = 补码 -1 再整体取反
[1111 1111](补) = [1111 1110](反) = [1000 0001](原)= -1
^ 按位异或
-
对应的二个二进位 值不同时,结果位就为1。 对应的二个二进位 值相同时,结果位就为0
-
规则: 1 ^ 1=0 、 1 ^ 0=1 、 0 ^ 1=1 、 0 ^ 0=0,
举例:
9 ^ 5:
[0000 1001] ^ [0000 0101] = [0000 1100] = 12
结果符号位为0,正数,则原码为0000 1100 = 12
9 ^ -5:
[0000 1001] ^ [1111 1011] = [1111 0010] = -14
结果符号位为1,负数,则原码 = 补码 -1 再整体取反
[1111 0010](补) = [1111 0001](反) = [1000 1110](原)= -14
~ 按位与
- 单目运算符:对该整数的二进制形式逐位取反
举例:
~9:
~[0000 1001] = [1111 0110] = -10
结果符号位为1,负数,则原码 = 补码 -1 再整体取反
[1111 0110](补) = [1111 0101](反) = [1000 1010](原)= -10
~ -5:
~ [1111 1011] = [0000 0100] = 4
结果符号位为0,正数,则原码为0000 0100 = 4
<< 按位左移
- 将一个数的各二进制位全部左移若干位,移动的位数由右操作数指定,右操作数必须是非负值,其右边空出的位用0填补,高位左移溢出则舍弃该高位
举例:
9 << 2:
[0000 1001] << 2 = 00 [0010 0100] = 36
结果符号位为0,正数,则原码为0000 1100 = 12
-5 << 3:
[1111 1011] << = 111 [1101 1000] = -40
结果符号位为1,负数,则原码 = 补码 -1 再整体取反
[1101 1000](补) = [1101 0111](反) = [1010 1000](原)= -40
>> 按位右移
- 右移运算是将一个二进制位的操作数按指定移动的位数向右移动,移出位被丢弃,左边移出的空位对于无符号类型强制补0,对于有符号类型续补符号位,正数的符号位为0,负数的符号位为1
举例: 设 char a = 9 , b = -5 ;
a >> 2:高位补0
[0000 1001] >> 2 = [0000 0010] 01 = 2
结果符号位为0,正数,则原码为0000 0010 = 2
b >> 3:高位补1
[1111 1011] >> 3 = [1111 1111] 011 = -1
结果符号位为1,负数,则原码 = 补码 -1 再整体取反
[1111 1111](补) = [1111 1110](反) = [1000 0001](原)= -1
举例:设 unsigned char num = 14;
num >> 3 : 无符号类型强制补0
[0000 1110] >> 3 = [0000 0001] 110 = 1
结果符号位为0,正数,则原码为0000 0001 = 1