美文网首页
float小记

float小记

作者: anliner | 来源:发表于2021-01-26 10:00 被阅读0次

    c中不管32位还是64位机,float所占字节均为4字节,即32位,根据IEEE R32.24标准,float在内存中的存储格式为1位符号位,8位指数位,23位尾数位。

    其中指数位算数取值范围为[0 ~ 255],但根据IEEE754标准,全0和全1分表代表浮点数0和浮点数无穷,被舍去,即0和255被舍去,所以范围变成[1 ~ 254],由于这是一整个数的一部分,不区分符号位,所以为了表示正负数,设立了偏移量,根据有符号8位取值范围[-127 ~ -0,0 ~ 127]去掉全0和全1变成[-126 ~ 127]得到偏移量为127,这样1即为-126,126即为-1。

    由于浮点数在内存中是按科学计算法存储的,即 6.125 => 0b110.001 => 0b1.10001 * 22 ,由于任何浮点数都可以按1.x···x * 2n 表示,所以这里的个位数1就可以隐藏,所以23位尾数位就可以全部表示科学计数里的小数位,那么float可表示的最大绝对值数为 0b1.11111111111111111111111 * 2127,即为 (0b10 - 0b0.00000000000000000000001) * 2127 ,即 (2 - 2-23) * 2127 ,而 2 - 2-23 约等于2,即为 2128 ,所以初步计算,float范围为[-2128 ~ 2128]。
    又由于指数位最小为-126,尾数位最小为全0,则float可表示的最小绝对值数为 0b1 * 2-126 ,即为 2-126 ,所以float取值范围为 [-2128 ~ -2-126,2-126 ~ 2128] 。

    对于float精度,由于隐藏位始终为1,不作考虑,那么23位二进制数最多能表示8388607个数字,想再多表示一些数字,就会越位,一旦数字超出23位,存储时就意味着丢失精确值,使用的是近似值,这也就是为什么float数值到一定程度时是跳跃的,例如十进制1.2 转二进制为 0b1.00110011001100110011001(0011无限循环),这时候再转成十进制就变成了1.19999992847442627这个值,从这个例子也可以看出,位数越多,才能越无限趋近于1.2,23位所表示的趋近于1.2的精度也就7位,所以结合8388607这个数字以及更多的例子就可以得出float所能表示的十进制数最大精度为7位的结论。

    关于指数位全0和全1,分别称为“非规格化值”和“特殊值”,其他为“规格化值”。
    非规格化值:一方面用于表示0,另一方面表示接近于0的数。因为规格化值默认隐藏个位数1,所以表示是 [1~2) 范围内的数,所以指数位全0时无隐藏个位数1,或认为个位数是0。且指数位和尾数位全0时,根据符号位不同,区分-0.0和+0.0。
    特殊值:当尾数位全0,根据符号位不同分别表示正无穷和负无穷;当尾数位不是全0,表示NaN。

    相关文章

      网友评论

          本文标题:float小记

          本文链接:https://www.haomeiwen.com/subject/gkfizktx.html