将双倍四舍五入到小数点后 2 位原始版本;注意这个因此,请改用此在每种情况下

2022-08-31 04:16:43

如果值为 ,则应将其格式化为 。如果是 ,则应该是 。200.3456200.34200200.00


答案 1

下面是一个实用程序,它将双精度值舍入(而不是截断)到指定的小数位数。

例如:

round(200.3456, 2); // returns 200.35

原始版本;注意这个

public static double round(double value, int places) {
    if (places < 0) throw new IllegalArgumentException();

    long factor = (long) Math.pow(10, places);
    value = value * factor;
    long tmp = Math.round(value);
    return (double) tmp / factor;
}

这在小数位数非常高(例如)或大整数部分(例如)的角落情况下会严重分解。感谢Sloin指出这一点。round(1000.0d, 17)round(90080070060.1d, 9)

多年来,我一直在使用上述方法将“不太大”的双精度值愉快地舍入到小数点后2或3位(例如,出于日志记录目的,以秒为单位清理时间:27.987654321987 -> 27.99)。但我想最好避免它,因为更可靠的方法很容易获得,代码也更干净。

因此,请改用此

(改编自Louis Wasserman的这个答案Sean Owen的这个答案。

public static double round(double value, int places) {
    if (places < 0) throw new IllegalArgumentException();

    BigDecimal bd = BigDecimal.valueOf(value);
    bd = bd.setScale(places, RoundingMode.HALF_UP);
    return bd.doubleValue();
}

请注意,这是“通常在学校教授”的舍入模式。仔细阅读舍入模式文档,如果您怀疑自己需要其他东西,例如银行家的舍入HALF_UP

当然,如果您愿意,可以将上述内容内联到一行中:
new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()

在每种情况下

永远记住,浮点表示使用和是不精确的。例如,请考虑以下表达式:floatdouble

999199.1231231235 == 999199.1231231236 // true
1.03 - 0.41 // 0.6200000000000001

为了准确起见,您希望使用 BigDecimal。在使用它时,请使用采用 String 的构造函数,而不要使用采用 double 的构造函数。例如,尝试执行以下命令:

System.out.println(new BigDecimal(1.03).subtract(new BigDecimal(0.41)));
System.out.println(new BigDecimal("1.03").subtract(new BigDecimal("0.41")));

关于这个主题的一些很好的进一步阅读:


如果您想要字符串格式而不是(或除了)严格舍入数字之外,请参阅其他答案。

具体来说,请注意返回 。如果要输出“200.00”,则应首先进行轮询,然后格式化结果以进行输出(这在Jesper的答案中得到了完美的解释)。round(200, 0)200.0


答案 2

如果您只想在小数点后打印两位数,请使用类似如下的方法:double

double value = 200.3456;
System.out.printf("Value: %.2f", value);

如果要将结果打印到控制台中,请使用相同的参数:StringString.format()

String result = String.format("%.2f", value);

或者使用类 :DecimalFormat

DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " + df.format(value));