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)
在第二个或者第三个构造方法中,指定了当除不尽的时候,进行有效位数的保留,因此会比较安全。
在此推荐大家使用这个方法的时候 使用第三个方法,比较安全。