关于浮点数和IEEE754标准的一点理解

1.什么是浮点数?

小数点浮动的数,简称浮点数

2.浮点数的分类

float :单精度浮点数      (4字节)

double float :双精度浮点数       (8字节)

long double float 扩展双精度浮点数    (建议16字节)

3.对于long double float 具体字节长度的解释

 ANSI C并未规定long double float 的确切精度。所以对于不同平台可能有不同的实现。有的是8字节,有的是10字节,有的是12字节或更多

一般来说long double的精度要高于double, 至少相等,就像int和long int一样,记住与具体平台的实现有关。

4.在计算机中的存储方式

float的存储方式:符号位(S)+指数位(E)+小数位/有效数字(M)

doule float 的存储方式:符号位(S)+指数位(E)+小数位/有效数字(M)

由上图可见,二者在存储方式上一致的,都由三部分组成,只是指数位和小数位的长度不一样,从而导致表示的范围和精度不一样,篇幅有限,对于long double float 的存储方式未给出解释,具体可以查阅IEEE 754.

5.如何将一个浮点数转换为计算机内存储的内码形式

例如十进制数:25.5     对应的二进制形式为:11001.1  (如何将十进制浮点数转换为二进制,不在本文的讨论范围之类),改写成相应的指数形式为:1.10011*2^4

25.5在float的精度范围内表示绰绰有余,假设我们用单精度浮点数来存储它,符号位S=0(正数),负数的符号位为1,8位指数位为127+4=131(其中127为指数的偏移量),至于为什么要加上偏移,且偏移为何偏偏为127的原因,我们后面会讨论,我们暂且按规定来,指数位131转换为二进制位:1000 0011,接下来小数位M=10011,原始的小数位应该是1.10011,为什么可以省略小数点前面的1呢?因为我们用来存储小数位的二进制bit位是有限的,而我们希望利用有限的二进制bit位来尽可能大存储浮点数的精度范围,因此我们可以将小数点前面的默认的1可以省略,只要我们在还原时记得加上小数点前面的1就可以。

因此25.5用float类型来存储的编码为:0   1000 0011    0000 0000 0000 0000 0010 011

如果是负浮点数只需要将最高位的符号位改为1,其他步骤一样。

6.浮点数的表示范围

我们知道float的指数范围为:E=(-126 ~+127)     而小数M的范围为:1<=M <2故可表示的最大正浮点数范围为2*2^(+127),前面的2表示小数的最大范围,其实是取不到2的,这里考虑极值,通过计算器可得2*2^(+127) ≈1.7*10^(38)     ,而我们考虑最小值,-2*2^(+127) ≈ -1.7*10^(38) .可能有朋友会疑惑为什么最小值不考虑取指数的-126的情况?

其实我们想想:2*2^(-126)  ≈ 2.35*10^(-38)  是一个非常接近于0的数,而不是float的下限值。

因此我们得出了float型数的可表示范围为:(-1.7*10^(38)  ~    1.7*10^(38))。

  而double float 的指数范围为:E=(-1022 ~+1023) 相应的我们可以计算出double的可表示范围为:( -1.7*10^(308)  ~  1.7*10^(308))

7.有效数字与精度范围是如何得来的?

我们知道float类型的浮点数的精度范围是6~7位有效数字,意指可以保证小数点后6~7的有效数字是准确的,再往后的小数位不能保证正确

而double类型的精度范围是15~16位有效数字,但这是如何得来的呢?

我们知道float的有效数字M=23位,可表示的范围为:0000 0000 0000 0000 0000 000  ~ 1111 1111 1111 1111 1111 111 转换成十进制数位(0 ~ 8388608)刚好为7位数,故可表示的精度范围为:1.0000000 ~ 1.8388608,故我们可以保证6位有效数字是绝对精确的,而七位有效数字不一定准确。

相应的double类型的有效数字M=51,可小数范围为:(0 ~  2^52 = 4503599627370496)刚好16位数字,故可表示的精度范围为:1.0000000000000000 ~ 1.4503599627370496 。故我们可以保证15位有效数字是绝对精确的,而16位有效数字不一定准确。

7.IEEE754对于小数M和指数E的一些特殊规定

a. 对于有效数字:1≤M<2,也就是说,M 可以写成1.xxxxxx 的形式,其中xxxxxx 表示小数部分。IEEE 754 规定,在计算机内部保存M 时,默认这个数的第一位总是1, 
因此可以被舍去,只保存后面的xxxxxx 部分。比如保存1.01 的时候,只保存01,等到读取的时候,再把第一位的1 加上去。这样做的目的,是节省1 位有效数字,以32 位浮点数为例,留给M 只有23 位,将第一位的1 舍去以后,等于可以保存24 位有效数字。

b. 指数E,情况就比较复杂。 

首先,E 为一个无符号整数(unsigned int)。这意味着,如果E 为8 位,它的取值范围为0~255;如果E 为11 位,它的取值范围为0~2047。但是,我们知道,科学计数法中的E 是可以出现负数的,所以IEEE 754 规定,E 的真实值必须再减去一个中间数,对于8 位的E,这个中间数是127;对于11 位的E,这个中间数是1023。比如,2^10  的E 是10,所以保存成32 位浮点数时,必须保存成10+127=137,即10001001。

c. 然后,指数E 还可以再分成三种情况:(1)E 不全为0 或不全为1。这时,浮点数就采用上面的规则表示,即指数E  的计算值减去127   (或1023),得到真实值,再将有效数字M 前加上第一位的1。 

(2)E 全为0。这时,浮点数的指数E 等于1-127 (或者1-1023),有效数字M 不再加上第一位的1,而是还原为0.xxxxxx 的小数。这样做是为了表示±0,以及接近 于0 的很小的数字。 
(3)E 全为1。这时,如果有效数字M 全为0,表示±无穷大(正负取决于符号位s);如果有效数字M 不全为0,表示这个数不是一个数(NaN)。
注释:
        (以8 为指数位的float 类型为例,中间数(偏移量)为什么不取128,而要取127呢?)因为8 位二进制位所能表示的无符号整型的范围为:0000 0000 (0) ~ 1111 1111 (255), 但是因为指数为全0 和全1 的情况要特殊用途,如下所述,所以实际可用的数要减去2 个,故可用的数的范围为1-254,但是我们的指数是有符号数,有正负之分因此我们必须将1-254 这254 个数平均分配表示正负的指数范围,因此,需要加入一个偏移量,有两种方案,一种是原指数偏移127 后在1-254 这个范围内,即实际的指数范围为[-126,127],其中下限-126=1-127  (偏移量),上限127=254-127  (偏移量),此时表示的数的绝对值范围为: 
       下限:
         0 0000 0001 111 1111 1111 1111 1111 1111  (指数为-126+127=1,小数部分全为1)
        =1.111 1111 1111 1111 1111 1111 1111 1111*2^(-126)

       上限:
       0 1111 1110 111 1111 1111 1111 1111 1111  (指数为127+127=254,小数部分全为1)
       = 1.111 1111 1111 1111 1111 1111 1111 1111*2^(127)

        边界为:[1.2*10^(-38) ~ 1.7*10^(38)]

如果采用128 位的偏移量,则实际指数的范围为[-127,126],  其中下限-127=1-128(偏移量),上限126=254-128  (偏移量),此时表示的数的绝对值范围为:
       下限:
         0 0000 0001 111 1111 1111 1111 1111 1111  (指数为-127+128=1,小数部分全为1)
        =1.111 1111 1111 1111 1111 1111 1111 1111*2^(-127) 
       上限:
       0 1111 1110 111 1111 1111 1111 1111 1111  (指数为126+128=254,小数部分全为1)
       = 1.111 1111 1111 1111 1111 1111 1111 1111*2^(126)

        边界为:[5.9*10^(-39) ~ 8.5*10^(37)]
       由上可见,采用127 的偏移量时,表示的数的上限要大于采用128偏移量时,我们当然是希望浮点数表示上限的范围越大越好,故IEEE采用了127 的偏移量。

相应的double类型的浮点数的指数偏移量采用了1023的偏移量




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值