Java中BigDecimal,DateFormatter 和迭代器的"陷阱"

网友投稿 288 2022-07-25


前言:

使用 IDEA 创建一个 Maven 项目 calculate-date-traps 并导入 Junit 依赖。

junit

junit

4.12

test

在进行计费时使用 Double 和 Float 类型计算经常会出现丢失精度的情况,在 test 包下新建一个测试类 ScaleLostTest。

public class ScaleLostTest {

@Test

public void testDoubleLostScale(){

double alpha = 1;

double bravo = 20.2;

double charlie = 400.03;

System.out.println(alpha + bravo + charlie);

}

}

执行上述代码,输出结果如下 :

使用 Double 类型进行精确运算出现了精度问题。

代码中所使用的这些数最终都会转换成二进制,而浮点类型的数转换成二进制并不是精确地二进制,只能是最接近的二进制,这是应为浮点数是由指数和尾数两部分组成,所以在浮点数计算的过程中会出现丢失精度的问题。

如果恰巧计算结果的二进制能和十进制准确转换那么自然也就不会出现丢失精度的问题了。浮点数并不适合进行精确计算而更适合科学计算。而 BigDecimal 类型的核心就是精度,在 test 包下新建一个测试类 BigDecimalTest

public class BigDecimalTest {

@Test

public void testScaleException(){

BigDecimal bigDecimal = new BigDecimal("12138.121");

BigDecimal res = bigDecimal.setScale(2);

System.out.println(res);

}

}

执行上述代码,输出结果如下:

设置的精度既小数点的位数比原来小会报错。设置为5,会自动补上0,再次执行测试输出结果如下:

只想保留两位数字,如何解决?如何对原始数字进行舍入?BigDecimal支持的舍入方式有很多中,向上取整,向下取整,四舍五入等

@Test

public void testChangeScale(){

BigDecimal bigDecimal = new BigDecimal("12138.121");

BigDecimal res = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP);

System.out.println(res);

}

12138.128

测试其他舍入方式,除法运算,除不尽出现异常问题,除不尽,既无限循环的问题

@Test

public void testDivideException(){

BigDecimal d1 = new BigDecimal(10);

BigDecimal d2 = new BigDecimal(3);

System.out.println(d1.divide(d2));

}

@Test

public void testSolveDivideException(){

BigDecimal d1 = new BigDecimal(10);

BigDecimal d2 = new BigDecimal(3);

System.out.println(d1.divide(d2, 2, BigDecimal.ROUND_HALF_UP));

}

指定精度和舍入方式

总结:使用BigDecimal一定要指定保留小数点的位数和指定的舍入方式

精度问题导致结果比较不一致:

@Test

public void testCompare(){

BigDecimal d1 = new BigDecimal("0");

BigDecimal d2 = new BigDecimal("0.0");

System.out.println(d1.equals(d2));

System.out.println(d1.compareTo(d2));

}

equals()方法,精度不同直接返回false


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java模拟QQ实现聊天互动程序
下一篇:Java向上转型和向下转型的区别说明
相关文章

 发表评论

暂时没有评论,来抢沙发吧~