You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Double类型数值末尾莫名追加0:存库需保留3位小数遇异常

解决Double类型保留3位小数后转回仍出现多余位数的问题

这个问题我太熟了——本质上是踩了浮点数精度的坑!咱们先拆解问题根源,再给你靠谱的解决方案:

为什么会出现0.001变成0.0010的情况?

Double这类浮点数是基于二进制存储的,很多十进制小数(比如0.001)在二进制里是无限循环的近似值,并不是精确的0.001。当你把格式化后的字符串转回Double时,它又会回到那个近似的二进制存储状态,看起来就像是多了一位小数,其实是浮点数本身的精度特性导致的。

正确的解决方案:用BigDecimal替代Double

要精确处理十进制小数(尤其是涉及金额、需要固定小数位数的场景),永远优先用BigDecimal,它专门为精确的十进制运算设计,能完美解决你的问题。

示例代码:

// 初始化时用字符串构造,避免Double转BigDecimal的精度损失
BigDecimal amount = new BigDecimal("0.001");

// 强制保留3位小数,这里用HALF_UP(四舍五入),你可以根据需求换其他舍入模式
amount = amount.setScale(3, RoundingMode.HALF_UP);

// 存入数据库时直接用BigDecimal类型即可,数据库字段建议用DECIMAL(10,3)这类精确类型

如果你的amount是从其他地方(比如接口参数)来的Double,别直接转BigDecimal,先转成字符串再构造:

Double originalDouble = 0.001;
BigDecimal amount = new BigDecimal(String.valueOf(originalDouble))
    .setScale(3, RoundingMode.HALF_UP);

如果不得不使用Double(不推荐)

如果因为某些限制必须用Double,那不要依赖Double的数值展示,而是在存入数据库时:

  • 用DecimalFormat格式化得到正确的3位小数字符串
  • 把这个字符串转成BigDecimal后再存入数据库(或者直接让数据库字段用DECIMAL类型,插入时传格式化后的字符串)
  • 数据库字段一定要用DECIMAL(精度, 3),而不是DOUBLE,从存储层面保证精度

关键提醒

永远不要用Double来处理需要精确小数位数的业务场景(比如金额、计价),浮点数的精度误差会给你带来各种意想不到的问题,BigDecimal才是正确的选择。

内容的提问来源于stack exchange,提问作者Manjunath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:20:47