浮点数

简介:

由于进制的关系,十进制下的大多数小数,在二进制下无法完美的表示,只能表示为无限循环小数。

比如0.5可以表示为0.1,0.4则只能表示为0.011001100110......

十进制小数转换成二进制小数的方法,可以通过对小数部分乘2法来实现,

比如:0.4

0.4   *2    0.8

0.8   *2    1.6

0.6   *2    1.2

0.2   *2    0.4

取乘积的整数部分,得到,0.0110的无限循环。

还有一种方法就是把0.4看出2/5即2除以5,即10/101,通过除法运算也可以得到相同的值。

因此计算机有限的内存注定无法表示无限的循环小数,只能使用近似值代替。32位和64位的表示方法如下:

clipboard

其中阶码的值用移码表示,移码是符号位取反的补码,[X]移与[X]补的关系是符号位互为相反数(仅符号位不同)。

还需要注意的是,该阶码值需要减去偏移值127后才是正真的指数值,偏移值通常为2e-1 - 1,其中的e为阶码的长度。以单精度浮点数为例,它的指数域是8个比特,固定偏移值是28-1 - 1 = 128?1 = 127

在表示浮点数的时候,我们总是确保最高位是1,如果是0的话,则乘以2^n,即左移n位变成1。

因此23位的尾数可以表示24位有效数字。这种简化浮点数表示的操作称之为规格化。规格化后的数据都是如下格式

±1.xxxxxx*2^E

1.1010001*2^10100 表示成32位时,阶码需要加上127

 0001 0100

+0111 1111

——————

 1001 0011

因此,当浮点数是正数的时候,最小值的编码如下:

clipboard[1]

阶码为0-127=127,小数部分为1,因此该值表示 2^-127

clipboard[2]

阶码为255-127=128,小数部分为1.11111111111111111111111(正数部分为1,小数部分23个1),因此该值表示 (2-2^-23)*2^128

1.11111111111111111111111=2-2^-23,这个等式让我一开始也愣了下,想了下有多种方式证明。

1.11111111111111111111111=2^0+2^-1+2^-2+2^-3+2^-4………………+2^-22+2^-23

等比数列求和公式     
clipboard[3]

a1=1,q=1/2, n=24

因此最终的结果等于2-2^-23

    

还有一种计算方式

1.11111111111111111111111=10-0.000000000000000000000001

二进制表示即为2-2^-23

同理,最高位如果改成1的话,表示负数。因此浮点数的取值范围为:

[- (2-2^-23)*2^128,-2^-127] 和 [2^-127, (2-2^-23)*2^128] 换算成十进制则为   
clipboard[4]

如该数轴的显示,其他区域将会导致溢出。实际上,这个浮点数在数轴上并不是连续的,只能是一个十分接近的近似值,但这个近似值已足够满足一般的应用了。

上述浮点数的表示只是一种通常的解释方式,实际使用中有会有部分改进,比如上述的浮点数没法表示真正的0。

目前使用最广泛的浮点数的表示方法是IEEE 754标准所定义的,该标准定义了32位单精度和64位双精度。

IEEE754标准定义了一些特殊值。如下图所示,摘自维基百科

clipboard[5]

逐行解释:

1.正零和负零,除去符号位,所有的数都为0的情况,认为是±0。这个0是一个精确值。

2.当指数是0111 1111=127时,减去偏移量127,即实际指数为0,尾数全零,默认的小数点前的数字是1,所以这种情况认为是±1.0

3.当指数域为0,尾数位非0时,认为是非规格化的数。规格化的数字,默认认为小数点前是1,而非规格化的数字,默认认为小数点前的数字是0。

  并且,当数字是非规格化时,规定偏移量比原先大1,变成了-126。

4.指数域不为0,为规格化的数字,此时尾数域默认小数点前的数字是1,最小的规格化的数字的实际指数为1-127=-126,即最小的规格化数字为±2^-126

5.指数最大不能为255,255为保留值,只能是254,因此,实际指数值为254-127=127。最大的规格化的数字即1.11111111111111111111111(二进制)^127

6.指数域全1,尾数域全0,表示正负无穷。

7.指数域全1,尾数域不为0,是非法的浮点数。

以上规则,总结如下:

形式 指数 小数部分
0 0
非规约形式 0 非0
规约形式 1-254 任意
无穷 255 0
NaN 255 非零

引入非规约形式的浮点数是很有必要的有效可以使用的,只是它们的绝对值已经小于所有的规约浮点数的绝对值;即所有的非规约浮点数比规约浮点数更接近0。

clipboard[6]

它填补了一部分空隙,使得数字更均匀覆盖数轴,非规格化数字的使用,称之为逐级下溢,如果不采用这种方式,那么绝对值最小的规约浮点数与0的距离是相邻的小浮点数之间距离的2^23倍!可以说是非常突然的下溢出到0。这种情况的一种糟糕后果是:两个不等的小浮点数X与Y相减,结果将是0.

根据之前列出的IEEE754中的一些特殊值,可以看出,32位浮点数值的取值范围-3.4 × 10^38 到 +3.4 × 10^38

参考资料

《计算机组成与体系结构》

https://zh.wikipedia.org/wiki/IEEE_754
















本文转自cnn23711151CTO博客,原文链接: http://blog.51cto.com/cnn237111/1758841,如需转载请自行联系原作者



相关文章
|
8天前
|
C语言
|
9月前
浮点数的世界 0.1 + 0.2 = 0.30000000000000004?
今天看到一个有趣的新闻,浮点数计算导致的灾难,借此机会再理解一下浮点数的原理。
71 1
|
10月前
|
存储 Java
详解浮点数
1.什么是浮点数 在计算机系统的发展过程中,曾经提出过多种方法表示实数,但是到为止使用最广泛的是浮点表示法。浮点表示法,即用浮点数来表示实数,所谓浮点数,意思是小数点的位置不是固定的,是可以浮动的。浮点数采用IEEE 754这个标准作为统一的标准。该标准中严格定义个浮点数的表示格式、转化过程。 下面简单介绍一下IEEE 754标准。 IEEE 754的核心就是用科学计数法来表示实数,然后将表示结果转为二进制的方式,方便计算机存储。
291 0
|
存储
5.6.1_浮点数的表示
计算机组成原理之浮点数的表示
235 0
5.6.1_浮点数的表示
06:浮点数向零舍入
06:浮点数向零舍入
175 0
|
存储
浮点数的表示方法
浮点数的表示方法
65 0
浮点数的表示方法
|
存储 开发者
浮点数| 学习笔记
快速学习浮点数。
78 0
C#浮点数问题
C#浮点数问题
90 0
C#浮点数问题