计算机中的补码与无符号编码 [笔记]

Posted by Yinode on Thursday, October 31, 2019

TOC

在计算机中,我们可以采用 补码 以及 无符号 两种方式来存储我们的整数,两者的主要差别如下

  • 补码

第一位为符号位,当符号为 = 1 时,代表一个负权,= 0 时,权也为 0

每一位都有响应的权,最终十进制表示就等于 整个向量的加权

比如 [0,1,1,1] 为四位长度 其十进制等于 7, [1,0,0,0] 最高位为负权 = - 2 ^ 3 = -8

  • 无符号

全部为有效位,无法表示负数

比如 [1,1,1,1] 其十进制等于 16

表示范围

既然作为一种编码方式,自然会拥有表示的上下限,这里记录一下两者的上下限

无符号数的表示范围

我们用 U表示无符号数这种编码方式(usigned) , 用 w代表其位长(也就是有多少个位的情况下)

  1. 其下限自然等于所有位都为0也就是 0
  2. 他的上限等于 (2 ^ w) - 1 最后减一自然是因为你还得表示0

给出数学表示

UMin(w) = 0 UMax(w) = (2 ^ w) - 1

公式不太好输,见谅

补码的表示范围

我们用 T 表示补码(Two’s complement)这种编码方式

由于最高位作为符号位,所以我们获得了表达负数的能力,但是在正数这一块的最大值也降低了。这里直接给出数学表达

TMin(w) = - (2 ^ (w - 1) ) TMax(w) = (2 ^ (w - 1) ) - 1

你发现两者在数轴上并不对称,这主要是因为 0 只能被分配到非负的空间,在符号位=1, w = 4 的情况他 最大的可能值就是 [1,1,1,1] = -1 所以负数方向会拥有更大的编码空间。

还有值得一提的就是 UMax(w) = TMax(w) * 2 + 1 这个能通过换算得到。

TMax(w) * 2 + 1 = ( (2 ^ (w - 1) ) - 1 ) * 2 + 1 = 2 ^ w - 2 + 1 = 2 ^ w - 1 = UMax(w)

两者之间的转换

在一般语言之中,如果你要对这两种表示法进行转换,语言的默认行为是保持保持二进制上的存储,但是由于编码方式的转变,必然会造成一些程度上的变化

补码转无符号

由于有条件,所以给出类似流程判断的伪代码

// T2U 表示补码转无符号
// w 代表位数
// x 被转化的10进制整数

 T2Uw(x) = 
    if x < 0
      return x + 2 ^ 2
    else if x >= 0
      return x

无符号转补码

// U2T 代表无符号转补码
// w 代表位数
// x 被转换的10进制整数

  U2Tw(x) = 
    if x <= TMax(w)
      return u
    else if x > TMax(w)
      return u - 2 ^ w

参考

  1. 《CS:APP》