Java BigDecimal.doubleValue()在14与15位小数时的行为差异解惑
为什么BigDecimal.doubleValue()返回不同结果?
要搞懂这个问题,核心得先明确double类型是IEEE 754标准的双精度浮点数,它的精度是有限的:用64位存储数据,其中52位作为尾数(加上隐含的1位,总共53位有效二进制精度),换算成十进制的话,大概能精确表示15到17位有效数字。当调用BigDecimal.doubleValue()时,会把BigDecimal的数值舍入到最接近的、double能表示的数值。
逐个分析你的例子:
对于
bd1 = new BigDecimal("38.399999999999999"):
这个数的十进制有效数字是17位(2位整数+15位小数),刚好触碰到double精度的上限。实际上,这个数和38.4之间的差值,已经小于double能区分的最小单位(ULP,Unit in the Last Place)——也就是说,double无法分辨这两个数的差异,所以转成double时会被舍入到更接近的可表示值38.4。对于
bd2 = new BigDecimal("38.39999999999999"):
这个数的十进制有效数字是16位,处于double的有效精度范围内。它和38.4之间的差值大于对应数值的ULP的一半,double可以明确区分这两个数,因此转成double时就保留了原数的表示38.39999999999999。
本质上就是double的精度限制导致的:它只能表示有限的十进制小数,当BigDecimal的数值处于精度边界时,就会出现不同的舍入行为,最终得到不同的结果。
内容的提问来源于stack exchange,提问作者lospalos
相关产品推荐
相关产品推荐

