Java中Object转Double如何避免舍入?数值精度异常求助
问题根源与解决方案
为什么会出现这个错误?
double类型的有效精度仅为15-17位,你要存储的数值12334555578912349.13整数部分就有16位,加上小数部分后,double无法精确表示该数值,会自动将其转换为最接近的可存储近似值。此时你再把这个失真的double值转成BigDecimal,自然得不到预期结果。
解决方法
要避免精度丢失,必须跳过double中转,直接基于精确的字符串形式创建BigDecimal,因为字符串可以完整保留所有数字信息。
修正后的代码示例
如果你的num原本就是字符串形式(建议用这种方式存储高精度数值):
Object num = "12334555578912349.13"; BigDecimal result = new BigDecimal(num.toString()) .setScale(2, RoundingMode.HALF_EVEN); // 推荐使用枚举类替代旧常量 System.out.println(result);
如果num的类型不确定,可先做类型判断再处理:
Object num = "12334555578912349.13"; BigDecimal result; if (num instanceof String) { result = new BigDecimal((String) num) .setScale(2, RoundingMode.HALF_EVEN); } else if (num instanceof Number) { // 仅当数值在double精度范围内时使用此分支,否则仍会失真 result = BigDecimal.valueOf(((Number) num).doubleValue()) .setScale(2, RoundingMode.HALF_EVEN); } else { throw new IllegalArgumentException("不支持的数值类型"); } System.out.println(result);
注:BigDecimal.ROUND_HALF_EVEN是旧版常量,Java 1.5及以后推荐使用RoundingMode.HALF_EVEN枚举,语义更清晰。
内容的提问来源于stack exchange,提问作者Aleyna
相关产品推荐
相关产品推荐

