by 池雨泉
将二进制数以四个为一组,相邻两组之间添加空格,可以提高书写的可读性
半精度表示中,阶码的偏移量是15而不是16,习题3.27题干中的“余16编码”一词有误导性
将被减数5ed4
与减数07a4
分别转换为二进制表示后做减法
xxx x # 借位
0101 1110 1101 0100
- 0000 0111 1010 0100
---------------------
0101 0111 0011 0000
从右往左,逐位相减即可
将结果转换回十六进制得到5730
也可以直接以十六进制的形式做减法
5ed4
- 07a4
-------
5730
由于题目规定这里采用的是符号-大小表示法 (sign-magnitude format),因此最高位是符号位,不参与运算
xxx x # 借位
101 1110 1101 0100
- 000 0111 1010 0100
--------------------
101 0111 0011 0000
由于被减数的绝对值大于减数的绝对值,且两数同号,故结果的符号保持不变
加上符号位后结果变为0 101 0111 0011 0000
转换为十六进制为5730
计算机中
- 整数通常使用补码表示
- 减法通常是由加法实现的,即,先求减数的补码,然后将所求结果与被减数相加
本题中
07a4
对应的二进制表示为0000 0111 1010 0100
- 对其求补码得
1111 1000 0101 1100
- 计算机中,求补码的操作可以分解为
- 求反码
- 加1
- 手算时有一个更快的方法:摁住从右往左看到的第一个
1
不动,右边不动,左边取反
- 计算机中,求补码的操作可以分解为
- 转换为十六进制为
f85c
- 与被减数相加
11110 # 进位 5ed4 + f85c ------- 15730
- 由于结果只有16位,舍去第17位的1,得到
5730
,与前面直接相减的结果相同
可见补码表示法将减法转换为加法,简化了计算机的设计
注:
- 符号-大小表示法并不是没有用武之地
- IEEE 754浮点数标准实际上用到了符号-大小表示法的思想
- 符号-大小表示法又称原码表示法
Note
由于这道题目题干没有交代清楚,因此不参与本次作业的评分。以下的答案假设有两个8位二进制数A和B,当按照无符号数理解时,它们的值分别是185
和122
,题目问的是,如果我们将这两个数A和B按照“符号-大小表示法”进行解释,并进行加法运算,结果等于多少,是否溢出。
- 将十进制数
185
转换为二进制表示1011 1001
- 把上述二进制数看作一个用符号-大小表示法表示的数
- 符号位
1
表明符号为负 - 低7位
011 1001
对应的十进制数是57
- 转换为十六进制是
39
$3 \times 16 + 9 = 57$
- 转换为十六进制是
- 得到
-57
- 符号位
- 将十进制数
122
转换为二进制表示0111 1010
- 把上述二进制数看作一个用符号-大小表示法表示的数
- 符号位
0
表明符号为正 - 低7位
111 1010
对应的十进制数是122
- 转换为十六进制是
7a
$7 \times 16 + 10 = 122$
- 转换为十六进制是
- 得到
+122
- 符号位
由于两个数异号,因此
- 结果的符号与绝对值较大的数相同,为正
- 结果的大小等于两数绝对值之差$122 - 57 = 65$
- 得到
+65
8位符号-大小表示法能够表示的范围是
-127, ..., -0, +0, ..., +65, ..., +127
因此没有溢出
Note
这两道题目不参与本次作业的评分。
待办
- 弄清楚习题3.15需要7次加法还是8次
- 解释图3.7在干什么
十六进制0c00 0000
对应二进制0000 1100 0..0
,最高位为0
,是正数,因此不管是把它看作一个补码 (two's complement) 表示的有符号整数,还是看作一个无符号整数,结果相同
回到十六进制的0c00 0000
- 最低位的权值为
${16}^{0}$ ,假设它的编号为0 - 从右往左数,
c
所在的位置编号为6,权值为${16}^{6}$ - 十六进制的
c
对应十进制的12
,因此结果等于$12\times{16}^{6} = 3\times{2}^{26} = 201,326,592$
十六进制0c00 0000
- 对应二进制
0000 1100 0..0
- 按照1+8+23重新排列
0 0001 1000 0..0
,其中- 符号位为
0
,表示+
- 指数字段为
0001 1000
,转换为十进制得到$16 + 8 = 24$ ,减去偏移值后得到$24 - 127 = -103$ - 尾数字段为全
0
,注意IEEE 754的规格化表示中规定尾数前面有一个隐含的1
- 符号位为
- 合在一起,对应的十进制数为
$1.0 \times 2^{-103}$
将十进制数
- 整数部分与小数部分分开进行
- 整数部分
63
对应二进制11 1111
- 小数部分
0.25
对应二进制0.01
合在一起得到11 1111.01
规格化后为1.1111 101
- 因为
63.25
是正数,所以符号位为0
- 去到最前面的
1
,得到尾数字段1111 101 0..0
- 指数为
$5$ ,加上偏移值$127$ 后得到$132$ ,从而指数字段为1000 0100
合在一起得到0 1000 0100 1111 101 0..0
以4个比特为一组重新排列,得到0100 0010 0111 1101 0..0
转换为十六进制为427d 0000
将
- 方法:小数部分不断乘以2,直到小数部分为0,然后将整数部分从上到下排列
0.15625
x2 0.3125
x2 0.625
x2 1.25
x2 0.5
x2 1.0
得到
- 规格化得到
$1.01 \times 2^{-3}$ - 指数:
$-3 + 15 = 12$ - 对应5位二进制数
01100
- 尾数:扔掉前面的1,得到
01 0000 0000
- 有个负号,所以符号位为
1
- 合在一起为
1 01100 01 0000 0000
- 重新排列得
1011 0001 0000 0000
- 对应十六进制
b100
关于半精度浮点数与单精度浮点数的表示范围的对比,参见More on IEEE 754
待办
- 浮点数在数轴上的间距
- 二进制有效数位的个数是怎样换算成十进制有效数位的个数的
- 例如,半精度表示包含
$10 + 1$ 个二进制有效数位,这大约对应$11 \times \log_10 2 \approx 3.31$ 个十进制有效数字 - 为什么可以通过取对数的方式进行这种转换?
- 参考IEEE 754 - Wikipedia
- 例如,半精度表示包含
设两个待相加的数分别为a和b
将26.125转换为二进制
- 整数部分为
1 1010
- 小数部分为
0.001
- 合在一起为
1 1010.001
- 规格化得到
$1.1010 001 \times 2^4$
对应的半精度表示为0 10011 1010 0010 00
将0.4150390625转换为二进制
0.4150390625
x2 0.830078125
x2 1.66015625
x2 1.3203125
x2 0.640625
x2 1.28125
x2 0.5625
x2 1.125
x2 0.25
x2 0.5
x2 1.0
- 结果为
0.0110 1010 01
- 规格化得到
$1.1010 1001 \times 2^{-2}$
对应的半精度表示为0 01101 1010 1001 00
- 小阶对大阶
- 相加/减
- 规格化
- 舍入
- 如果结果变为非规格化数,回到第3步
- 溢出判断
G - guard bit
R - round bit
1.1010 1001 00 x 2E-2
0.0000 0110 1010 0100 x 2E4
GR
由于round bit右侧有非零数位,将sticky bit置为1
S - sticky bit
0.0000 0110 1010 1 x 2E4
GR S
a: 1.1010 0010 0000 0 x 2E4
b: 0.0000 0110 1010 1 x 2E4
+: 1.1010 1000 1010 1 x 2E4
GR S
由于结果已经是规格化数,因此这里不需要任何操作
舍入规则
- 当GRS小于等于
100
时,舍(最后一个有效数位不变) - 当GRS大于等于
101
时,入(最后一个有效数位加一)
GR S
1.1010 1000 1010 1 x 2E4
1.1010 1000 11 x 2E4
- 半精度可以表示的绝对值最小的规格化数为
0 00001 0000 0000 00
- 半精度可以表示的绝对值最大的规格化数为
0 11110 1111 1111 11
显然本题结果在这两个数之间,所以没有溢出
最终结果
-
二进制
1.1010 1000 11 x 2E4
-
移位
11010.1000 11
-
整数部分等于
$26$ -
小数部分等于
$\frac{1}{2^1} + \frac{1}{2^5} + \frac{1}{2^6} = 0.546875$ -
合在一起得到十进制
$26.546875$ -
对应的半精度表示为
0 10011 1010 1000 11
-
重新排列得
0100 1110 1010 0011
-
对应十六进制
4ea3
- 整数部分
1000
- 小数部分
0.0000 111
0.0546875 x2 0.109375 x2 0.21875 x2 0.4375 x2 0.875 x2 1.75 x2 1.5 x2 1.0
- 合在一起
1000.0000 111
- 规格化
1.0000 0001 11 x 2E3
- 符号为负,因此半精度表示
1 10010 0000 0001 11
- 重新排列得
1100 1000 0000 0111
- 对应十六进制
c807
0.179931640625
x2 0.35986328125
x2 0.7197265625
x2 1.439453125
x2 0.87890625
x2 1.7578125
x2 1.515625
x2 1.03125
x2 0.0625
x2 0.125
x2 0.25
x2 0.5
x2 1.0
- 二进制表示为
0.0010 1110 0001
- 规格化得
1.0111 0000 1 x 2E-3
- 符号为负,因此半精度表示为
1 01100 0111 0000 10
- 重新排列得
1011 0001 1100 0010
- 对应十六进制
b1c2
- 指数相加
- 尾数相乘
- 规格化
- 舍入
- 如果得到非规格化数,回到第3步
- 设置符号
1.0000 0001 11
x 1.0111 0000 10
----------------
0 .... .... .0
10 0000 0011 1
0.. .... ...0
0... .... ..0
0 .... .... .0
0. .... .... 0
100 0000 0111
1000 0000 111
1 0000 0001 11
0. .... .... 0
1 00 0000 0111
--------------------------
1.01 1100 1100 0001 0011 10
1.01 1100 1100 001
GRS
不需要进行任何操作
001
小于等于100
,因此舍,得到1.01 1100 1100
在这里可以求出误差
1.01 1100 1100 0001 0011 10
- 1.01 1100 1100
-----------------------------
0.00 0000 0000 0001 0011 10
对应的十进制小数为
负负得正
-
因此结果为
1.01 1100 1100 x 2E0
-
整数部分等于
$1$ -
小数部分等于
$\frac{1}{2^2} + \frac{1}{2^3} + \frac{1}{2^4} + \frac{1}{2^7} + \frac{1}{2^8} = 0.44921875$ -
合在一起得到十进制
$1.44921875$ -
转换为半精度表示为
0 01111 01 1100 1100
-
重新排列得
0011 1101 1100 1100
-
对应十六进制
3dcc