您的位置:首页 > 其它

由一道习题看如何设计浮点数

2016-09-24 15:12 239 查看
一道浮点数计算的题目,计算了很长时间,最终结果还是因为部分细节出错,导致全盘皆错,因此,有必要认真总结浮点数计算牵涉到的方方面面的数据表示的细节。

这个过程本身相当有趣,因为人脑在处理二进制方面并没有十进制那种直觉。尤其是当在补码下计算,总是得先进行一次数据的反加1才能看出数字的本意,进行一个减法,也需要默念,将减数连通符号位求反加一再和减数相加。甚至不如直接进行十进制数的加减再换算为补码。。

这个过程中需要多次进行这样的计算,仅仅明了计算规则,根本不能解决问题,需要的是细心,以及–实力。

好了,直接看题目,然后再在解析的过程中,一一解释。

已知十进制数X = -5/256, Y = +59/1024,按机器补码浮点运算的规则计算X-Y,结果用二进制表示,浮点数的格式如下:阶符取2位,阶码取3位,数符取2位,尾数取9位。

OK,首先在脑海中建立一种浮点数的格式:阶符+阶码+数符+尾数。

且均用补码表示。

这里题目中给出的小数很nice。

先用自然的语言表示一下,不考虑有多少位数用于存储:

X=−101⋅2−8

Y=+111011⋅2−10

再考虑移位使之满足规格化的形式。

X=−0.101⋅2−5

Y=0.111011⋅2−4

再最终化为补码的形式:

X=11,011;11,011000000 (分号前是阶码的补码表示:-5,分号后面是-0.101的补码表示)

Y=11,100;00,111011000(分号前面是阶码的补码表示:-4,分号后面是0.111011的补码表示)

这里有我比较迷惑的一点,在表示-0.101的时候,化为补码我知道是11.011,但是尾数有9位,在后面要补1还是补0?

如果是补1的话就是:11.011,111,111补化回来就是11.100,000,001原,等同于末尾加了个1,且前面的三位也不是以前的了。因此补1是不行的。

如果补0:11.011,000,000补 化回来是11.101,000,000原

我们知道后面的6个0,求反变成1后,是6个1,再因为加1会变成6个0并且往上进位一个1.

这里是不是因为11.011最低位是1,所以正确,如果是11.010补呢?11.010补对应的原码是11.110原

我们把补码补位到9位:11.010,000,000补,化回来是:11.110,000,000原

模拟这个过程时,突然明白了补0的原因:原码的数据位变补码是求反加1,这个1加在原来数据位的最低位,现在最低位在补的数据位里成了中产阶级,这个1会加到新的数据位长度的位置上,这是不行的,因此这个补贴需要通过链式传递的方式传回来。因此,补位的补码全是0.

解释的原因就是想说,如果一个补码小数被扩大了尾数的表示位数,在低位补0.

Ok,表示结束后,开始对阶:小阶变大阶。

所以是X的阶码往大里变。

X=11,100;11,101,100,000补

Y=11,100;00,111,011,000补

于是再进行尾数求和:[X尾]补−[Y尾]补=[X尾]补+[−Y尾]补

其中[−Y尾]补=[Y尾]补连同符号位求反加一

所以得到:10,110,001,000所以有溢出,需要右规,变成:11,011,000,100.

右归必然使得阶码加1,可以表示成:

11,100+00,001=11,101

于是最终结果是:11,101;11,011,000,100.

也就是:2−3⋅(−0.1001111)2=−0.0771484375

而我们知道,如果真的计算
$X - Y = +0.0380859375$


可见,因为位数的限制,还是有很大的误差的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息