今天在读《Java开发手册》时,看到浮点数的等值判断问题「浮点数的基本数据类型不能用 ==
比较,包装数据类型不能用 equals
比较」。以前开发时也遇到过浮点数的坑,所以就想一探究竟。
1. 浮点数表示
在计算机系统理论中,浮点数采用 IEEE 754 标准表示,编码方式是符号+阶码+尾数,如图:
浮点数表示
比如 float 类型占用 32 位,单精度浮点表示法:
- 符号位(sign)占用 1 位,用来表示正负数,0 表示正数,1 表示负数
- 指数位(exponent)占用 8 位,用来表示指数,实际要加上偏移量
- 小数位(fraction)占用 23 位,用来表示小数,不足位数补 0
从这里可以看出,指数位决定了大小范围,小数位决定了计算精度。当十进制数值转换为二进制科学表达式后,得到的尾数位数是有可能很长甚至是无限长。所以当使用浮点格式来存储数字的时候,实际存储的尾数是被截取或执行舍入后的近似值。这就解释了浮点数计算不准确的问题,因为近似值和原值是有差异的。
更详细的介绍可以查阅 java浮点类型float和double的主要区别,它们的小数精度范围大小是多少? - Boss呱呱的回答 - 知乎。
2. 比较浮点数的方式
让我们来验证一下比较浮点数的几种方式。
1. ==
操作符
比较两个浮点数,一个从零开始加 11 次 0.1,另一个用 0.1 乘以 11 计算。然后用 ==
比较大小。
参考文章
作者:落英坠露
链接:https://www.jianshu.com/p/4679618fd28c
来源:简书