初步了解机器中浮点数表示方法

浮点数是小数点位置变化的数,能表示的范围比定点数大很多。

比如二进制数11.11可以表示为111.1×2-1或1.111×21等,我们由此规律能得到二进制数更一般形式N=2E×F,E称为阶码,F称为尾数。这个数在机器里怎么存呢,是把正负符号、2、E、E的正负号、F转为01序列存起来吗?

如果由我们自己来设计计算机,这样的确可以,不过总有人会想出更聪明的办法。首先符号位必须占一位,2可以省略不存,默认的。阶码E转为移码存,这样就不用存阶码的正负符号了。最后是很讲究的尾数,尾数为0当然直接存0,不为0时,尾数域的最高位必须为1,比如0.001×20必须要变0.1×2-2,也就是小数点后不能为0,像0.001小数点后为0,就要变化阶码,使得小数点移到1前变成0.1,然后只存小数点之后的数,这个过程叫尾数规格化。

所以一般来说,浮点数的机器码表示如下:

符号位 阶码 (移码) 尾数(定点小数)

现实中具体到底如何实现有许多方法,比如阶码放在尾数后,符号位放在阶码后,阶码用补码表示等。
用一道题目来帮助理解:
在这里插入图片描述
在这里插入图片描述
如图1所示为计算机中16位浮点数的表示格式。
某机器码为1110001010000000。
若阶码为移码且尾数为反码,其十进制真值为 (1) ;
若阶码为移码且尾数为原码,其十进制真值为 (2) ;
若阶码为补码且尾数为反码,其十进制真值为 (3) ;
若阶码为补码且尾数为原码,其十进制真值为 (4) ,将其规格化后的机器码为 (5) 。
(1) ~ (4)
A.0.078125
B.20
C.1.25
D.20.969375
(5)
A.1110001010000000
B.11110101000000
C.1101010100000000
D.11110001010000

我的分析:
(1)阶码为移码,即1110为移码,对应原码为0110,其十进制真值为6,尾数001010000000为反码,正数反码换成原码为原形式,其对应十进制真值为2-2+2-4=0.3125,所以整个数十进制真值为26×0.3125=20
(2)阶码为移码,尾数为原码,和(1)是一样的。

(3)阶码为补码,补码1110对应的原码为1010,即-2,尾数为反码,(1)已经分析过为0.3125,则整个数十进制真值为2-2×0.3125=0.078125
(4)阶码1110为补码,真值为-2,尾数为原码,同(3)

(5)浮点数规格化表示,是尾数值不为0时,尾数域最高有效位要为1,比如0.001×20必须要变0.1×2-2, 题目中尾数域为001010000000第一个0为符号位不管,第二个0是可以消去的,变成010100000000,这样消去后,阶码要相应地减1变为1101,故规格化后的机器码1101010100000000

有个名叫IEEE-754的标准就统一了浮点数具体实现方法,目前大多数高级语言都按照IEEE-754标准来规定浮点数的存储格式,比如Java,还有我们熟知的C语言。

按IEEE-754标准定义的单精度浮点数float:

符号位 阶码 (移码) 尾数(定点小数)
0位 1~8位 9~31位

双精度浮点数double

符号位 阶码 (移码) 尾数(定点小数)
0位 1~11位 12~63位

IEEE-754中尾数的规格化有所不同,之前我们说尾数规格化规定小数点后为1,IEEE-754中就将此固定的1设为默认值去掉了,因此尾数域表示的值为1.xxxx(只存储xxxx,1是默认有的),这样使得尾数表示范围多上一位。

IEEE-754中阶码的移码也有特别规定,要除去阶码的全0和全1状态,因此像float中阶码的取值不是0~255,而是1 ~ 254,也就是说这里的阶码的移码不是简单地由补码变符号而来,还要减1,换个说法就是偏移量不为128了,而为127。所以对于float来说,真正指数的范围为-126 ~+127,所表示的数范围也就为2-126 ~2127即10-38 ~1038
举个栗子
在这里插入图片描述
将176.0625表示为符合IEEE-754标准的单精度浮点数。

  1. 首先将176.0625化为二进制:10110000.0001
  2. 尾数规格化:1.01100000001×27,因此尾数域求出来了,为01100000001
  3. 阶码的移码:7的二进制为00000111,移码为10000110。
  4. 拼接:0 10000110 01100000001000000000000
    尾数域记得要补0使尾数有23位。

posted on 2019-04-13 19:17  107国道道长  阅读(2497)  评论(0编辑  收藏  举报

导航