浮点数
浮点数家族:float , double , long double
浮点数的表示范围:float.h中定义
常见的浮点数:3.14159,1e3
根据国际标准IEEE(电器和电子工程协会)754,任意一个二进制浮点数V可以表示成下面这种形式:
- (-1)^S * M * 2^E
- (-1)^S表示符号位。当S=0,V位整数;当S=1,V位负数
- M 表示有效数字,大于等于1,小于2
- 2^E表示指数位
举个栗子:
1.IEEE754规定:
对于32位的浮点数,最高一位为S,接着的8位是指数E,剩下的23位为有效数字M。
对于64位双精度数,最高一位为S,接着的11位是指数E,剩下的52位为有效数字M。
2..IEEE754对有效数字M和指数位数E的规定是这样的:
先说M:
前面说过,1<=M<2,M总是可以写成1.×××××× (因为十进制的数转成二进制了,第一位1总不是0),于是M在存储时就只存小数点后面的就可以了。比如,1.01在存储时就只存01就可以;1.100101存100101;(不可能出现0.10101这样的,这样的数小数点还可以向后移,也不可能出现0.5这样的,因为是二进制嘛)这样做就可以节省一个比特位,使有效数字的位数多出一位,等到读取的时候,再把第一位的1加上去就可以啦。
再说E:
1.首先,E为一个无符号整数(unsigned int),这就意味着,如果E占8位,它的取值就是0~255;如果E占11位,它的取值就是0~2047。但是我们知道,科学计数法中指数E是可以为负数的,所以IEEE就规定,存入内存时,E的真实值必须加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023;
举个栗子:
2^10中E的值是10,所以保存浮点数时,E就存的不是10,而是10+127 = 137;换算成二进制就是 1000 1001(0111 1111
+ 0000 1010 = 1000 1001(127+10=137))
2.然后,E再分为3种情况:
a.E不全是0 或 E不全为1
这时,浮点数就采用下面的规则表示,即E的计算值要减去127(或1023),得到它的真实值,再将有效数M前加上第一位的1
比如:0.5的二进制形式为0.1,由于第一位必须是1,就可以将小数点右移一位变成1.0,于是它的形式就是:(-1)^0 * 0 * 2^(-1),则这时的E就应该是(-1)+127 = 126,换成二进制是(0111 1110)而M去掉第一位的1是0,则float类型的 0.5在内存中是指这样存储的(32位):
b.E全为0
这时,浮点数的指数E等于1-127(或1-1023)即为真实值,有效数字M不再加上第一位,而是还原为0.××××××的小数,这样做是为了表示±0,和很接近0 的数。
c.E全为1
这时,如果有效数字M全为0,表示±无穷大,是正还是负取决于S
相关阅读
1、精度丢失 作为程序员大家应该都遇到过下面这种情况,用浮点数做运算,发现结果与预期有偏差,比如下面的JAVA代码 public static