这几天老是抛出一个问题,就是关于JAVA中float数据类型的精度和存储的。
首先是关于float最常见的1.0f==0.99999999f,返回值为true,这个问题我判断的是0.99999999超出JAVA规定的7~8位有效数字范围了,最后一位9四舍五入,所以0.99999999四舍五入之后为1.0,所以转化成二进制数后和1.0f咦比较,返回值为true,但是四舍五入这个说法,在第二天又说不通了。问题如下
将1.0f转换成二进制
将0.99999999f转换成二进制
将0.9999999f转换成二进制
将0.99999998f转换成二进制
将0.99999997f转换成二进制
将0.999999999f转换成二进制
这是我在JAVA中测试的,分别计算以上数据的二进制数,结果如图:
我很奇怪,为什么这里0.99999997的二进制竟然和1.0f不一样。不一样就说明之前的四舍五入方法是错误的,我也在网上找了很多,但是都没有找到JAVA在0.99999997这个数据的二进制转换时是怎么处理的?我测试了,只要大于0.99999997就会得到和1.0f一样的结果。我用计算机组成原理的标准来做了之后,得到的数字也不一样。所以希望有知道的大佬,麻烦还请将0.99999997二进制转换的每一步过程详细解析一下!我们共同学习!
浮点数之间比较不能用等号,计算机将浮点数从10进制转换成2进制是存在误差的,所以建议用
f1-f2>0.0000001这种方式去比较好点
这个遵循 ieee754 浮点数的标准
一个浮点数首先分成 符号 阶码 尾数 三个部分
其中阶码没有符号,相当于是平移过来的,而尾数相当于把这个数字平移到0~1之间的小数
具体转换:https://www.cnblogs.com/zjujunge/archive/2012/09/13/2682613.html
浮点数在硬件软件的实现和转换中存在误差,所以即便你有一个精确值,表示出来不一样也很正常。