关于浮点数处理问题,BigDecimal的精度问题,BigDecimal增删查改操作,参考阿里巴巴Java开发手册规范处理
浮点数比较问题
浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用equals来判断。
问题:可以发现这两句都没有执行
public static void main(String[] args) {
float a = 1.0F - 0.9F;
float b = 0.9F - 0.8F;
if (a == b) {
System.out.println("未执行");
}
Float x = Float.valueOf(a);
Float y = Float.valueOf(b);
if (x.equals(y)) {
System.out.println("未执行");
}
}
这里阿里巴巴JAVA开发手册 [^1]中也有提到
解决
指定一个误差范围,两个浮点数的差值在此范围之内,则认为是相等的
float a =1.0F-0.9F; float b =0.9F-0.8F; float diff =1e-6F; if(Math.abs(a -b)<diff){ System.out.println("执行"); }
使用BigDecimal来定义值,再进行浮点数的运算操作(推荐使用)
BigDecimal a = new BigDecimal("1.0"); BigDecimal b = new BigDecimal("0.9"); BigDecimal c = new BigDecimal("0.8"); BigDecimal x = a.subtract(b); BigDecimal y = b.subtract(c); if (x.compareTo(y) == 0) { System.out.println("执行"); }
比较时候使用compareTo进行比较,equals()方法会比较值和精度(1.0与1.00返回结果为false),而compareTo()则会忽略精度,使用下面代码进行测试发现只有compareTo执行了。
BigDecimal x = new BigDecimal("0.1"); BigDecimal y = new BigDecimal("0.10"); if(x.equals(y)) { System.out.println("未执行!"); } if(x.compareTo(y) == 0) { System.out.println("执行!"); }
BigDecimal初始化
初始化时应该使用字符串的形式进行初始化定义,对比一下他们的区别
BigDecimal a = new BigDecimal(0.1F);
BigDecimal b = new BigDecimal("0.1");
System.out.println(a);
System.out.println(b);

两种方式定义的值不一样,BigDecimal(double)存在精度损失风险,这里阿里巴巴Java开发手册 [^1]中也有提及

BigDecimal增删查改操作
public static void main(String[] args) {
BigDecimal a = new BigDecimal("0.123");
BigDecimal b = new BigDecimal("0.987");
BigDecimal c = new BigDecimal("-0.555");
// 加
BigDecimal add = a.add(b);
// 减
BigDecimal subtract = a.subtract(b);
// 乘
BigDecimal multiply = a.multiply(b);
// 除,设置保留的小数点位数与四舍五入
BigDecimal divide = a.divide(b, 20, BigDecimal.ROUND_HALF_UP);
// 绝对值
BigDecimal abs = c.abs();
System.out.println(add);
System.out.println(subtract);
System.out.println(multiply);
System.out.println(divide);
System.out.println(abs);
}
除法中的第二个参数是设置保留的小数点位数,第三个参数是设置如何进行四舍五入操作,阅读源码可知就是我们的平时使用的大于等于0.5时候就进一位。

运行结果
BigDecimal还有一些其它操作,可以去操作尝试下
阿里JAVA开发手册地址
版权声明:本文为weixin_44750617原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。