跳至主要內容

1.数值与编码


整数的表示

无符号整数

无符号整数按道理来说没有补码

无符号数的减法直接减,借位减,最高位比如0-1的情况,不管,假装向前借了1位,所以最高位的0-1结果是1[1]

无符号的减法还有一种解释,在计算机内部,无符号数的加减法等同于补码进行加减法,只是最后对于结果的解释不一样,例如

// 情形一
unsigned A, B;
A = 0;
B = 1;
A - B;
// 情形二
int A, B;
A = 0;
B = 1;
A - B;

提示

两种情况计算的结果都是,A-B进行的其实是[A][B][A]_{\text {补}}-[B]_{\text{补}},就是[0][1][0]_{\text {补}}-[1]_{\text{补}} = 00000000H + FFFFFFFFH = FFFFFFFFH,但是解释不同:

  • 对于无符号的来说,结果就是 FFFFFFFFH
  • 对于有符号的来说,结果FFFFFFFFH是补码,转换成真值就是-1。

有符号整数

定点数的编码表示

定点数的编码表示

补码

  • 纯小数
  • 纯整数

{0,x,0x<2n2n+1+x=2n+1x,2nx<0 \begin{cases} & 0,x, \quad 0\le x\text{<}2^n \\ & 2^{n+1}+x=2^{n+1}-|x|,\quad -2^n\le x \text{<} 0 \end{cases}

若字长为n+1n+1,表示范围为2nx2n1-2^n \le x \le 2^n-1

原码补码十进制
0,00000000,00000000
0,11111110,1111111271=1272^7-1=127
1,00000011,11111111
1,11111101,0000001(271)=127-(2^7-1)=-127
溢出[2]1,0000000-128
1,00000000,0000000[3]-0

补码表示与真值的关系

设一个二进制整数补码有n+1n+1位(含1位符号位xnx_{n}),即

[x]=xnxn1xn2x1x0 [x]_{\text{补}} = x_{n}x_{n-1}x_{n-2}\dots x_{1}x_{0}

其补码表示的真值为

x=2nxn+i=0n12ixi x=-2^n x_{n}+\sum_{i=0}^{n-1}2^ix_{i}

由此可以得出一个推论,即补码的高位扩展符号位,其值不变,例如补码1,1的值等于1,11,1,111,以此类推1,1111...11都一样,证明如下:

f(w)=xnxn1xn2x1x0f(w+1)=xnxnxn1xn2x1x0 \begin{align*} f(w)&=x_{n}x_{n-1}x_{n-2}\dots x_{1}x_{0} \\ \\ f(w+1)&=x_{n}x_{n}x_{n-1}x_{n-2}\dots x_{1}x_{0} \end{align*}

下面我们证明f(w)=f(w+1)f(w)=f(w+1)
按照补码表示与真值的关系,进行展开

f(w)=2nxn+i=0n12ixif(w+1)=2n+1xn+2nxn+i=0n12ixi=2nxn+i=0n12ixi \begin{align*} f(w)&= -2^n x_{n} +\sum_{i=0}^{n-1}2^ix_{i} \\f(w+1)&=-2^{n+1}x_{n}+2^n x_{n} +\sum_{i=0}^{n-1}2^ix_{i} \\ &=-2^n x_{n}+\sum_{i=0}^{n-1}2^ix_{i} \end{align*}

故可以得到f(w)=f(w+1)f(w)=f(w+1)

结论的应用

借助这个结论我们可以很方便的求一些补码的值,例如补码1,1111111,根据结论等于1,1,很显然对应的原码为1,1[4],同时也可以按照补码的定义进行展开,则其值为21+20=1-2^1+2^0=-1,二者是等价的

移码

补码=补码符号取反结果,但是补码实际上的定义是真值+偏置值[5]

补码的移位操作

算术移位

  • 正数的补码在移位时,空位添 0
  • 负数的补码左移时,低位添 0;右移时高位添 1

证明

我们可以从补码关系式展开的角度来看,例如对于f(w)=xnxn1xn2x1x0f(w)=x_{n}x_{n-1}x_{n-2}\dots x_{1}x_{0},左移一位结果为f(w+1)=xnxn1x1x00f(w+1)=x_{n}x_{n-1}\dots x_{1}x_{0} {\color{Red} 0}[6]

f(w)=2nxn+i=1n12ixif(w+1)=2n+1xn+2i=0n12ixi    f(w+1)=2f(w) \begin{align*} f(w)&=-2^n x_{n} +\sum_{i=1}^{n-1}2^ix_{i} \\ f(w+1)&=-2^{n+1}x_{n}+{\color{red}2}\sum_{i=0}^{n-1}2^ix_{i} \\ \implies &f(w+1)=2f(w) \end{align*}

对应的右移一位,则f(w)=xxnxn1xn2x1f^{'}(w)=x^{'}x_{n}x_{n-1}x_{n-2}\dots x_{1},即

f(w)=2nx+2n1xn+12i=1n12ixi f^{'}(w)=-2^{n}x^{'}+2^{n-1}x_{n}+\frac{1}{2}\sum_{i=1}^{n-1}2^{i}x_{i}

显然,此时若不考虑溢出,则f(w)=2f(w)f(w)=2f^{'}(w),故对应的x=xnx^{'}=x_{n}
此时

f(w)=2nx+2n1xn+12i=1n12ixi=2nxn+2n1xn+=2n1+12i=1n12ixi=12f(w) \begin{align*} f^{'}(w)&=-2^{n}x^{'}+2^{n-1}x_{n}+\frac{1}{2}\sum_{i=1}^{n-1}2^{i}x_{i} \\ &=-2^nx_{n}+2^{n-1}x_{n}+\dots \\ &=-2^{n-1}+\frac{1}{2}\sum_{i=1}^{n-1}2^{i}x_{i} \\ &=\frac{1}{2}f(w) \end{align*}

即补码左移时,低位补 0,右移时,高位应该补符号位,即负数补1,正数 补 0

示例

  • 例如对于补码1,100(-4),右移一位对应的是1,110(-2),左移一位是1,000(-8),即若没有溢出正好就是 2 倍的关系
  • 对于补码1,011(-5),右移一位对应1,101(-3),左移一位是0110(溢出)

  1. 这个借位减算不算溢出,2011有个统考真题没有算 ↩︎

  2. 字长为 8 位时,原码和反码是不能表示-128的,至少得 9 位 ↩︎

  3. 按照补码的定义,我们可以知道 0 对应的补码表示是唯一的,即均作为+0,这个位置对应的补码实际上对应的值是-128 ↩︎

  4. 我们可以按照符号位不变,其他位取反加 1 的方式求补码对应的原码 ↩︎

  5. 偏置值取2n12^{n-1} ↩︎

  6. 这里没有考虑溢出 ↩︎