目录
  1. 1. 无符号整数的编码
  2. 2. 有负数的编码
    1. 2.1. 移码
    2. 2.2. 原码(Sign-Magnitude)
    3. 2.3. 反码(Ones' Complement)
    4. 2.4. 补码(two's-complement)
整数的编码

为了方便叙述,我们先确定一些概念:

  • 假设有一个整数数据类型有w位,我们可以把位向量写为 \(\vec{x}≡[x_{w-1},x_{w-2},...,x_{0}]\) (注意最高位是w-1位) ,表示整个向量。
  • 对某类数据的内部真实储存情况的零一串,记作内码;真正想表示的数,记作意码
  • 将零一串\(\vec{x}\)直接读成二进制数得到数字,这种变化记作\(B2U_w(\vec x)\) (B2U:binary to unsigned),即\(B2U_w(\vec x)≡Σ^{w-1}_{i=0}x_i2^i\)\(U2B_w(x)\)是它的反函数,可证这是双射。
  • 为了简化表示,我们将正在以A方式编码的、意码为x的内码记作\(\vec{x}_{A_{ed}}\)

无符号整数的编码

直接将 \(\vec{x}\) 视作二进制数,就是 \(\vec{x}\) 的无符号表示。

优点:

  • 简明直观

缺点:

  • 没有负数

有负数的编码

移码

为了兼容负数的朴素编码,若数据为w位,考虑意码是由内码减去\(2^{w-1}\)得到,则可以得到意码范围在\(-2^{w-1} \sim 2^{w-1}\)的编码。

优点:

  • 直观,可以直接兼容移码和无符号编码的加减计算。没有两个0。

缺点:

  • 移码与移码的加减运算要稍复杂。\(B2U_w(\vec{x}_{移_{ed}})+B2U_w(\vec{y}_{移_{ed}})=B2U_w(\vec{x}_{移_{ed}}+\vec{y}_{移_{ed}}-U2B_w(2^{w-1}))\) ; \(B2U_w(\vec{x}_{移_{ed}})-B2U_w(\vec{y}_{移_{ed}})=B2U_w(\vec{x}_{移_{ed}}-\vec{y}_{移_{ed}}+U2B_w(2^{w-1}))\)

原码(Sign-Magnitude)

还有一种很朴素的想法,就是将最高位作为正负标志,称为符号位。一般将符号位为0视作正数;1为负数。即 \(B2S_w(\vec{x}_{原_{ed}})≡(-1)^{x_{w-1}}Σ^{w-2}_{i=0}x_i2^i\)

优点:

  • 直观朴素,容易看出负数的意码

缺点:

  • “正数+负数”处理很困难,存在“+0”和“-0”两个0

反码(Ones' Complement)

正数表示不变,某正数的对应的负数储存为这个正数的反码(按位取反)。转化公式为\(B2O_w(\vec{x}_{原_{ed}})≡-x_{w-1}(2^{w-1}-1)+Σ^{w-2}_{i=0}x_i2^i\)

优点:

  • 还算直观,比较容易看出负数的意码

缺点:

  • 加减处理较困难,存在“+0”和“-0”两个0

补码(two's-complement)

正数表示不变,某正数的对应的负数储存为这个正数的反码+1。转化公式为\(B2T_w(\vec{x}_{原_{ed}})≡-x_{w-1}2^{w-1}+Σ^{w-2}_{i=0}x_i2^i\)。这样任何数的加减计算都可以直接使用内码加减,如果有进位到w位(位数溢出),直接抛掉(或者说无视w位的情况,始终认定w-1是最高位)

优点:

  • 加减处理非常方便,只有一个0。

缺点:

  • 负数的意码较难直接看出,正负数表示范围差了1(负数比正数范围大1)。
文章作者: LxChx
文章链接: http://yoursite.com/posts/1010843376/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LxChx