舍入一个2位小数位 [英] Round a double to 2 decimal places

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

问题描述

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

解决方案

这是一个实用程序,回合(而不是截断)一个双倍到指定的小数位数。 / p>

例如:

  round(200.3456,2); //返回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))或大整数部分(例如 round(90080070060.1d,9))。感谢 Sloin 指出这一点。



我有一直使用上面的方式将不太大的双打,以高达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 = new BigDecimal(value);
bd = bd.setScale(places,RoundingMode.HALF_UP);
return bd.doubleValue();
}

请注意, HALF_UP 是通常在学校教书的四舍五入模式。请仔细阅读 RoundingMode文档,如果您怀疑需要其他的东西,例如 Bankers'Rounding



当然,如果你愿意,你可以将上面的内容列入一行:

new BigDecimal(value).setScale(places,RoundingMode.HALF_UP)在每一种情况下,$ d $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $> point point point point point point point point point point point point point point point point point point使用 float double 的表示不正确。
例如,考虑这些表达式:

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

要确切地,您要使用BigDecimal 。而在它的同时,使用构造函数接受一个String,从来没有一个双重。例如,尝试执行以下操作:

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

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








如果您希望使用String 格式化,而不是(或除了)严格舍入数字,请参阅其他答案。



具体来说,请注意, round(200,0)返回 200.0 。如果要输出 200.00 ,您应该首先回合,然后格式化输出结果(这在 Jesper的答案)。


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.

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

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.

So, use this instead

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

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

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

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.

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

And in every case

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

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:


If you wanted String formatting instead 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).

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

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