BigDecimal equals () 대 compareTo ()


157

간단한 테스트 클래스를 고려하십시오.

import java.math.BigDecimal;

/**
 * @author The Elite Gentleman
 *
 */
public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        BigDecimal x = new BigDecimal("1");
        BigDecimal y = new BigDecimal("1.00");
        System.out.println(x.equals(y));
        System.out.println(x.compareTo(y) == 0 ? "true": "false");
    }

}

(의식적으로) 객체 참조 x가 아니라고 말할 수 는 y있지만 프로그램을 실행하면 다음 결과가 표시됩니다.

false
true

질문 : 차이 무엇 compareTo()equals()에서 BigDecimalcompareTo것을 확인할 수 있습니다 x같다가 y?

추신 : BigDecimal에는 inflate()메소드에 대한 equals()메소드가 있습니다. 무엇 않습니다 inflate()실제로합니까?


1
광고 inflate(): 내부 표현 만 조작하고 "외부"에 가시적 인 영향을 미치지 않기 때문에 공개 API의 일부가 아닙니다. 따라서 BigDecimal깊이 있는 구현을 실제로 연구하고 싶지 않다면 이 방법을 무시하는 것이 좋습니다.
Joachim Sauer

간단한 설명과 소스 코드 스 니펫은 여기
xenteros

답변:


224

대답은 메소드 의 JavaDoc에 있습니다equals() .

와 달리 compareTo,이 방법은 두 BigDecimal객체가 값과 스케일이 동일한 경우에만 동일 하다고 간주 합니다 (따라서이 방법과 비교할 때 2.0은 2.00이 아닙니다).

즉 , 모든 측면 에서 객체가 정확히 동일한 지 equals()확인합니다 . "only"는 숫자 값을 비교합니다.BigDecimalcompareTo()

equals() 이런 식으로 행동하는지에 관해서 는, 이것은 이 SO 질문에서 대답되었습니다 .


24
BigDecimalJavaDoc을주의 깊게 읽지 않으면 매우 까다로운 부분입니다 . :)-차이점을 깨달을 때까지 이상한 버그가 생겼습니다.
토마스

3
직관적 인 것이 정확하지 않을 때 표준 API의 많은 부분이 "직관적으로"작동합니다. BigDecimal그런 것 중 하나입니다. 따라서 항상 JavaDoc을 확인해야합니다. 적어도 한 번 이상 이상한 것을 발견하면 계속됩니다.
Joachim Sauer

7
이상한. "좋습니다 (필수 사항은 아님)"답을 읽은 후 난 그냥 Comparable를 확인하고는 equals와 그 일관성을 말한다
SJuan76

4
나는 이유를 물었다 : stackoverflow.com/questions/14102083/…
bacar

8
@StephenC 이 불일치가 존재한다고 잘못 생각 합니다.
Matt R

1

BigDecimal에는 equals () 메소드에 inflate () 메소드가 있습니다. inflate () 실제로 무엇을합니까?

기본적으로 필요한 경우 inflate()호출 BigInteger.valueOf(intCompact)합니다. 즉, BigIntegerfrom으로 저장된 스케일되지 않은 값을 만듭니다 long intCompact. 필요하지 않고 BigInteger스케일링 되지 않은 값이 long BigDecimal가능한 한 공간을 절약하려고 시도 하는 것 같습니다.


나는 당신이 무엇을 썼는지 (특히 마지막 문장으로) 알지 못합니다.
Buhake Sindi

@The Elite Gentlement 마지막 문장은 내부적 BigDecimal으로 스케일링되지 않은 가치를 a long와 같이 유지 한다고 말합니다 BigInteger. 이 경우 BigInteger내부적으로 필요하지 않습니다이 작성되지 않습니다하지만이 필요한 경우 (예를 들면 때 equals만남 팽창과 비 팽창 BigDecimal) 부풀려은 ()`를 만드는 데 사용되는 -을 요약하면 :. inflate()핸들 내부 전환이 필요한 경우와 그 이후 개인 사용자는 문제가되지 않습니다
Thomas

1

정답은 두 숫자 (BigDecimals)를 만들고 같은 척도를 갖는 것이므로 그 평등에 대해 결정할 수 있다고 생각합니다. 예를 들어이 두 숫자가 같은가요?

1.00001 and 1.00002

음, 그것은 규모에 달려 있습니다. 스케일 5 (소수점 5)에서는 동일하지 않습니다. 그러나 더 작은 10 진수 정밀도 (스케일 4 이하)에서는 동일한 것으로 간주됩니다. 따라서 두 숫자의 스케일을 동일하게 한 다음 비교하십시오.


-10

이중 값과 비교할 수도 있습니다

BigDecimal a= new BigDecimal("1.1"); BigDecimal b =new BigDecimal("1.1");
System.out.println(a.doubleValue()==b.doubleValue());

5
이 솔루션을 최대한 피하십시오. 복식도 "엡실론"과 비교해야합니다. BigDecimal을 가지고 그것을 복식으로 비교하는 것은 의미가 없습니다. 자신의 다리를 쏠 확률은 매우 높습니다.
Vadim Kirilchuk

Douuble 값은 epsillons를 사용하여 비교해야합니다
Bishwajit Purkaystha
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.