位运算基础

作草分茶About 2 min

位运算基础

计算机内部存储数据都是用0和1来存储的,现在的计算机都是32位或者64位,即如果表示数字5,在32位的计算机中是这样表示的:

00000000 00000000 00000000 00000101

其中8位表示一个字节byte。

原码、反码和补码

以下表格用8位来表示十进制的原码、反码和补码

十进制原码反码补码
5000001010000010100000101
-5100001011111101011111011
2000000100000001000000010
-2100000101111110111111110
3000000110000001100000011
-31000001111111001111101

结论

  1. 正数的原码、反码和补码都是一样。
  2. 负数的反码是在原码的基础上,保持符号位(第一位)不变,后面的每一位都取反,负数的补码是在反码的基础上 +1

验算:

5 - 2 = 5 + ( -2 )
=00000101(补码)+11111110(补码)
=00000011(补码)
=3

左移和右移

jshell> 3<<1
$1 ==> 6
jshell> 3>>1
$2 ==> 1
jshell> -3<<1
$3 ==> -6
jshell> -3>>1
$4 ==> -2

怎么解释上面这些计算数字呢,想知道这个其实只要知道左移右移到底是移什么。

  1. 将3的原码00000011往左移动一位是00000110,这个表示十进制是6。
  2. 将3的原码00000011往右移动一位是00000001,这个表示十进制是1。
  3. 将-3的补码1111101往左移动一位是1111010,然后-1得到反码1111001,再取反得到原码0000110,这个表示十进制是-6。
  4. 将-3的补码1111101往右移动一位是0****111110,然后-1得到反码0111101,再取反得到原码1000010这个表示十进制是-2。

结论

  1. 正数左右移就是原码的左右移。
  2. 负数的左右移是补码左右移之后再-1得到反码,然后取反得到原码。
  3. m << n = m * 2^n。