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. 先对正数求补码
  2. 然后对补码取反,包括符号位
  3. 最后进行一个补码求原码的过程

快速计算小技巧:

  1. 所有正整数的按位取反是其本身+1的负数

  2. 所有负整数的按位取反是其本身+1的绝对值

  3. 零的按位取反是 -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。

相关推荐