相同数值的double和float类型比较结果为false
float f1 = 0.2f;
double d1 = 0.2d;
System.out.println(f1 == d1);
System.out.println((float)d1);
System.out.println((double)f1);
输出结果
false
0.2
0.20000000298023224
我们知道计算机是以二进制进行存储数据,当我们传入10进制的小数时,计算机会将十进制的小数转换为二进制的小数,但是有些小数不能精确转换,于是就转换为无限趋近于十进制数值的二进制小数了
由于比较的数据类型不同,所以在比较时会进行类型转换,会出现精度差,所以结果为false
float fa = 8964568f;
System.out.println("fa===="+fa);
float fb = fa + 1;
System.out.println("fb===="+fb);
System.out.println(fa == fb);
System.out.println("----------------------");
float fa2 = 89645688f;
System.out.println("fa2---"+fa2);
float fb2 = fa2 + 1;
System.out.println("fb2---"+fb2);
System.out.println(fa2 == fb2);
输出结果
fa====8964568.0
fb====8964569.0
false
----------------------
fa2---8.9645688E7
fb2---8.9645688E7
true
float的精度只有7位,超过的话就用科学计数法表示
fa是8964568为7位数,加1是8964569还是7位数,直接比较为false
fa2是89645688为8位数用科学计数法表示为8.9645688E7,加1是89645689用科学计数法表示为8.9645688E7,两次用科学计数法表示一样,所以结果为true
解决精度丢失
由于某些情况下数值相加和没相加时的数值相等,所以在一些银行、财务等不能有精确度丢失的地方,不能使用浮点数,改为使用BigDecimal
//创建BigDecimal对象传入数值,以String类型传入数字确保精度进度不会丢失
BigDecimal bigDecimal = new BigDecimal("0.00000001");
/*创建具有指定精度和舍入方式的MathContext对象
* setPrecision 指定非负数的int类型精度
* RoundingMode 舍入方式 四舍五入等
* */
MathContext mathContext = new MathContext(8, HALF_UP);
float ff = 0.12345678f;
BigDecimal result = bigDecimal.add(new BigDecimal(Float.toString(ff)),mathContext);
System.out.println(result);
输出结果
0.12345679