我正在使用BigDecimal执行简单的乘法运算,并且在乘以零时发现了一些奇怪的行为(在此用例中乘以零是正确的)。
基础数学告诉我,任何乘以零的东西都等于零(参见:零积性质和乘法性质)
但是,以下代码将始终以相同的错误失败:
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\u 27在IntelliJ 11中运行
打开BigDecimal检查BigDecimal的内部状态以进行比较
参考下面的代码
public boolean equals(Object x) {
if (!(x instanceof BigDecimal))
return false;
BigDecimal xDec = (BigDecimal) x;
if (x == this)
return true;
if (scale != xDec.scale)
return false;
long s = this.intCompact;
long xs = xDec.intCompact;
if (s != INFLATED) {
if (xs == INFLATED)
xs = compactValFor(xDec.intVal);
return xs == s;
} else if (xs != INFLATED)
return xs == compactValFor(this.intVal);
return this.inflate().equals(xDec.inflate());
}
如果要比较值,请使用compareTo()
将代码更改为
assertEquals(0 , new BigDecimal(0).compareTo(new BigDecimal(22.3).multiply(new BigDecimal(0)));
更新:
使用将String作为BigDecimal参数的构造函数以提高精度检查以下相关链接
另请参见
您的代码有两个问题:
new bigdecime(“22.3”)
而不是双构造函数new bigdecime(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
您不能像此断言那样使用equals()
方法来比较大小数。这是因为这个equals函数将比较刻度。如果刻度不同,equals()
将返回false,即使它们在数学上是相同的数字。
但是,您可以使用compareTo()
来执行您想要的操作:
正如@assylias指出的,您还应该使用new BigDecimal("22.3")
构造函数来避免双精度问题。
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());
描述 (Description) java.math.BigDecimal.subtract(BigDecimal subtrahend)返回一个BigDecimal,其值为(this - subtrahend),其标度为max(this.scale(),subtrahend.scale())。 声明 (Declaration) 以下是java.math.BigDecimal.subtract()
描述 (Description) java.math.BigDecimal.remainder(BigDecimal divisor)方法返回一个BigDecimal,其值为(this%divisor)。 余数由this.subtract(this.divideToIntegralValue(divisor).multiply(divisor))给出。 这不是模运算,即结果可能是负的。 声明 (D
描述 (Description) java.math.BigDecimal.multiply(BigDecimal multiplicand)返回一个BigDecimal,其值为(this×multiplicand),其标度为(this.scale()+ multiplicand.scale())。 声明 (Declaration) 以下是java.math.BigDecimal.multiply
描述 (Description) java.math.BigDecimal.min(BigDecimal val)返回此BigDecimal和val的最小值。 声明 (Declaration) 以下是java.math.BigDecimal.min()方法的声明。 public BigDecimal min(BigDecimal val) 参数 (Parameters) val - 要计算最大值
描述 (Description) java.math.BigDecimal.max(BigDecimal val)返回此BigDecimal和val的最大值。 声明 (Declaration) 以下是java.math.BigDecimal.max()方法的声明。 public BigDecimal max(BigDecimal val) 参数 (Parameters) val - 要计算最大值
描述 (Description) java.math.BigDecimal.divideToIntegralValue(BigDecimal divisor)返回一个BigDecimal,其值是向下舍入的商(this/divisor)的整数部分。 结果的首选比例是(this.scale() - divisor.scale())。 声明 (Declaration) 以下是java.math.BigD