浮点数是小数点位置变化的数,能表示的范围比定点数大不少。web
好比二进制数11.11能够表示为111.1×2-1或1.111×21等,咱们由此规律能获得二进制数更通常形式N=2E×F,E称为阶码,F称为尾数。这个数在机器里怎么存呢,是把正负符号、二、E、E的正负号、F转为01序列存起来吗?svg
若是由咱们本身来设计计算机,这样的确能够,不过总有人会想出更聪明的办法。首先符号位必须占一位,2能够省略不存,默认的。阶码E转为移码存,这样就不用存阶码的正负符号了。最后是很讲究的尾数,尾数为0固然直接存0,不为0时,尾数域的最高位必须为1,好比0.001×20必需要变0.1×2-2,也就是小数点后不能为0,像0.001小数点后为0,就要变化阶码,使得小数点移到1前变成0.1,而后只存小数点以后的数,这个过程叫尾数规格化。设计
因此通常来讲,浮点数的机器码表示以下:xml
符号位 | 阶码 (移码) | 尾数(定点小数) |
---|
现实中具体到底如何实现有许多方法,好比阶码放在尾数后,符号位放在阶码后,阶码用补码表示等。
用一道题目来帮助理解:
如图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
blog
个人分析:
(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)it
(5)浮点数规格化表示,是尾数值不为0时,尾数域最高有效位要为1,好比0.001×20必需要变0.1×2-2, 题目中尾数域为001010000000第一个0为符号位无论,第二个0是能够消去的,变成010100000000,这样消去后,阶码要相应地减1变为1101,故规格化后的机器码1101010100000000table
有个名叫IEEE-754的标准就统一了浮点数具体实现方法,目前大多数高级语言都按照IEEE-754标准来规定浮点数的存储格式,好比Java,还有咱们熟知的C语言。webkit
按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标准的单精度浮点数。