将一个小数加倍到2位小数

时间:2010-05-11 06:36:50

标签: java double rounding

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

13 个答案:

答案 0 :(得分:726)

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

例如:

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

我一直在使用上面的内容将“不太大”的双打多次绕到2或3位小数(例如为了记录目的,以秒为单位清理时间:27.987654321987 - &gt; 27.99)。但我想最好避免它,因为更可靠的方法随时可用,代码也更清晰。

因此,请改用

(改编自this answer by Louis Wassermanthis 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();
}

请注意HALF_UP是“通常在学校教授”的舍入模式。如果您怀疑需要其他内容,例如RoundingMode documentation

,请仔细阅读Bankers’ Rounding

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

并且在每种情况下

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

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

<强> For exactness, you want to use 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")));

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


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

具体而言,请注意round(200, 0)返回200.0。如果要输出“ 200.00 ”,则应首先对结果进行格式化,然后将结果格式化为输出(Jesper's answer中完全解释了这一点)。

答案 1 :(得分:300)

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

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

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

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

或使用班级DecimalFormat

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

答案 2 :(得分:114)

我认为这更容易:

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

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

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

答案 3 :(得分:64)

最简单的方法就是做这样的伎俩;

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

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

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

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

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

答案 4 :(得分:47)

请使用Apache commons math

Precision.round(10.4567, 2)

答案 5 :(得分:31)

function Double round2(Double val) {
    return new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue();
}

注意toString()!!!!

这是因为BigDecimal会转换double !!!的确切二进制形式。

这些是各种建议的方法及其失败案例。

// Always Good!
new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue() 

Double val = 260.775d; //EXPECTED 260.78
260.77 - WRONG - new BigDecimal(val).setScale(2,RoundingMode.HALF_UP).doubleValue()

Double val = 260.775d; //EXPECTED 260.78
260.77 - TRY AGAIN - Math.round(val * 100.d) / 100.0d  

Double val = 256.025d; //EXPECTED 256.03d
256.02 - OOPS - new DecimalFormat("0.00").format(val) 
// By default use half even, works if you change mode to half_up 

Double val = 256.025d; //EXPECTED 256.03d
256.02 - FAIL - (int)(val * 100 + 0.5) / 100.0;

答案 6 :(得分:22)

double value= 200.3456;
DecimalFormat df = new DecimalFormat("0.00");      
System.out.println(df.format(value));

答案 7 :(得分:16)

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

答案 8 :(得分:13)

如果你真的想要相同的双倍,但你想要的方式四舍五入,你可以使用BigDecimal,例如

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

答案 9 :(得分:8)

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

答案 10 :(得分:6)

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

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

答案 11 :(得分:0)

在你的问题中,似乎你想避免将数字四舍五入?我认为.format()会使用half-up来取消数字,afaik?
因此,如果你想要舍入,200.3456应该是200.35,精度为2.但在你的情况下,如果你只想要前2然后丢弃其余的?

您可以将它乘以100然后再转换为int(或取数字的最低点),然后再将其除以100。

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

你可能会遇到与边界接近的真正大数字的问题。在这种情况下,转换为字符串和子字符串,它将同样容易。

答案 12 :(得分:0)

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