将双精度舍入到小数点后两位 [英] Round a double to 2 decimal places

查看:42
本文介绍了将双精度舍入到小数点后两位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果值为200.3456,则格式为200.34.如果是200,那么应该是200.00.

If the value is 200.3456, it should be formatted to 200.34. If it is 200, then it should be 200.00.

推荐答案

这里有一个实用程序,可以舍入(而不是截断)双精度数到指定的小数位数.

Here's an utility that rounds (instead of truncating) a double to specified number of decimal places.

例如:

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;
}

在小数位数非常多(例如round(1000.0d, 17))或大整数部分(例如<代码>圆形(90080070060.1d,9)).感谢 Sloin 指出这一点.

This breaks down badly in corner cases with either a very high number of decimal places (e.g. round(1000.0d, 17)) or large integer part (e.g. round(90080070060.1d, 9)). Thanks to Sloin for pointing this out.

多年来,我一直在使用上述方法将不太大"的双精度数四舍五入到小数点后 2 或 3 位(例如,为了记录目的而以秒为单位清理时间:27.987654321987 -> 27.99).但我想最好避免它,因为更可靠的方法很容易获得,代码也更简洁.

I've been using the above to round "not-too-big" doubles to 2 or 3 decimal places happily for years (for example to clean up time in seconds for logging purposes: 27.987654321987 -> 27.99). But I guess it's best to avoid it, since more reliable ways are readily available, with cleaner code too.

(改编自 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 是学校常用"的舍入模式.仔细阅读RoundingMode 文档,如果您怀疑自己需要其他东西,例如银行家的四舍五入.

Note that HALF_UP is the rounding mode "commonly taught at school". Peruse the RoundingMode documentation, if you suspect you need something else such as Bankers’ Rounding.

当然,如果你愿意,你可以将上面的内容内联成一行:
new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()

Of course, if you prefer, you can inline the above into a one-liner:
new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue()

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

Always remember that floating point representations using float and double are inexact. For example, consider these expressions:

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

为了准确起见,您想使用 BigDecimal.在此期间,请使用接受 String 的构造函数,而不是采用 double 的构造函数.例如,尝试执行此操作:

For exactness, you want to use BigDecimal. And while at it, use the constructor that takes a String, never the one taking double. For instance, try executing this:

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

关于该主题的一些优秀的进一步阅读:

Some excellent further reading on the topic:

  • Item 48: "Avoid float and double if exact answers are required" in Effective Java (2nd ed) by Joshua Bloch
  • What Every Programmer Should Know About Floating-Point Arithmetic

如果您想要 String formatting 而不是(或除了)严格四舍五入的数字,请参阅其他答案.

If you wanted String formatting instead of (or in addition to) strictly rounding numbers, see the other answers.

特别注意round(200, 0) 返回200.0.如果你想输出200.00",你应该先舍入然后格式化输出的结果(这在 Jesper 的回答).

Specifically, note that round(200, 0) returns 200.0. If you want to output "200.00", you should first round and then format the result for output (which is perfectly explained in Jesper's answer).

这篇关于将双精度舍入到小数点后两位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆