浮点数在计算机中的编码
我们知道整数在计算机中的编码,源码,补码,反码等等,利用二进制的数表示一个整数,比如,32可以表示成“100000”,但是对于浮点数的编码,一般的教材介绍的很少,这里做了一点资料整理,希望对大家有用。
1、历史
浮点表示对形如的有理数进行编码。它对执行涉及非常大的数字(|V|>>0)、非常接近于0(|V|<<1)的数字,以及更普遍的作为实数运算的近似值的计算,是很有用的。
直到20世纪80年代,每个计算机制造商都设计了自己的表示浮点数的规则,以及对浮点数执行运算的细节。另外,他们常常不会关注运算的准确性,而把实现的速度和简便性看得比数字精确性更重要。
大约在1985年,这些情况随着IEEE标准754的推出而改变了,这是一个仔细定制的表示浮点数及其运算的标准。这项工作是从1976年开始由Intel赞助的,在8087设计的同时,8087是作为一种为8086处理器提供浮点支持的芯片。他们请William Kahan(加州大学伯克利分校的一名教授)作为顾问,帮助设计未来处理器的浮点标准。他们支持Kahan加入一个IEEE资助的制定工业标准的委员会。这个委员会最终采纳的标准非常接近于Kahan为Intel设计的标准。目前,实际上所有的计算机都支持这个后来被称为IEEE浮点的标准。这大大提高了科学应用程序在不同机器上的可移植性。
题外话:这里也是看出来Intel的人有着一般人没有的前瞻性,果然,大公司还是大公司
2、IEEE浮点表示
IEEE浮点标准使用的形式来表示一个数:
符号(sign):s决定这个数是负数(s=1)还是正数(s=0),而对于数值0的符号位解释做特殊情况处理。
尾数(significand):M是一个二进制小数,它的范围是,或者是。
阶码(exponent):E的作用是对浮点数加权,这个权重是2的E次冪(可能是负数)。
在C语言中浮点数包括单精度浮点数(float)、双精度浮点数(double),分别占有32位和64位,对于float而言,符号位用1位表示,尾数M用8位表示,阶码E用23位表示。而对于double而言,符号位1位,尾数11位,阶码52位,具体表示如下图所示。
单精度
31 30 23 22 0
s |
exp |
frac |
双精度和单精度类似,这里不做描述。
题外知识:
(float和double的精度是由尾数的位数来决定的。浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,由于它是不变的,故不能对精度造成影响。
float:2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字;
double:2^52 = 4503599627370496,一共16位,同理,double的精度为15~16位。)
这里拿单精度浮点数做例子说明。
当给定了一个浮点数后,根据里面M和E值的不同分为三种情况,规格化的值、非规格化的值以及特殊值,浮点数存储在4个字节内,如下图所示:
1:规格化的值
s |
|
f |
注意:阶码的值不能全为1或者全为0。
2:非规格化的值
s |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
f |
注意:阶码的值全为0。
3:特殊值
3a:无穷大
s |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
注意:阶码的值全为1,尾数为0。
3b:非数字,即表示的不是一个数字
s |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
≠ 0 |
这三种情况分别怎样表示浮点数呢?这里分别说明:
情况1:规格化
阶码的位既不全为0,也不全为1,这种情况下
公式的三个参数: s已知;
E的值为e-bias,其中e是8位阶码所代表的值,例如“00000011”就表示3,bias是一个等于(k是阶码的位数,这里是8位)的偏置值。
M的值定义为1+f,f是23位二进制码尾数代表的值。
情况2:非规格化
此时阶码域全为0,在这种情况下,阶码值E=1-bias,尾数M=f。
情况3:特殊值
当阶码全为1,尾数为0时表示无穷大,当s=0时表示正无穷,s=-1时表示负无穷,如果尾数值不为0,那么这样所表示的就不是一个数,比如当计算时。
3、浮点表示实例
前面做了那么多讲解,相信有些还是有些迷糊,这里做一个示范,显示浮点数表示法的具体应用:
假设一个8位的浮点数,其中阶码位k=4,尾数位n=3,那么根据公式,偏置量bias=7,以下表格是浮点数的具体表示:
描述 |
位表示 |
指数 |
小数 |
值 |
e E 2E |
f M |
M*2E V 十进制 |
||
0 最小的非规格化数
最大的非规格化数 |
0 0000 000 0 0000 001 0 0000 010 . . . 0 0000 111 |
0 -6 1/64 0 -6 1/64 0 -6 1/64
0 -6 1/64 |
0/8 0/8 1/8 1/8 2/8 2/8
7/8 7/8 |
0/512 0 0.0 1/512 1/512 0.001953 2/512 1/256 0.003906
7/512 7/512 0.013672 |
最小的规格化数
1
|
0 0001 000 0 0001 001 . . . 0 0110 110 0 0110 111 0 0111 000 0 0111 001 0 0111 010 . . . 0 1110 110 |
0 -6 1/64 0 -6 1/64
6 -1 1/2 6 -1 1/2 7 0 1 7 0 1 7 0 1
14 7 128 |
0/8 8/8 1/8 9/8
6/8 14/8 7/8 15/8 0/8 8/8 1/8 9/8 2/8 10/8
6/8 14/8 |
8/512 1/64 0.015625 9/512 9/512 0.017578
14/16 7/8 0.875 15/16 15/16 0.9375 8/8 1 1.0 9/8 9/8 1.125 10/8 5/4 1.25
1792/8 224 224.0 |
最大的规格化数 |
0 1110 111 |
14 7 128 |
7/8 15/8 |
1920/8 240 240.0 |
无穷大 |
0 1111 000 |
— — — |
— — |
— — |
相信大家通过这个表格能够对浮点数的计算机表示得到自己的理解。