大十进制乘以零

我正在用BigDecimal执行一个简单的乘法,我发现在乘以零时有一些奇怪的行为(在这个用例中乘以零是正确的)。

基本数学告诉我,任何乘以零的东西都等于零(参见:零乘积属性乘法属性)

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

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

这是BigDecimal的不准确之处,还是我在某个地方错过了一些利基数学分支?

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


答案 1

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

但是,您可以使用 来执行所需的操作:compareTo()

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

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

还有一个名为 的方法,它返回负数、零值和正数的 -1、0 或 1。因此,您也可以使用signum()

assertEquals(0, actual.signum());

答案 2

您的代码存在 2 个问题:

  • 您应该将 BigDecimal 与 compareTo 进行比较,而不是 equals,如其他答案所示
  • 但你也应该使用字符串构造函数:而不是双精度构造函数,以避免双精度问题new BigDecimal("22.3")new BigDecimal(22.3)

换句话说,以下代码(正确使用 compareTo)仍返回 false:

BigDecimal bd = new BigDecimal(0.1).multiply(new BigDecimal(10));
System.out.println(bd.compareTo(BigDecimal.ONE) == 0);

因为0.1d * 10d != 1


推荐