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 은 비교 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을 매개 변수로 사용하는 생성자를 사용하여 아래 관련 링크를 확인하십시오.
참조
참고 URL : https://stackoverflow.com/questions/11949330/bigdecimal-multiply-by-zero
'development' 카테고리의 다른 글
Java를 사용하여 버킷의 모든 AWS S3 객체를 나열하는 방법 (0) | 2020.12.10 |
---|---|
예외 있음 : 조각이 이미 활성화 됨 (0) | 2020.12.10 |
같지 않음에 대한 Rails ActiveRecord 쿼리 (0) | 2020.12.10 |
Windows에서 Cygwin을 통해 쉘 스크립트 실행 (0) | 2020.12.10 |
Gulp-uglify : 던지기 어; (0) | 2020.12.10 |