
[英]Java BigDecimal bugs with String constructor to rounding with ROUND_HALF_UP
[英]BigDecimal is not rounding good with ROUND_HALF_UP
我正在创建一个应用程序来计算带有百分比的标记平均值,但是问题是BigDecimal并不总是四舍五入,例如,如果标记平均值为3.85 BigDecimal ROUND_HALF_UP,则小数位数1应该四舍五入为3.9,但显示的平均值为3.8,这种情况仅在某些特定时间发生,有时BigDecimal第4.95轮像5.0一样好,但是我不知道为什么发生,问题出在哪里。 这是一个示例代码,您可以看到此问题:
import java.io.*;
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) throws IOException{
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader buff = new BufferedReader (input);
//temporal
float average=0;
float mark1=0;
float mark2=0;
float percent1=0.75f;
float percent2=0.25f;
for(int i=0;i<1;i++){
System.out.println("Enter mark 1 (75%) : ");
mark1=Float.parseFloat(buff.readLine());
}
for(int i=0;i<1;i++){
System.out.println("Enter mark 2 (25%): ");
mark2=Float.parseFloat(buff.readLine());
}
average= ((mark1*percent1)+(mark2*percent2));
// convert to BigDecimal
BigDecimal bd = new BigDecimal(average);
BigDecimal roundingMark = bd.setScale(1,
BigDecimal.ROUND_HALF_UP);
System.out.println(" the complete average is :"+average);
System.out.println(" The rounding average is :"+roundingMark);
}
}
您应该在第一个标记4.5中添加第二个标记1.9,结果应为3.8,并且应为3.9
请原谅我的英语不好,非常感谢您的阅读:)
您应该使用BigDecimal
进行计算,而不仅仅是四舍五入。
这意味着, mark1
mark2
, percent1
, percent2
和average
应BigDecimal
秒。 您在此处面临的问题是一个精度问题 : float
的精度不足以保证计算的准确性,因此您认为应该为3.85
实际上是3.849999999999
。 尝试打印bd
,您将其原始值为849999904632568359375
(至少这是我的准确值)。
编辑,扩展 :对我来说,您可能还误解了ROUND_HALF_UP的含义。 我从文档中引用
舍入模式向“最近的邻居”舍入,除非两个邻居都等距,在这种情况下将舍入。 如果丢弃分数≥0.5,则表现为ROUND_UP; 否则,行为与ROUND_DOWN相同。 请注意,这是我们大多数人在小学时所教的四舍五入模式。
因此,总结精度问题,使bd
的实际值更接近3.8
,而不是3.9
,以及ROUND_HALF_UP
的预期行为,现在您应该对结果有完整的解释。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.