浮点数详解(IEEE 754标准)

浮点数详解(IEEE 754标准)_第1张图片


【浮点数有关】
在计算机发展过程中,曾经提出过许多种实数的表达方法,比较典型的有浮点数,定点数两种

【定点数简介】
|| 在定点数表达法中,其小数点固定地位于实数所有数字中间的某个位置。例如,货币的表达就可以采用这种表达方式,如 55.00 或者 00.55 可以用于表达具有 4 位精度,小数点后有两位的货币值。由于小数点位置固定,所以可以直接用 4 位数值来表达相应的数值。

|| 但我们不难发现,定点数表达法的缺点就在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大的数或者特别小的数。因此,最终绝大多数现代的计算机系统都采纳了所谓的浮点数表达法。

【浮点数简介】
|| 浮点数表达法采用了科学计数法来表达实数,即用一个有效数字。一个基数(Base)、一个指数(Exponent)以及一个表示正负的符号来表达实数。比如,666.66 用十进制科学计数法可以表达为 6.6666×102(其中,6.6666 为有效数字,10 为基数,2 为指数)。浮点数利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数。

|| 当然,对实数的浮点表示仅作如上的规定是不够的,因为同一实数的浮点表示还不是唯一的。例如,上面例子中的 666.66 可以表达为 0.66666×103、6.6666×102 或者 66.666×101 三种方式。因为这种表达的多样性,因此有必要对其加以规范化以达到统一表达的目标。规范的浮点数表达方式具有如下形式:
在这里插入图片描述(其中,d.dd…d 为有效数字,β 为基数,e 为指数)

|| 有效数字中数字的个数称为精度,我们可以用 p 来表示,即可称为 p 位有效数字精度。

||十进制的基数 β 等于 10,每个数字 d 只能在 0 和 9 之间取值 , 二进制的 β 等于 2,而每个数字 d 只能在 0 和 1 之间取值。他们之间的转换关系式(在第二步进行了十进制的运算)
浮点数详解(IEEE 754标准)_第2张图片

|| 由上面的等式,我们可以得出:
1,向左移动二进制小数点一位相当于这个数除以 2,而向右移动二进制小数点一位相当于这个数乘2。如 101.11=3/4,而 10.111=7/8。
2,一个十进制小数要能用浮点数精确地表示,最后一位必为5(当然这是必要条件,并非充分条件)
可以使用程序证明:

#include 
int main(void)
{
    float f1=34.6;
    float f2=34.5;
    float f3=34.0;
    printf("34.6-34.0=%f\n",f1-f3);
    printf("34.5-34.0=%f\n",f2-f3);
    return 0;
}

|| 误差原理:因为计算机将二进制转换为十进制的浮点数时,若十进制浮点数尾数非5/0,会因为二进制数无法精确转化为该数而保存四舍五入的结果,故造成了误差,如下图:

浮点数详解(IEEE 754标准)_第3张图片

因此,建议不要将浮点数用于精确计算!!!
且建议不要将浮点数直接用 == 或 != 进行比较,尽量转换为><号

#include 
int main(void)
{
    float f1=34.7;
   	if(f1 - 34.7 < 0.001) 
    	printf("Right!");
	
	if(f1 == 34.7)
		printf("Right!");
	
    return 0;
}

【IEEE浮点数表示法】

|| 本质:IEEE 浮点数标准是从逻辑上用三元组{S,E,M}来表示一个浮点数 V 的,即 V=(-1)S×M×2E
在这里插入图片描述

  • 符号位 s(Sign)决定数是正数(s=0)还是负数(s=1),而对于数值 0 的符号位解释则作为特殊情况处理。

  • 有效数字位 M(Significand)是二进制小数,它的取值范围为 1~2-ε,或者为
    0~1-ε。它也被称为尾数位(Mantissa)、系数位(Coefficient),甚至还被称作“小数”。

  • 指数位E(Exponent)是 2 的幂(可能是负数),它的作用是对浮点数加权。

||(分析思路:位数 = =》 有效范围 = =》实际范围 )

【32位单精度浮点数详解】

Float
S--------E-------M
1位-----8位-----23位

M位:代表其精度,有效数字的个数有 2^ (23+1) = 16777216个,即二进制数的范围为(0,16777216) 化为十进制:10^ 7 < 16777216 < 10^8,所以说单精度浮点数的有效位数是7位

E位:代表其指数位:有效数字个数有 2^ 8 = 256个,即指数范围为(0,255)除去第一个和最后一个数字作为特殊值,有效指数的范围为(1,254),设置一个偏差值(2k-1-1)= -127 使之可以表示负指数,故实际指数范围(-126,127),可以代表127个正指数和126个负指数加1个零指数。

【64位双精度浮点数详解】

Double
S--------E-------M
1位-----11位----52位

M位:代表其精度,有效数字个数有*2^ (52+1) = 9007199254740992,又10^ 16 < 9007199254740992 < 10^17,所以双精度的有效位数是16位
E位:代表其指数位:有效数字个数有 2^ 11 = 2048个,即指数范围为(0,2047)除去第一个和最后一个数字作为特殊值,有效指数的范围为(1,2046),设置一个偏差值(2k-1-1)= 1023 使之可以表示负指数,故实际指数范围(-1022,1023),可以代表1023个正指数和11022个负指数加1个零指数。

|| 浮点异常值:NAN,QNAN,SNAN
这里所要说的浮点异常值就是这种IEEE浮点表示产生的几种特殊值,IEEE规定根据指数和尾数的不同分别可表示如下几种特殊值:

  1. 零值:按上述的浮点表述形式如果指数部分全部为0,并且尾数全部为0,则表示为浮点0.0,并且规定-0 = +0

  2. 非规格化值:如果指数全部为0,尾数非0,则表示非规格化的值,16进制看到的就是[80xxxxxx]h或者[00xxxxxx]h

  3. 无穷值:如果指数全部为1,尾数全部为0,则根据符号位分别表示正无穷大和负无穷大,16进制看到的就是[FF800000]h或者[7F800000]h

  4. NAN:如果指数全部为1,尾数非0,则表示这个值不是一个真正的值(Not A Number)。NAN又分成两类:QNAN(Quiet NAN)和SNAN(Singaling NAN)。
    QNAN与SNAN的不同之处在于,QNAN的尾数部分最高位定义为1,SNAN最高位定义为0;
    QNAN一般表示未定义的算术运算结果(技术NaN),最常见的莫过于除0运算;SNAN一般被用于标记未初始化的值 (信号NaN),以此来捕获异常。

你可能感兴趣的:(learning)