代码如下
public class Test {
public static void main(String[] args) {
double a = 0.06;
double b = 0.01 + 0.05;
System.out.println(a == b);
}
}
// 输出
false
继续测试代码
public class Test {
public static void main(String[] args) {
double a = 0.06;
double b = 0.01 + 0.05;
System.out.println(a);
System.out.println(b);
System.out.println(a == b);
}
}
// 输出
0.06
0.060000000000000005
false
分析原因
类型 | 符号位 | 指数 | 小数 | 总长度 |
---|---|---|---|---|
float | 1 | 8 | 23 | 32 |
double | 1 | 11 | 52 | 64 |
浮点数在java中存储的形式决定了在java中,浮点数并不是精确的。
先举个简单的例子,算算1.0在double中是怎么存储的
1.0如何在double中存储
符号位:0 表示正数
指数:0 + 2047 (IEEE标准规定double加2047,float加127)
小数:0
变换成相应的长度,可以写为:
符号位:0
指数:011 1111 1111
小数:0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
整体为:
0011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0.1如何在double中存储
0.1可以写为
1.0100 0111 1010 1110 0001 0100 0111 1010 1110 0001 0100 0111 1011 * 2 ^ (011 1111 1000 - 2047)
符号位:0 表示正数
指数:011 1111 1000
小数:0100 0111 1010 1110 0001 0100 0111 1010 1110 0001 0100 0111 1011
整体为:0011 1111 1000 0100 0111 1010 1110 0001 0100 0111 1010 1110 0001 0100 0111 1011
可以发现0.1在double中并不是一个精确值,0.5同样也不是一个精确值,对于2进制来说,它们都是无限循环小数。
所以由于精度的原因,0.01 + 0.05 并不等于0.06