当前位置: 首页 > 知识库问答 >
问题:

BigDecimal不适合四舍五入,向上取整\u HALF\u

殳飞扬
2023-03-14

我正在创建一个用百分比计算分数平均值的应用程序,但问题是BigDecimal并不总是对平均值进行四舍五入,例如,如果分数平均值是3.85 BigDecimal ROUND\u HALF\u,那么在量表1中应该四舍五入到3.9,但它显示的平均值像3.8,这只发生在某些特定的时间,有时BigDecimal ROUND 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

请原谅我英语不好,非常感谢阅读:)

共有1个答案

洪浩波
2023-03-14

您应该使用BigDecimal进行计算,而不仅仅是四舍五入。

意思是,mark 1mark 2percent1percent2平均应该是BigDecimals。您在这里面临的问题是精度问题:浮动s不够精确,无法保证计算的准确性,因此您认为应该是3.85实际上是3.849999999999。尝试打印bd,您将其原始值设为849999904632568359375(至少这是我的确切值)。

编辑、扩展:我刚刚想到,您可能也误解了ROUND\u HALF\u UP的含义。我从文件中引用

舍入模式向“最近邻居”舍入,除非两个邻居等距,在这种情况下舍入。如果丢弃的分数≥0.5,则表现为ROUND_UP;否则,表现为ROUND_DOWN。请注意,这是我们大多数人在小学学到的舍入模式。

因此,将精度问题相加,使bd的实际值更接近3.8,而不是3.9,以及取整半个的预期行为,您现在应该对结果有一个完整的解释。

 类似资料:
  • 我有一个函数,它接收两个大十进制数,即bd1和bd2作为参数。函数应该减去bd1-db2并返回 bd1和bd2的刻度都是2,结果也应该只有2的刻度,但使用减法是按比例缩小到小数点后的完整表示形式。我希望刻度设置为2,并尝试使用setScale,但setScale需要舍入模式,并且不清楚使用哪种舍入模式才能获得限制在刻度2的精确结果 需要的是获得比例为2的精确减去值(bd1-bd2)。在这种情况下,

  • 有人能告诉我怎么打双人球吗 e、 g.从双倍值55.6666666666667开始-四舍五入到双倍值56.0000000000- 或者从55.333333333333开始-四舍五入到55.0000000000的两倍- 谢谢。

  • 本文向大家介绍SQL四舍五入、向下取整、向上取整函数介绍,包括了SQL四舍五入、向下取整、向上取整函数介绍的使用技巧和注意事项,需要的朋友参考一下 round() 遵循四舍五入把原值转化为指定小数位数,如:round(1.45,0) = 1;round(1.55,0)=2 floor()向下取整 如:floor(1.45)= 1,floor(1.55) = 1 ,floor(-1.45)= -2

  • 我一直在尝试在java中使用bigdecimal进行取整,并遇到了一个java。显示非终止十进制扩展的lang.ArithmeticException错误。 谁能解释一下这个错误的起源吗?因为我对java还很陌生?帮我写代码? 谢谢 变量“d”是我认为产生错误的地方。

  • 问题内容: 我需要以下结果 还是?我该怎么办? 问题答案: 您可以使用将小数位数减少为零。假设拥有要取整的值: 使用起来有点麻烦,因为它要求您指定要保留的位数。在您的示例中,该值为3,但这不适用于所有值: (请注意,对象是不可改变的,都和会返回一个新的对象。)

  • 我正在使用BigDecimal在我的应用程序中处理正数,我想让它在第4个之后截断小数。我似乎几乎找到了我想要的RoundingMode。向下,但当BigDecimal是从双精度创建时存在一些问题。 例如: 但是,以下打印的是123.1110,这根本不是我想要的: