C语言位运算符详解
基本概念
原码:正数是其二进制本身;负数是符号位为1,数值部分取X绝对值的二进制
- 例如:3的原码为
0000 0011
;-3的原码为1000 0011
。
反码:正数的反码是其本身,对于负数其符号位不变其它各位取反(0变1,1变0)。
- 例如:3的反码为
0000 0011
;-3的反码为1111 1100
。
补码:正数的补码是其本身,负数的补码是其反码的基础上+1。
- 例如:3的补码为
0000 0011
;-3的补码为1111 1101
。
正数的补码、反码都是其本身
要弄懂位运算符的计算方法,首先必须明白二进制数在内存中的存放形式,二进制数在内存中是以补码的形式存放的。
按位与&
参与运算的两个值,转换成2进制,如果两个相应位均为1时,结果位才为1,否则为0.
例如:8&3,转换成2进制:00001000(8的二进制) & 00000011(3的二进制) 00000000(结果为0)
7 & 3,转换成2进制:00000111(7的二进制) & 00000011(3的二进制) 00000011(结果为3)
-7 & 3,转换成2进制:1000 0111(-7的二进制) & 0000 0011(3的二进制),转换成补码形式1111 1001(-7的补码) & 0000 0011(3的补码), 结果为0000 0001(结果为1)
-7 & -3,转换成2进制:1000 0111(-7的二进制) & 1000 0011(-3的二进制),转换成补码形式1111 1001(-7的补码) & 1111 1101(-3的补码), 结果为1111 1001 这是补码还要转换成原码,转换后为 1000 0111(结果为-7)
按位或 |
参与运算的两个值,转换成二进制,如果两个数的相应位有1,结果位就为1。
例如:8&3,转换成2进制:00001000(8的二进制) | 00000011(3的二进制) 00001011(结果为11)
7 & 3,转换成2进制:00000111(7的二进制) | 00000011(3的二进制) 00000111(结果为7)
-7 & 3,转换成2进制:1000 0111(-7的二进制) | 0000 0011(3的二进制),转换成补码形式1111 1001(-7的补码) | 0000 0011(3的补码), 结果为1111 1011这是补码,转换成原码为1000 0101(结果为-5)
-7 & -3,转换成2进制:1000 0111(-7的二进制) | 1000 0011(-3的二进制),转换成补码形式1111 1001(-7的补码) | 1111 1101(-3的补码), 结果为1111 1101这是补码,转换成原码为1000 0011(结果为-3)
按位异或 ^
参与运算的两个值,转换成二进制,如果两个数的相应为相同,为0,否则为1.
例如:8&3,转换成2进制:00001000(8的二进制) ^ 00000011(3的二进制) 00001011(结果为11)
7 & 3,转换成2进制:00000111(7的二进制) ^ 00000011(3的二进制) 00000100(结果为4)
-7 & 3,转换成2进制:1000 0111(-7的二进制) ^ 0000 0011(3的二进制),转换成补码形式1111 1001(-7的补码) ^ 0000 0011(3的补码), 结果为1111 1010这是补码,转换成原码为1000 0110(结果为-6)
-7 & -3,转换成2进制:1000 0111(-7的二进制) ^ 1000 0011(-3的二进制),转换成补码形式1111 1001(-7的补码) ^ 1111 1101(-3的补码), 计算结果为0000 0100,十进制为 4
按位取反运算符 ~
取反运算符~为单目运算符,具有右结合性。 其功能是对参与运算的数的各二进位按位求反。
例如:~7,转换成2进制:0000 0111(7的二进制)[原]
,求补码0000 0111 [补]
,对补码取反,包括符号位1111 1000
,最后补码转原码1111 0111 [反码],1000 1000 [原码]
计算步骤:
- 先对正数求补码
- 然后对补码取反,包括符号位
- 最后进行一个补码求原码的过程
快速计算小技巧:
-
所有正整数的按位取反是其本身+1的负数
-
所有负整数的按位取反是其本身+1的绝对值
-
零的按位取反是 -1(0在数学界既不是正数也不是负数)
左移(<<)、右移(>>)运算符
左移运算符和右移运算符都是双目运算符。
左移运算:其功能是将运算符‘<<’左边的操作数的各二进制位全部左移指定的位数。左移时,操作数移出左边界的位被屏蔽,从右边开始用0填补空位,其表达式的一般形式为:(操作数) << (移位位数)
例如:13 << 3, 将操作数转换成二进制0000 1101
,左移3位0110 1000
,十进制就是104。
15<<2, 将操作数转换成二进制0000 1111
,左移2位0011 1100
,十进制就是60。
计算技巧: (操作数) x 2移位位数 ,例如:13 x 23 = 104, 15 x 22 =60。
右移运算:其功能是将运算符‘>>’ 左边的操作数的各二进制位全部右移指定的位数。
右移时,操作数移出右边的位被屏蔽,从左边开始用符号位填补空位。如果原先最高位是1,则填补1;如果是0,则填补0,其表达式的一般形式为:(操作数) >> (移位位数)
。
例如:16 >> 3, 将操作数转换成二进制0001 0000
,右移3位0000 0010
,十进制就是2。
15>>2, 将操作数转换成二进制0000 1111
,右移2位0000 0011
,十进制就是3。
-15>>2, 将操作数转换成二进制1000 1111
,转换成补码 1111 0001
,右移2位1111 1100
,转换成原码1000 0100
十进制就是-4。