Java 将双精度四舍五入到小数点后2位

Java 将双精度四舍五入到小数点后2位,java,double,rounding,Java,Double,Rounding,如果该值为200.3456,则应将其格式化为200.34。 如果它是200,那么它应该是200.00四舍五入通常不是人们想要的。取而代之的是,用所需的格式来表示它。最简单的方法是做这样一个技巧 double val = ....; val = val*100; val = Math.round(val); val = val /100; 如果val从200.3456开始,然后到20034.56,然后四舍五入到20035,然后我们除以它得到200.34 如果您希望始终向下取整,我们可以始终通过强

如果该值为
200.3456
,则应将其格式化为
200.34

如果它是
200
,那么它应该是
200.00

四舍五入通常不是人们想要的。取而代之的是,用所需的格式来表示它。

最简单的方法是做这样一个技巧

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;

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

如果您只想打印小数点后有两位数字的
双精度
,请使用以下方法:

double value = 200.3456;
System.out.printf("Value: %.2f", value);
如果希望将结果打印为
字符串
,而不是打印到控制台,请使用具有相同参数的
String.format()

String result = String.format("%.2f", value);
或者使用class
十进制格式

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

在你的问题中,似乎你也希望避免将数字四舍五入?我认为.format()将使用对半法对数字进行四舍五入,好吗?
所以,如果你想取整,200.3456应该是200.35,精度为2。但在你的情况下,如果你只想要前两个,然后放弃其余的

您可以将其乘以100,然后转换为整数(或以数字为底),然后再除以100

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

但是,你可能会对接近边界的非常大的数字产生问题。在这种情况下,转换为字符串并对其进行子字符串运算同样容易。

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

例如:

round(200.3456, 2); // returns 200.35
原文;小心这个 请注意,
HALF_UP
是舍入模式“通常在学校教授”。如果你怀疑你还需要其他东西,比如

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

在任何情况下 始终记住,使用
float
double
的浮点表示是不精确的。 例如,考虑这些表达式:

999199.1231231235 == 999199.1231231236 // true
1.03 - 0.41 // 0.6200000000000001
。同时,使用接受字符串的构造函数,而不是接受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")));
关于该主题的一些优秀的进一步阅读:

  • Joshua Bloch在《有效Java》(第二版)中的第48项:“如果需要准确答案,则避免
    float
    double

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


具体来说,请注意
round(200,0)
返回
200.0
。如果你想输出“200.00”,你应该先进行一轮,然后将结果格式化输出(这在中有很好的解释)。

我认为这更容易:

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

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

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

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


x=数学楼层(x*100)/100

例如,如果您确实想要相同的双精度,但以您想要的方式进行舍入,则可以使用BigDecimal

new BigDecimal(myValue).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;
请使用:


使用
DecimalFormat
还可以选择舍入模式;默认值将匹配OP的示例,或者他们可能需要
舍入模式.DOWN
。前两个选项为大于-0.005小于0的数字提供
-0.00
。如果在报表上显示值,这可能不是最佳选择。@根据您的具体情况,我认为应该使用3位或更多的小数点。这取决于你的误差幅度。这个答案才是真正的答案。。。其他的是双精度,这与格式化是完全不同的操作。如果希望结果是双精度变量而不是字符串,该怎么办?谢谢您的回答。如果该值为200.3456,则工作正常,但如果该值为200,则应为200.00,正如Monn评论的那样(在回答中),200.3456实际需要200.34还是200.35?当您接受我的答案时,我想您确实需要舍入(+可能还需要格式化),而不仅仅是截断。但是你能不能明确你的意思?显然不是你的问题的答案,但是任何阅读这个问题的人都应该认真考虑为什么他们真的需要使用一个双而不是一个大写的小数。另一个问题需要一个字符串作为结果。这一个想要一个双倍的,解决方案是不同的;格式和取整是两件完全不同的事情。再一次,否决票在评论中更有用。(请注意,这个问题模棱两可,我的回答清楚地表明,它并没有解决问题的所有解释。)请参阅《为什么
tmp/因子》
这类事情可能失败》阅读关于该答案的第一条评论。很明显,如果你处理的是精确的(如货币)价值,你就可以。(在这种情况下,)谢谢,这看起来坚如磐石,顺便说一句:返回新的BigDecimal(value).setScale(places,BigDecimal.ROUND_HALF_UP).doubleValue()@莉萨克:在什么情况下,舍入到18位数有意义?舍入的目的不是要创建一个简化的表示吗?好吧,也许在计算大额贷款的利息时。。但希望所有做金融计算的人都知道使用
BigDecimal
而不是<
new BigDecimal(myValue).setScale(2, RoundingMode.HALF_UP).doubleValue();
value = (int)(value * 100 + 0.5) / 100.0;
double d = 28786.079999999998;
String str = String.format("%1.2f", d);
d = Double.valueOf(str);
double value= 200.3456;
DecimalFormat df = new DecimalFormat("0.00");      
System.out.println(df.format(value));
function Double round2(Double val) {
    return new BigDecimal(val.toString()).setScale(2,RoundingMode.HALF_UP).doubleValue();
}
// 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;
Precision.round(10.4567, 2)