返回顶部
首页 > 资讯 > 后端开发 > Python >Java中BigDecimal,DateFormatter 和迭代器的"陷阱"
  • 640
分享到

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

2024-04-02 19:04:59 640人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

前言: 使用 idea 创建一个 Maven 项目 calculate-date-traps 并导入 Junit 依赖。 <dependency> <gro

前言:

使用 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);
    }
}

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

 使用 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

到此这篇关于Java中BigDecimal,DateFORMatter 和迭代器的"陷阱"的文章就介绍到这了,更多相关java 迭代器陷阱内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java中BigDecimal,DateFormatter 和迭代器的"陷阱"

本文链接: https://lsjlt.com/news/151067.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作