Java BigDecimal不适合四舍五入
我正在创建一个应用程序,用百分比计算分数平均值,但问题是BigDecimal并不总是对平均值进行四舍五入,例如,如果分数平均值为3.85,则等级1中的BigDecimal四舍五入应四舍五入为3.9,但它显示的平均值类似于3.8,仅在某些特定时间发生,有时BigDecimal四舍五入,比如5.0,这很好,但我不知道为什么会发生,问题出在哪里。这是一个示例代码,您可以看到问题:Java BigDecimal不适合四舍五入,java,rounding,bigdecimal,Java,Rounding,Bigdecimal,我正在创建一个应用程序,用百分比计算分数平均值,但问题是BigDecimal并不总是对平均值进行四舍五入,例如,如果分数平均值为3.85,则等级1中的BigDecimal四舍五入应四舍五入为3.9,但它显示的平均值类似于3.8,仅在某些特定时间发生,有时BigDecimal四舍五入,比如5.0,这很好,但我不知道为什么会发生,问题出在哪里。这是一个示例代码,您可以看到问题: import java.io.*; import java.math.BigDecimal; public class
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);
}
}
import java.io.*;
导入java.math.BigDecimal;
公共班机{
公共静态void main(字符串[]args)引发IOException{
InputStreamReader输入=新的InputStreamReader(System.in);
BufferedReader buff=新的BufferedReader(输入);
//暂时的
浮动平均值=0;
浮动标记1=0;
浮动标记2=0;
浮动百分比1=0.75f;
浮动百分比2=0.25f;
对于(int i=0;i您应该使用BigDecimal
进行计算,而不仅仅是四舍五入
意思是,mark1
、mark2
、percent1
、percent2
和average
应该是bigdecimic
s。你在这里面临的问题是:float
s不够精确,无法保证计算的准确性,所以你认为应该是3.85
实际上是3.849999999999
。尝试打印bd
,您将看到其原始值为84999904632568359375
(至少这是我的准确值)
编辑、扩展:我刚刚想到,您可能也误解了。我从文档中引用了
舍入模式:向“最近邻”舍入,除非两个邻居距离相等,在这种情况下,舍入。如果丢弃的分数为≥ 0.5;否则,表现为向下舍入。请注意,这是我们大多数人在小学教的舍入模式
因此,总结精度问题,使bd
的实际值更接近3.8
而不是3.9
,以及取整的预期行为,您现在应该对结果有一个完整的解释。但是,当您只读取一个值时,为什么要对循环使用我不记得如何制作控制台程序,我只是先像工作一样做了。非常感谢,现在我了解了所有内容,我想现在我知道了如何解决它;)