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
相关产品推荐
相关产品推荐

