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

如何处理Java的BigDecimal中的舍入错误

左丘成业
2023-03-14

我正在使用开源项目(axil),该项目在java应用程序中实现了一个脚本引擎,我在尝试利用BigDecimal的舍入时遇到了一个主要的绊脚石。似乎BigDecimal正在将我的输入转换为科学符号,然后将我传递的精度应用于数字的SN表示的系数,而不是其非SN表示。例如:

new BigDecimal("-232454.5324"). cle(new MathContext(2, RoundingMode.HALF_UP)). toString()

生成-2.3E 5的结果。这给我带来了两个问题。首先,我期待-232454.5-2.324545E 5)的结果,因此获取-230000会抛出任何涉及结果的数学运算。其次,我不期望,也找不到一种方法来绕过SN获取结果(尽管我希望有一种格式化方法,我还没有偶然发现)。

现在,由于项目的性质,我们对传递给round()方法的数字的大小/类型几乎没有什么期望,因此任何解决方案都需要高度模块化。有人有什么建议吗?如果有帮助的话,这里有一个链接,指向项目中这个bug的google代码发布报告。这里是项目主页的链接。

任何帮助都非常感谢。

共有3个答案

乌俊健
2023-03-14

MathContext需要一个精度,即结果中有效位数的总数(小数点前后)<代码>BigDecimal的逻辑在此是正确的。

柯正谊
2023-03-14

我会这样做:

BigDecimal number = new BigDecimal("22.2222").setScale(0, RoundingMode.UP);

if (number.intValue() % 2 != 0) {
    number = number.add(BigDecimal.ONE);
}

System.out.println(number); // => 24
裴硕
2023-03-14

不要使用round方法,而是使用setScale,其中参数是小数位数:

BigDecimal bd = new BigDecimal("-232454.5324").setScale(1,
                RoundingMode.HALF_UP);
String string = bd.toPlainString();
System.out.println(string); // prints -232454.5

另请注意,setScale返回一个新的BigDecimal实例,它不会更改当前实例的规模。

 类似资料:
  • 问题内容: 以下代码使用, 分别显示和。在我看来,它应该分别显示和,因为丢弃的小数部分左边的数字(在这种情况下为5)是 奇数 。在这种情况下, 并且在的情况下, 当丢弃的小数部分> = 0.5时执行(这是正确的),否则执行。 问题答案: 该行为在Javadoc中有很好的描述: 舍入模式向“最近的邻居”舍入, 除非两个邻居都等距,在这种情况下,向偶数邻居舍入 。 因此,给定数字4.5,当您调用它时,

  • 我有一个由数字组成的数据集。我想在一份报告中陈述这一点。我已经设法生成了一个具有以下格式的报告。这有点类似于会计中的试算表。但事实并非如此!表中的数据在其值中有4个小数点。但在报告中,它应该四舍五入到小数点后两位。报告还必须准确,因此需要使用。 基于@marciob、@user3679868和@joopeggen的编辑3决定根据舍入值进行计算。差额。047(.56-.553)显然被冲销了(审计标准

  • 问题内容: 这两个电话有什么区别?(有没有?) 问题答案: 提到但没有直接解决的一个重要问题是 “精度” 和 “比例” 之间的区别以及它们在两个语句中的用法。 “精度” 是数字中有效数字的总数。 “比例” 是小数点右边的位数。 MathContext构造函数仅接受precision和RoundingMode作为参数,因此第一条语句中从未指定scale。 显然接受scale和RoundingMode

  • 在我的代码中进行一系列计算后,我有了一个,其值为 然后,我需要将这个乘以,我希望计算出的值为

  • 我将以下代码与java BigDecimal setScale方法结合使用,并使用半\u偶数舍入模式,得到以下结果。 结果:1.11 预计:1.12 由于距离5最近的偶数数字应该是2,因此我预期的结果是1.12。但结果是1.11。再一次, 结果:1.15 预期:1.14 因为5左边的偶数是4,所以我希望结果是1.14。对此有什么解释吗?

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