在工作中,我们在尝试将大数除以1000时发现了一个问题.这个数字来自数据库.
说我有这个方法:
private static BigDecimal divideBy1000(BigDecimal dividendo) {
if (dividendo == null) return null;
return dividendo.divide(BigDecimal.valueOf(1000), RoundingMode.HALF_UP);
}
Run Code Online (Sandbox Code Playgroud)
当我拨打以下电话时
divideBy1000(new BigDecimal("176100000"))
Run Code Online (Sandbox Code Playgroud)
我收到176100的预期值.但是,如果我尝试下面这一行
divideBy1000(new BigDecimal("1761e+5"))
Run Code Online (Sandbox Code Playgroud)
我收到价值200000.为什么会这样?这两个数字是相同的,具有不同的表示,最新的是我从数据库收到的.我知道,不知何故,JVM将数字1761除以1000,向上舍入并在最后填充0.
避免这种行为的最佳方法是什么?请记住,原始号码不受我控制.
dce*_*chi 21
如javadoc中所指定的,a BigDecimal
由整数值和比例定义.
因此,BigDecimal表示的数字的值是(unscaledValue×10 ^( - scale)).
因此,BigDecimal("1761e+5")
具有规模经济-5和BigDecimal(176100000)
有刻度0.
两者的划分BigDecimal
分别使用-5和0标度来完成,因为在划分时没有指定标度.该divide
文档解释了为什么结果是不同的.
divide
Run Code Online (Sandbox Code Playgroud)public BigDecimal divide(BigDecimal divisor)
返回
BigDecimal
其值为(this / divisor)
,其首选比例为(this.scale() - divisor.scale())
; 如果无法表示确切的商(因为它具有非终止的十进制扩展),ArithmeticException
则抛出一个.参数:
divisor
- 要分割此BigDecimal的值.返回:
Run Code Online (Sandbox Code Playgroud)this / divisor
抛出:
ArithmeticException
- 如果确切的商没有终止十进制扩展以来:
1.5
如果在分割时指定刻度,例如,dividendo.divide(BigDecimal.valueOf(1000), 0, RoundingMode.HALF_UP)
您将得到相同的结果.
表达new BigDecimal("176100000")
和new BigDecimal("1761e+5")
是不相等的.BigDecimal
跟踪价值和精确度.
BigDecimal("176100000")
有9位精度,在内部表示为BigInteger("176100000")
,乘以1. BigDecimal("1761e+5")
有4位精度,内部表示为BigInteger("1761")
,乘以100000.
当您将a BigDecimal
除以一个值时,结果会考虑精度的数字,从而导致看似相等的值的不同输出.
小智 6
使用 BigDecimal 进行除法。
dividendo.divide(divisor,2,RoundingMode.CEILING)//00.00 nothing for up and nothing for down
Run Code Online (Sandbox Code Playgroud)
在此操作中,精度为两位小数。
归档时间: |
|
查看次数: |
23080 次 |
最近记录: |