繁体   English   中英

BigDecimal使用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 mark2percent1percent2averageBigDecimal秒。 您在此处面临的问题是一个精度问题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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM