【问题标题】:Decimal Format Rounding Mode produces inconsistent values十进制格式舍入模式产生不一致的值
【发布时间】:2016-01-11 15:50:50
【问题描述】:

我发现使用显示的十进制格式和舍入模式会出现一些值的意外行为

    double b = 123.135;
    //double b = 1896.675;
    //double b = 523.135;

    DecimalFormat df = new DecimalFormat(".##");
    df.setRoundingMode(RoundingMode.HALF_UP);
    System.out.println(b);
    String a = df.format(b);
    System.out.println(a);

    double roundOff = Math.round(b * 100.0) / 100.0;
    System.out.println(roundOff);

生产:

123.135
123.14
123.14

我认为这是正确的。

使用此值时:1896.675 会产生以下结果:

1896.675
1896.67
1896.68

我认为出乎意料 - 我在这里做错了什么?

【问题讨论】:

  • 设置 BigDecimal bd = new BigDecimal(b);并打印 bd 结果为 1896.674999999999954525264911353588104248046875 我猜这接近存储的实际值。

标签: java double precision decimalformat


【解决方案1】:

这里的问题是,由于二进制格式的限制,不可能将所有可能的分数存储在一个变量中。所以基本上 double 只是近似于您输入的值,这就是发生舍入错误的原因。 您可以在例如此线程中阅读有关此主题的更多信息:how does java.math.RoundingMode work?

长话短说,如果您想要精确舍入,请使用 BigDecimal(以及 BigDecimal 类的 valueOf 函数)

【讨论】:

  • 请注意,即使 BigDecimal 也只能在涉及的每个数字都可以精确表示为小数部分时才能给出精确结果。它不能准确表示,例如,1 除以 3 的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多