Java 将双精度舍入到小数点后两位

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2808535/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 13:04:02  来源:igfitidea点击:

Round a double to 2 decimal places

javadoublerounding

提问by Rajesh

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

如果值为200.3456,则应将其格式化为200.34。如果是200,那么应该是200.00

采纳答案by Jonik

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

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

For example:

例如:

round(200.3456, 2); // returns 200.35

Original version; watch out with this

原版;小心这个

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

This breaks down badlyin 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 Sloinfor pointing this out.

这在具有非常多的小数位(例如)或大整数部分(例如)的极端情况下会严重崩溃。感谢Sloin指出这一点。round(1000.0d, 17)round(90080070060.1d, 9)

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.

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

So, use this instead

所以,改用这个

(Adapted from this answer by Louis Wassermanand this one by Sean Owen.)

(改编自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();
}

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

请注意,这HALF_UP是“通常在学校教授”的舍入模式。仔细阅读RoundingMode 文档,如果你怀疑你需要其他的东西,比如Bankers' Rounding

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

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

And in every case

而且在任何情况下

Always remember that floating point representations using floatand doubleare inexact. For example, consider these expressions:

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

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

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:

为准确起见,您希望使用 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")));

Some excellent further reading on the topic:

关于该主题的一些出色的进一步阅读:



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

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

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).

具体来说,请注意round(200, 0)返回200.0. 如果你想输出“ 200.00”,你应该先舍入然后格式化输出的结果(这在Jesper 的回答中得到了完美的解释)。

回答by Ignacio Vazquez-Abrams

Rounding a double is usually not what one wants. Instead, use String.format()to represent it in the desired format.

四舍五入通常不是人们想要的。相反,使用String.format()以所需格式表示它。

回答by luke

The easiest way, would be to do a trick like this;

最简单的方法是做这样的把戏;

double val = ....;
val = val*100;
val = Math.round(val);
val = val /100;

if val starts at 200.3456 then it goes to 20034.56 then it gets rounded to 20035 then we divide it to get 200.34.

如果 val 从 200.3456 开始,那么它会变为 20034.56,然后它会四舍五入到 20035,然后我们将它除以得到 200.34。

if you wanted to always round down we could always truncate by casting to an int:

如果你想总是四舍五入,我们总是可以通过转换为 int 来截断:

double val = ....;
val = val*100;
val = (double)((int) val);
val = val /100;

This technique will work for most cases because for very large doubles (positive or negative) it may overflow. but if you know that your values will be in an appropriate range then this should work for you.

这种技术适用于大多数情况,因为对于非常大的双精度(正或负),它可能会溢出。但是如果您知道您的值将在适当的范围内,那么这应该适合您。

回答by Jesper

If you just want to print a doublewith two digits after the decimal point, use something like this:

如果您只想打印double小数点后两位数字,请使用以下内容:

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

If you want to have the result in a Stringinstead of being printed to the console, use String.format()with the same arguments:

如果您希望将结果显示在 aString而不是打印到控制台,请使用String.format()相同的参数:

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

Or use class DecimalFormat:

或使用类DecimalFormat

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

回答by bryanallott

In your question, it seems that you want to avoid rounding the numbers as well? I think .format() will round the numbers using half-up, afaik?
so if you want to round, 200.3456 should be 200.35 for a precision of 2. but in your case, if you just want the first 2 and then discard the rest?

在您的问题中,您似乎也想避免对数字进行四舍五入?我认为 .format() 会使用一半来对数字进行四舍五入,afaik?
所以如果你想四舍五入,200.3456 应该是 200.35,精度为 2。但在你的情况下,如果你只想要第一个 2 然后丢弃其余的?

You could multiply it by 100 and then cast to an int (or taking the floor of the number), before dividing by 100 again.

您可以将其乘以 100,然后再除以 100 之前转换为 int(或取整数)。

200.3456 * 100 = 20034.56;  
(int) 20034.56 = 20034;  
20034/100.0 = 200.34;

You might have issues with really really big numbers close to the boundary though. In which case converting to a string and substring'ing it would work just as easily.

但是,您可能会遇到接近边界的非常大的数字的问题。在这种情况下,转换为字符串和子字符串将同样容易。

回答by Santiago

I think this is easier:

我认为这更容易:

double time = 200.3456;
DecimalFormat df = new DecimalFormat("#.##");      
time = Double.valueOf(df.format(time));

System.out.println(time); // 200.35

Note that this will actually do the rounding for you, not just formatting.

请注意,这实际上会为您进行四舍五入,而不仅仅是格式化。

回答by Srujan Kumar Gulla

For two rounding digits. Very simple and you are basically updating the variable instead of just display purposes which DecimalFormat does.

对于两个四舍五入的数字。非常简单,您基本上是在更新变量,而不仅仅是 DecimalFormat 的显示目的。

x = Math.floor(x * 100) / 100;

x = Math.floor(x * 100) / 100;

回答by daoway

If you really want the same double, but rounded in the way you want you can use BigDecimal, for example

例如,如果您真的想要相同的双精度值,但以您想要的方式四舍五入,则可以使用 BigDecimal

new BigDecimal(myValue).setScale(2, RoundingMode.HALF_UP).doubleValue();

回答by user2068610

value = (int)(value * 100 + 0.5) / 100.0;

回答by user1692711

double d = 28786.079999999998;
String str = String.format("%1.2f", d);
d = Double.valueOf(str);