原码·表示数值
例子采用4位二进制,最高位表示符号位,0代表正、1代表负
缺点:
1、0的表示不唯一,故不利于程序员编程
+0:0000
-0:1000
2、加、减运算方式不唯一
3+2:
3-2:
0011 0011
+ 0010 - 0010
---- ----
0101 0001
3、需要额外对符号进行处理,故不利于硬件设计
需要硬件对加法处理的同时又需要硬件对减法的处理,这大大增加了设计的难度。
4、当a<b时,实现a-b比较困难
2-3:
0010
- 0011
----
001?
因此从50年代开始,整数都采用补码来表示,但浮点数的尾数用原码定点小数表示。
补码-模运算(modular运算)
在一个模运算系统中,一个数与它除以“模"后的余数等价
例子:
时钟是一个模12系统
假定钟表时针指向10点,要将它爸向6点,则有两种方法:
1、倒退4格:10-4=6
2、顺序转8格:10+8=18 %12=6
模12系统中:10-4=10+8 等价于 -4=8
则称8是-4对模12的补码(即-4的模12补码等于8)
结论一:一个负数的补码等于模减该负数的绝对值
结论二:对于某一个确定的模,某数减去小于模的另一个数,总可以用该数加上另一负数的补码来代替。
12模系统:
10-4=10+8 (mod 12)
补码:+和-的统一
即计算10-4的减法运算时,可以采用加上负数对应补码进行加法运算来代替减法运算。
补码(二进制)表示
8位二进制加法器模运算系统
计算 0111 1111 - 0100 0000 =? [-0100 0000]补码=[2^8-0100 0000]
= 0111 1111 + 2^8 - 0100 0000
= 0111 1111 + 1100 0000
= 1 0011 1111 (mod 2^8)
= 0011 1111
结论:一个负数的补码等于将对应的正数补码各位取反,末位加一
补码的定义: 假定补码有n位,则:
[x]补=2^n+x (-2^(n-1)<=x<2^(n-1),mod 2^n)
x-真值 [x]补-机器数
假定机器数n位
1、[-2^(n-1)]=2^n - 2^(n-1)=10...0 (n-1个0)
2、[-1]补 = 2^n - 0...01 = 11...1 (n个1)
3、[+0]补 = [-0]补 = 00...0 (n个0)
n=4
[-1]补= 1 0000
- 0001
---------
0 1111
变形(4`s)补码
双符号,用于存放可能溢出的中间结果
假定n为4位
8:
补码: 1000
值太大,用4位补码无法表示,故"溢出",但用变形补码可保留符号位和最高数值位
变形补码: 0 1000
-8
补码: 1000
变形补码: 1 1000
+0和-0表示唯一
求真值的补码
设机器数有8位,求123和-123的补码表示
如何快速得到123的二进制表示
123 = 127 - 4 =0111 1111 - 0000 0100 =0111 1011
[0111 1011]补 = 2^8 + 0111 1011 = 1 0000 0000 + 0111 1011
= 1 0111 1011(mod 2^8)
=0111 1011
[-0111 1011]补 = 2^8 - 0111 1011 =1 0000 0000 - 0111 1011
= 1111 1111 - 0111 1011 +0000 0001
= 1000 0100 + 0000 0001 各位取反,末位加一
= 1000 0101
简便方法:从右向左遇到第一个1的前面各位取反
求补码的真值
补码"1101 0110"的真值为
-2^7 + 2^6 + 2^4 +2^2 + 2^1 =-42
补码"0101 0110"的真值为
-0*2^7 + 2^6 + 2^4 + 2^2 + 2^1 = 86
移码表示Excess (biased)notion
将每一个数值加上一个偏置常数(bias)
通常,当编码位数为n时,bisa取2(n-1)或2(n-1)-1(如IEEE 754)
0的移码表示唯一
当bisa为2n-1时,移码和补码仅第一位不同
Ex.n=4: Ebiased=E+23(bias=23=1000B)
-1:1111 ~ 0111
0:0000 ~ 1000
1: 0001 ~ 1001
移码用来表示浮点数的阶
为什么要用移码来表示指数(阶码)?
1.01 * 2-1+1.11*23
补码: 111 (-1) < 011 (3) ?
简化比较
1.01 * 2-1+4+1.11*23+4
移码: 011 (3) < 111 (7)