浮点数表示

1.浮点数由以下三部分组成:

  符号位

  指数位(阶码)

  尾数

2.其规范如下:

float遵从的是IEEE R32.24 ,而double 遵从的是R64.53。

需要注意到地方有: 在float 由于科学计数法都表示1.xxx 所以23位的尾码可表示24位 ,double同理,52位尾码实际表示53位

故在float中  符号位 1 , 指数位8 , 尾数 23位(实际表示24)

在double中 符号位1, 指数位11,尾数位 52(实际表示53)

由于 二进制并不能表示十进制所有的整数,有时只是近似表示,所以,进行类型转换时就可能会出现数值不一致。

3.具体如何表示:

可参考如下文章:

https://zhuanlan.zhihu.com/p/63897066

移位存储详解

https://cloud.tencent.com/developer/article/1177204

关于float 数值不一致问题,思考方式如下:

1.其实,对于浮点数,对它们进行真正的比较时使用的是机器码,如果两个数的机器码完全一致,那么它们就是相等的。

1.所以,对于同一个数,它们一定是会相等的,因为即使是近似表示,它们的机器码也都是取相同的近似值

2.对于单浮点和双浮点数,java对其显示时,通常都是格式化显示(即只显示部分,截取型),这时你就会发现,即使拿打印出的数值和该数值比较有时也是不相等的,其原因就是打印值不等于机器码代表的完整的值。

    我们可以通过printf("%.LEGTH f", NUM) 来显示该浮点数的完整值,也即机器码对应的完整的值。 对于float 24尾数 1 / 2 ^24 ,所以我们应该保证从第一位非零数值起,打印出 其后9 位 小数(粗略估计哈,保证不错),多打印几位也没啥,你会发现后面都是0,这样我们看到的才是才是机器码对应的完整的值,我们拿该打印值与原值比较也一定是相等的。

    对应于 double 1 / 2^53 ,应该保证从第一位非零数值起其后打印出 17位 小数. 

  

  

原文地址:https://www.cnblogs.com/yzw-daemon/p/13461329.html