development

BigDecimal 곱하기 0

big-blog 2020. 12. 10. 20:52
반응형

BigDecimal 곱하기 0


BigDecimal을 사용하여 간단한 곱셈을 수행하고 있으며 0으로 곱할 때 이상한 동작을 발견했습니다 (이 사용 사례에서는 0으로 곱하는 것이 맞습니다).

기본 수학은 0으로 곱한 모든 것이 0과 같다고 말합니다 ( 제로 제품 속성곱하기 속성 참조 ).

그러나 다음 코드는 동일한 오류와 함께 지속적으로 실패합니다.

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


이 주장처럼 equals()비교 하는 방법을 사용할 수 없습니다 BigDecimals. 이것은 같음 함수가 척도 를 비교하기 때문 입니다. 척도가 다르면 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()음수, 0 및 양수에 대해 -1, 0 또는 1을 반환 하는라는 메서드가 있습니다 . 따라서 0을 테스트 할 수도 있습니다.

assertEquals(0, actual.signum());

코드에는 두 가지 문제가 있습니다.

  • 다른 답변의 조언에 따라 BigDecimal을 equals 대신 compareTo와 비교해야합니다.
  • 그러나 배정 밀도 문제를 피하기 위해 double 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


equals()on 은 비교 BigDecimalBigDecimal위해 의 내부 상태 확인합니다.

아래 코드를 참조하십시오

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을 매개 변수로 사용하는 생성자를 사용하여 아래 관련 링크를 확인하십시오.


참조

참고 URL : https://stackoverflow.com/questions/11949330/bigdecimal-multiply-by-zero

반응형