位运算与移位运算

2020-09-21  本文已影响0人  泡泡茶壶大人

原码、反码、补码

对于有符号的数来说:

  1. 二进制的最高位是符号位:0表示正数,1表示负数;

示例:

1-1byte (8位) 类型再内存中分别表示为:

1 ==> [0000 0001] -1 ==> [1000 0001]

  1. 正数的原码、反码、补码都一样;
  2. 负数的反码 = 原符号位不变,其他位取反 (0->1 1->0)
  3. 负数的补码 = 反码 + 1
  4. 0的原码、反码、补码都是0
  5. 在计算机运算时,都是以补码的方式运算的

示例:

10: 8位原码、反码、补码: 0000 1010
6:  8位原码、反码、补码:0000 0110
-6:  8位原码:1000 0110  反码:1111 1001  补码:1111 1010
-10: 8位原码:1000 1010  反码:1111 0101  补码:1111 0110

位运算符

按位与 (&): 两位全为1,结果为1,否则为0

示例:

计算 10 & -6
10的补码:0000 1010
-6的补码:1111 1010
----------------------
结果补码: 0000 1010 ==> 正数,即为 10

计算 -10 & -6
-10的补码:1111 0110
-6的补码: 1111 1010
----------------------
结果补码: 1111 0010 ==> 反码:1111 0001 ==> 原码:1000 1110 即 -14

按位或 (|): 两位只要有一个为1,结果为1,均为不1,即为0

示例:

计算 10 | 6
10的补码:0000 1010
6的补码: 0000 0110
-----------------------
结果补码:0000 1110 ==> 正数,即为 14

计算 10 | -6
10的补码:0000 1010
-6的补码:1111 1010
-----------------------
结果补码:1111 1010 ==> 反码:1111 1001 ==> 原码:1000 0110 即 -6

按位异或 (^): 只有当两位不相同时,结果为1,否则为0

示例:

计算 10 ^ 6
10的补码:0000 1010
6的补码: 0000 0110
-----------------------
结果补码:0000 1100 ==> 正数,即为 12

计算 10 ^ -6
10的补码:0000 1010
-6的补码:1111 1010
-----------------------
结果补码:1111 0000 ==> 反码:1110 1111 ==> 原码:1001 0000 即 -16

任何数与0异或,结果都是其本身。

利用异或还可以实现两个数的交换:

int a = 10;
int b = -6;
a = a ^ b; //生成补码: 1111 0000
b = a ^ b; //生成补码: 0000 1010 ==> 10
a = a ^ b; //生成补码: 1111 1010 ==> 原: 1000 0110 即-6
//以上通过按位异或,实现a、b两个数的交换。
//交换方法二: (补充)
a = a + b;
b = a - b;
a = a - b;

非(~): 按位取反,包括符号位

计算 ~10
10的补码:0000 1010
-----------------------
结果补码:1111 0101 ==> 反码:1111 0100 ==> 原码:1000 1011 即 -11

计算 ~-6
-6的补码:1111 1010
-----------------------
结果补码:0000 0101 ==> 正数,即 5

移位运算符

右移:低位溢出,符号位不变,并用符号位补溢出的高位

符号:>>

/* 位右移:
 * 右移一位,相当于原数值 / 2,
 * 右移两位,相当于原数值 / 4,
 * 右移n位,相当于原数值 / 2^n
 * 结果没有小数(向下取整)
 */
计算 10 >> 1
10的补码:0000 1010
-----------------------
结果补码:0000 0101 ==> 正数,即 5

计算 10 >> 2
10的补码:0000 1010
-----------------------
结果补码:0000 0010 ==> 正数,即 2

计算 11 >> 1
11的补码:0000 1011
-----------------------
结果补码:0000 0101 ==> 正数,即 5

计算 -11 >> 1
-11的补码:1111 0101
-----------------------
结果补码: 1111 1010 ==> 反码:1111 1001 ==> 原码:1000 0110 即 -6

左移:符号位不变,低位补0

符号:<<

/* 位左移:
 * 左移一位,相当于原数值 * 2,
 * 左移两位,相当于原数值 * 4,
 * 左移n位,相当于原数值 * 2^n
 */
计算 10 << 1
10的补码:0000 1010
-----------------------
结果补码:0001 0100 ==> 正数,即 20

计算 10 << 2
10的补码:0000 1010
-----------------------
结果补码:0010 1000 ==> 正数,即 40

计算 11 << 1
10的补码:0000 1011
-----------------------
结果补码:0001 0110 ==> 正数,即 22

计算 -11 << 1
-11的补码:1111 0101
-----------------------
结果补码: 1110 1010 ==> 反码:1110 1001 ==> 原码:1001 0110 即-22

参考文章:
https://www.jianshu.com/p/c6362f67ef5b
https://www.jianshu.com/p/60952a44841f

上一篇下一篇

猜你喜欢

热点阅读