Error: while trying to format decimal output in Java

Error: while trying to format decimal output in Java

我正在写 this program 作为学校的作业。该程序以 'sex' 和 'age' 的形式从用户那里获取输入,并返回所有男性 and/or 女性的平均年龄。

该程序一直运行良好,直到我妈妈对其进行了 Beta 测试,我们偶然发现了一个问题。如果用户碰巧输入了一些人,而他们的年龄总和不能被输入的人数整除,则输出将给出一个小数点后 15 位的答案。 例如,如果我输入 3 名年龄分别为 98、1 和 1 的男性,程序将 100 除以 3,得到输出:

33.333333333333336.

所以我开始寻找这个问题的解决方案,并找到了 this 我在我的程序中实现了如下所示,这样它就会 trim 将答案减少到最多 3小数位:

/*
This method takes two values. The first value is divided by the second value to get the average. Then it trims the
answer to output a maximum of 3 decimal places in cases where decimals run amok.
*/
public static double average (double a, double b){
    double d = a/b;
    DecimalFormat df = new DecimalFormat("#.###");
    return Double.parseDouble(df.format(d));

我在我的程序底部写了代码,在它自己的方法中,我在第 76 和 77 行的 main 方法中调用了它:

// Here we calculate the average age of all the people and put them into their respective variable.
    double yAverage = average(yAge, men);
    double xAverage = average(xAge, women);

不过。当我尝试 运行 程序时得到这个 error message,但我不明白错误消息。我尝试用谷歌搜索错误,但一无所获。 请记住,我是初学者,我需要任何人都能给我的简单答案。 提前致谢!

试试这个代码

    public static double average(double a, double b) {
    double d = a / b;
    DecimalFormat df = new DecimalFormat(
            "#.###", 
            DecimalFormatSymbols.getInstance(Locale.ENGLISH)
    );
    return Double.parseDouble(df.format(d));
}

您正在使用以点作为小数点分隔符(“#.###”)的格式。根据您 运行 您的程序所在的位置,Java 运行 时间使用不同的本地化设置,例如在德国,逗号用作小数点分隔符。 当您使用 new DecimalFormat("#.###") 时,默认语言环境用于解释字符串 #.###,这可能在某些地方有效,但在其他地方无效。幸运的是,DecimalFormat 有另一个构造函数,您可以在其中指定应使用的符号。通过使用 DecimalFormatSymbols.getInstance(Locale.ENGLISH) 作为第二个参数,您指定您需要英语格式约定(“.”作为小数点分隔符,“,”代表千位)。

问题是 DecimalFormat 尊重您的 Locale 设置,根据您的语言设置格式化数字。

例如在美国英语中,结果是 33.333,但在德语中,结果是 33,333.

但是,Double.parseDouble(String s) 被硬编码为仅解析美国英语格式。

修复它的几个选项:

  • 不要四舍五入该值。 推荐

    在需要显示值的地方使用 DecimalFormat,但要保持值本身的完整精度。

  • 强制 DecimalFormat 使用美国英语格式符号。

    DecimalFormat df = new DecimalFormat("#.###", DecimalFormatSymbols.getInstance(Locale.US));
    
  • 使用DecimalFormat重新解析值。

    DecimalFormat df = new DecimalFormat("#.###");
    try {
        return df.parse(df.format(d)).doubleValue();
    } catch (ParseException e) {
        throw new AssertionError(e.toString(), e);
    }
    
  • 不要将 to/from 字符串转换为保留 3 位小数。

    • 使用Math.round(double a).

      return Math.round(d * 1000d) / 1000d;
      
    • 使用BigDecimal(并坚持使用)推荐

      return BigDecimal.valueOf(d).setScale(3, RoundingMode.HALF_UP);
      
    • 使用BigDecimal(暂时).

      return BigDecimal.valueOf(d).setScale(3, RoundingMode.HALF_UP).doubleValue();