Java的BigDecimal容易出现的坑

Wesley13
• 阅读 650

BigDecimal一般是用来做要求比较高的精准计算的。前几天在使用的时候遇到一个大坑,记录下。

这个问题产生是使用BigDecimal做除法(divide)运算,这个类的divide方法存在三个常用的构造函数。

BigDecimal

**divide**(BigDecimal divisor) 
          Returns a BigDecimal whose value is (this / divisor), and whose preferred scale is (this.scale() - divisor.scale()); if the exact quotient cannot be represented (because it has a non-terminating decimal expansion) an ArithmeticException is thrown.

[BigDecimal](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fmath%2FBigDecimal.html)

**[divide](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fmath%2FBigDecimal.html%23divide%28java.math.BigDecimal%2C%2520int%29)**([BigDecimal](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fmath%2FBigDecimal.html) divisor, int roundingMode) 
          Returns a BigDecimal whose value is (this / divisor), and whose scale is this.scale().

[BigDecimal](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fmath%2FBigDecimal.html)

**[divide](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fmath%2FBigDecimal.html%23divide%28java.math.BigDecimal%2C%2520int%2C%2520int%29)**([BigDecimal](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fmath%2FBigDecimal.html) divisor, int scale, int roundingMode) 
          Returns a BigDecimal whose value is (this / divisor), and whose scale is as specified.

在第一个构造方法中,可以只传入被除数(divisor)。但是调用这个方法极容易出现一个错误,当除不尽时候,会产生无限循环小数,这时将会抛出异常:

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

at java.math.BigDecimal.divide(BigDecimal.java:1690)

在第二个或者第三个构造方法中,指定了当除不尽的时候,进行有效位数的保留,因此会比较安全。

在此推荐大家使用这个方法的时候  使用第三个方法,比较安全。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Java中的浮点数四舍五入到小数点后2位的几种方法
前言四舍五入到2或3个小数位是我们Java程序员日常开发中肯定会遇到。幸运的是,JavaAPI提供了几种在Java中舍入数字的方法我们可以使用Math.round(),BigDecimal或DecimalFormat将Java中的任何浮点数四舍五入到n个位置。我个人更喜欢使用BigDecimal在Java中四舍五入任何数字,因为它具有便捷的API并
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
java浮点型精度丢失浅析
java浮点型数值在运算中会出现精度损失的情况,在业务要求比较高比如交易等场景,一般使用BigDecimal来解决精度丢失的情况。最近一个同事在使用BigDecimal时仍然出现了精度损失,简略记录一下测试用例代码如下@Testpublicvoidfd(){doubleabc
Wesley13 Wesley13
2年前
java.math.BigDecimal类的用法
在java中提供了大数字的操作类,即java.math.BinInteger类和java.math.BigDecimal类。这两个类用于高精度计算,其中BigInteger类是针对大整数的处理类,而BigDecimal类则是针对大小数的处理类。下边我们介绍BigDecimal类:BigDecimal的实现利用到了BigInteger,不同的是Big
Wesley13 Wesley13
2年前
java精确计算工具类
java精确计算工具类importjava.math.BigDecimal;importjava.math.RoundingMode;importjava.math.BigDecimal;importjava.text.DecimalFormat;importorg.springfram
Wesley13 Wesley13
2年前
Java 的BigDecimal
原文:http://blog.csdn.net/diyu122222/article/details/76887382decimaldecimal(18,0)18是定点精度,0是小数位数。decimal(a,b)a指定指定小数点左边和右边可以存储的十进制数字的最大个数,最大精度38。b指定小数点右边可以存储的十
Stella981 Stella981
2年前
BigDecimal与Long、int之间的相互转换
在实际开发过程中BigDecimal是一个经常用到的数据类型,它和int、Long之间可以相互转换。转换关系如下代码展示:一、int转换成BigDecimal数据类型//int转换成bigDecimal类型publicstaticBigDecimalintToBigDecim
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这