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

Java中使用DecimalFormat保留两位小数的舍入异常问题

Double类型四舍五入精度问题解决

问题根源

Double是二进制浮点数类型,50.275这个十进制小数无法被二进制精确表示,它实际在内存中存储的是一个略小于50.275的近似值(比如50.274999999999996)。DecimalFormat基于这个近似值做四舍五入,自然会得到50.27,而非你预期的50.28,换HALF_EVEN模式也没用,因为底层数值本身就不对。

可行解决方案

方案1:用BigDecimal精确处理(推荐)

直接用字符串构造BigDecimal,避免Double转BigDecimal时的精度丢失,再指定小数位数和舍入模式:

import java.math.BigDecimal;
import java.math.RoundingMode;

public class RoundingUtil {
    public static String formatToTwoDecimal(double value) {
        // 用字符串构造BigDecimal,保留原始数值精度
        BigDecimal decimal = new BigDecimal(String.valueOf(value));
        // 保留两位小数,使用HALF_UP舍入
        return decimal.setScale(2, RoundingMode.HALF_UP).toString();
    }

    public static void main(String[] args) {
        System.out.println(formatToTwoDecimal(50.275)); // 输出:50.28
    }
}

方案2:调整DecimalFormat的输入(不推荐,但可应急)

如果一定要用DecimalFormat,先把Double转成精确的BigDecimal再传入格式化:

import java.text.DecimalFormat;
import java.math.BigDecimal;
import java.math.RoundingMode;

public class DecimalFormatFix {
    public static String formatValue(double value) {
        DecimalFormat df = new DecimalFormat("0.00");
        df.setRoundingMode(RoundingMode.HALF_UP);
        // 先转成精确的BigDecimal再格式化
        return df.format(new BigDecimal(String.valueOf(value)));
    }

    public static void main(String[] args) {
        System.out.println(formatValue(50.275)); // 输出:50.28
    }
}

关键提示

  • 涉及精确计算(比如金额、统计数据)的场景,别用Double/Float类型存储数值,直接用BigDecimal更靠谱。
  • 不要依赖Double的十进制字面量做精确运算,二进制浮点数的精度限制会让你踩很多坑。

内容的提问来源于stack exchange,提问作者Mr.Simple

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 16:32:16