快捷搜索:  汽车  科技

arraylist为什么不能用迭代器修改(你有没有掉进去过这些)

arraylist为什么不能用迭代器修改(你有没有掉进去过这些)public class BigDecimalTest { @Test public void testScaleException(){ BigDecimal bigDecimal = new BigDecimal("12138.121"); BigDecimal res = bigDecimal.setScale(2); System.out.println(res); } } 复制代码执行上述代码,输出结果如下:在 test 包下新建一个测试类 BigDecimalTest代码中所使用的这些数最终都会转换成二进制,而浮点类型的数转换成二进制并不是精确地二进制,只能是最接近的二进制,这是应为浮点数是由指数和尾数两部分组成,所以在浮点数计算的过程中会出现丢失精度的问题。如果恰巧计算结果的二进制能和十

arraylist为什么不能用迭代器修改(你有没有掉进去过这些)(1)

一、BigDecimal

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

<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> 复制代码

在进行计费时使用 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); } } 复制代码

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

arraylist为什么不能用迭代器修改(你有没有掉进去过这些)(2)

使用 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); } } 复制代码

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

arraylist为什么不能用迭代器修改(你有没有掉进去过这些)(3)

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

arraylist为什么不能用迭代器修改(你有没有掉进去过这些)(4)

只想保留两位数字,如何解决?如何对原始数字进行舍入?

BigDecimal支持的舍入方式有很多中,向上取整,向下取整,四舍五入等

@Test public void testChangeScale(){ BigDecimal bigDecimal = new BigDecimal("12138.121"); BigDecimal res = bigDecimal.setScale(2 BigDecimal.ROUND_HALF_UP); System.out.println(res); } 复制代码

arraylist为什么不能用迭代器修改(你有没有掉进去过这些)(5)

12138.128

arraylist为什么不能用迭代器修改(你有没有掉进去过这些)(6)

测试其他舍入方式

除法运算,除不尽出现异常问题

除不尽,既无限循环的问题

@Test public void testDivideException(){ BigDecimal d1 = new BigDecimal(10); BigDecimal d2 = new BigDecimal(3); System.out.println(d1.divide(d2)); } 复制代码

arraylist为什么不能用迭代器修改(你有没有掉进去过这些)(7)

@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)); } 复制代码

arraylist为什么不能用迭代器修改(你有没有掉进去过这些)(8)

指定精度和舍入方式

总结,使用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)); } 复制代码

arraylist为什么不能用迭代器修改(你有没有掉进去过这些)(9)

arraylist为什么不能用迭代器修改(你有没有掉进去过这些)(10)

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

来源:https://juejin.cn/post/7107267911537917959

猜您喜欢: