java - BigDecimal 乘以零

标签 java bigdecimal numerical-analysis rounding-error

我正在使用 BigDecimal 执行简单的乘法运算,但在乘以零时发现了一些奇怪的行为(在此用例中乘以零是正确的)。

基本数学告诉我,任何乘以零都将等于零(参见:Zero Product PropertyMultiplication Properties)

但是,以下代码将始终失败并出现相同的错误:

assertEquals(new BigDecimal(0), new BigDecimal(22.3).multiply(new BigDecimal(0)));
java.lang.AssertionError: 
Expected :0
Actual   :0E-48

这是 BigDecimal 的不准确之处,还是我在某处遗漏了一些特定的数学分支?

注意事项:JDK 1.6.0_27 在 IntelliJ 11 中运行

最佳答案

您不能像这个断言那样使用 equals() 方法来比较 BigDecimals。那是因为这个 equals 函数会比较比例。如果比例不同,equals() 将返回 false,即使它们在数学上是相同的数字。

你可以使用 compareTo() 来做你想做的事:

正如@assylias 指出的那样,您还应该使用 new BigDecimal("22.3") 构造函数来避免 double 问题。

BigDecimal expected = BigDecimal.ZERO;
BigDecimal actual = new BigDecimal("22.3").multiply(BigDecimal.ZERO);
assertEquals(0, expected.compareTo(actual));

还有一个名为 signum() 的方法,它返回 -1、0 或 1 表示负数、零和正数。所以你也可以用

测试零
assertEquals(0, actual.signum());

关于java - BigDecimal 乘以零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11949330/

相关文章:

java - 处理多个ResultSet

java - 将客户端数据放入 Java 对象中。获取 com.fasterxml.jackson.databind.exc.MismatchedInputException

java - 为什么 BigInteger 除法时要减去小数位数,乘法时要加上小数位数?

java - java中的货币操作使用哪种舍入模式?

c - 如何生成与直方图匹配的点?

c++ - 实现自定义非线性最小化,从符号数学到 C

Java数学库计算日志

ruby - 我怎么知道 BigDecimal 是否解析失败?

java - 现代计算机上的二进制 GCD 算法与欧几里得算法

java - 在 while(rset.next) 内调用方法时耗尽结果集