位运算之补码

位运算之补码

  • 补码
  • 理解计算机数值的加法
  • 利用补码可以用加法来计算减法

位运算在我们开发工作中经常遇到,在一些性能优化的场景经常会出现位运算的场景,比如Java的HashMap里面就是不是通过取余操作而是通过 (n - 1) & hash 来计算key的index的(table array的length是2的n次方)。

程序中的整数在计算机内存中都是以二进制的形式存在的,位运算就是直接对整数在内存中对应的二进制位进行操作。

补码

首先需要补充一个背景知识:

  • 正数的补码就是正数本身;
  • 负数的补码 = 负数的绝对值取反 + 1

举个例子: 以int8为例:

  • 15的的补码就是: 00001111
  • -15的补码是:11110001
    我们分析下-15的补码是怎么算出来的:
  1. 取绝对值:|-15| = 15 == 00001111
  2. 按位取反得到:11110000
  3. 加一:11110001

我们设定:二进制中最高位为 0 代表正,为 1 则代表负。

理解计算机数值的加法

int8的整数为例,表示的数的范围是-128 ~ 127

(1)127+127
我们现在推倒127 + 127 的过程, 下面数值都用二进制表示
01111111 + 01111111 -> 11111110,
很明显,11111110因为第一个二进制位是1,所以是一个负数。

根据负数补码计算方法反推:原码的绝对值 = (补码 - 1,再求反)

所以:11111110的原码的绝对值 = 00000010,也就是int8的127 + 127最后结果是-2。

(2)127+127+127

前面已经得到127+127等于 -2。再加上127也就是:
11111110 + 01111111 = 01111101 (注意,超出8位的会溢出)
这明显是个正数,也就是125。

利用补码可以用加法来计算减法

还是基于int8来说。建设我们现在要计算 7-3,但是我们希望通过加法来计算减法。

也就是我们希望计算 7 + (-3):

  1. 7的补码加上 -3 的补码
  2. 00000111(7的补码) + 11111101(-3的补码)
  3. 00000111 + ^(00000011 -1)

也就是负数的补码 = ^ (负数对应的正数-1) 。 这里的^是按位取反的意思。

你可能感兴趣的:(Golang,数据结构-basic)