알 리 바 바 가 왜 BigDecimal 의 equals 방법 을 사용 하여 등가 비 교 를 금지 하 는 지 상세 하 게 설명 하 다.
6051 단어 BigDecimalequals
금액 표시,금액 계산 등 을 진행 하 는 장면 에 서 는 더 블,플 로 트 등 을 사용 할 수 없고 정밀도 에 더 잘 지원 되 는 빅 데 시 밀 을 사용 해 야 한 다 는 것 을 많은 사람들 이 알 고 있다.
그래서 많은 결제,전자상거래,금융 등 업무 에서 빅 데 시 멜 의 사용 이 매우 빈번 하 다.그리고 이것 은 매우 사용 하기 좋 은 유형 이 라 고 할 수 밖 에 없다.그 내 부 는 여러 가지 방법 을 가지 고 있다.예 를 들 어 더하기,빼 기,곱 하기,제외 등 연산 방법 은 모두 직접 호출 할 수 있다.
BigDecimal 로 숫자 를 표시 하고 숫자 연산 을 해 야 하 는 것 외 에 코드 에 서 는 숫자 에 대한 동일 한 판단 이 자주 필요 하 다.
이 지식 에 대해 최신 판 알 리 바 바 자바 개발 매 뉴 얼 에 도 설명 되 어 있다.
이 뒤의 사 고 는 무엇 입 니까?
나 는 이전의 CodeReview 에서 다음 과 같은 저급한 오 류 를 본 적 이 있다.
if(bigDecimal == bigDecimal1){
//
}
이런 오 류 는 똑똑 하 다 고 믿 는 독자 들 이 한눈 에 문 제 를 알 수 있다.빅 디 밀 이 대상 이기 때문에 두 숫자의 값 이 같 는 지 아 닌 지 를 4 만 567914 로 판단 할 수 없다.상기 와 같은 문 제 는 일정한 경험 이 있 는 후에 도 피 할 수 있 지만 똑똑 한 독자 들 은 다음 과 같은 코드 를 보 세 요.그 에 게 문제 가 있다 고 생각 합 니까?
if(bigDecimal.equals(bigDecimal1)){
//
}
이상 의 이런 표기 법 은 당신 이 예상 한 것 과 다 를 수 있 음 을 명확 하 게 알려 드릴 수 있 습 니 다!먼저 실험 을 하고 다음 코드 를 실행 합 니 다.
BigDecimal bigDecimal = new BigDecimal(1);
BigDecimal bigDecimal1 = new BigDecimal(1);
System.out.println(bigDecimal.equals(bigDecimal1));
BigDecimal bigDecimal2 = new BigDecimal(1);
BigDecimal bigDecimal3 = new BigDecimal(1.0);
System.out.println(bigDecimal2.equals(bigDecimal3));
BigDecimal bigDecimal4 = new BigDecimal("1");
BigDecimal bigDecimal5 = new BigDecimal("1.0");
System.out.println(bigDecimal4.equals(bigDecimal5));
이상 코드,출력 결 과 는:true
true
false
BigDecimal 의 equals 원리
상기 코드 예 시 를 통 해 우 리 는 BigDecimal 의 equals 방법 으로 1 과 1.0 을 비교 할 때 어떤 때 는 true(int,double 로 BigDecimal 을 정의 할 때),어떤 때 는 false(String 으로 BigDecimal 을 정의 할 때)를 발견 했다.
그렇다면 왜 이런 상황 이 벌 어 졌 을 까?빅 데 시 멜 의 equals 방법 부터 살 펴 보 자.
BigDecimal 의 자바 독 에 서 는 그 이 유 를 설명 했다.
Compares this BigDecimal with the specified Object for equality. Unlike compareTo, this method considers two BigDecimal objects equal only if they are equal in value and scale (thus 2.0 is not equal to 2.00 when compared by this method)
대충 말 하면 equals 방법 과 compare To 는 다 르 고 equals 방법 은 두 부분 을 비교 하 는데 각각 값(value)과 정밀도(scale)이다.
대응 하 는 코드 는 다음 과 같 습 니 다.
그래서 우리 가 상기 코드 에서 정의 한 두 개의 BigDecimal 대상(bigDecimal 4 와 bigDecimal 5)의 정밀도 가 다 르 기 때문에 equals 를 사용 하여 비교 한 결 과 는 false 입 니 다.
코드 를 debug 하려 고 시도 합 니 다.debug 과정 에서 우 리 는 bigDecimal 4 의 정밀도 가 0 이 고 bigDecimal 5 의 정밀도 가 1 입 니 다.
여기 서 우 리 는 equals 가 bigDecimal 4 와 bigDecimal 5 를 비교 한 결과 false 인 이 유 는 정밀도 가 다 르 기 때 문 이 라 고 대충 설명 했다.
그렇다면 왜 정밀도 가 다 릅 니까?왜 bigDecimal 2 와 bigDecimal 3 의 정밀도 가 같 습 니까?
왜 정밀도 가 다 릅 니까?
이것 은 BigDecimal 의 정밀도 문제 와 관련된다.이 문 제 는 사실 비교적 복잡 하 다.본문의 중점 이 아니 기 때문에 이 안 에는 간단하게 소개 하 자.모두 가 흥 미 를 느끼 면 뒤에 따로 이야기 합 시다.
우선 빅 디 밀 은 다음 과 같은 4 가지 구조 방법 이 있다.
BigDecimal(int)
BigDecimal(double)
BigDecimal(long)
BigDecimal(String)
상기 네 가지 방법 으로 만들어 진 빅 데 시 멜 의 정밀 도 는 다르다.BigDecimal(long)과 BigDecimal(int)
우선,가장 쉬 운 것 은 BigDecimal(long)과 BigDecimal(int)입 니 다.정수 이기 때문에 정밀도 가 0 입 니 다.
public BigDecimal(int val) {
this.intCompact = val;
this.scale = 0;
this.intVal = null;
}
public BigDecimal(long val) {
this.intCompact = val;
this.intVal = (val == INFLATED) ? INFLATED_BIGINT : null;
this.scale = 0;
}
BigDecimal(double)한편,BigDecimal(double)에 대해 우리 가 new BigDecimal(0.1)을 사용 하여 BigDecimal 을 만 들 었 을 때 사실은 만들어 진 값 은 0.1 과 같은 것 이 아니 라 0.100000000000000055511151231257821181583454115625 이다.이것 은 doule 자체 가 표시 한 것 이 단지 근사치 이기 때문이다.
그러면 우리 가 new BigDecimal(0.1)을 사용 하 든 new BigDecimal(0.10)의 정 의 를 사용 하 든 그의 유사 치 는 모두 0.1000000000000000555111527272727181583454115625 라 는 것 이다.그러면 그의 정 도 는 바로 이 숫자의 자릿수,즉 55 이다.
다른 부동 소수점 도 마찬가지다.new BigDecimal(1.0)과 같은 형식 으로 볼 때 그 는 본질 적 으로 정수 이기 때문에 그 가 만 든 숫자의 정밀도 가 0 이다.
그래서 빅 디 밀(1.0)과 빅 디 밀(1.00)의 정밀도 가 같 기 때문에 equals 방법 으로 비교 할 때 얻 은 결 과 는 트 루 다.
BigDecimal(string)
그리고 BigDecimal(double)에 대해 우리 가 new BigDecimal(0.1)을 사용 하여 BigDecimal 을 만 들 었 을 때 사실은 만 든 값 은 0.1 과 같 습 니 다.그럼 그의 정밀 도 는 1 이다.
new BigDecimal("0.10000")을 사용 하면 만 든 수 는 0.10000 이 고 정밀도 가 5 입 니 다.
그래서 빅 디 밀('1.0')과 빅 디 밀('1.00')의 정밀도 가 다 르 기 때문에 equals 방법 으로 비교 할 때 얻 은 결 과 는 false 다.
어떻게 BigDecimal 을 비교 합 니까?
앞에서 우 리 는 BigDecimal 의 equals 방법 을 설 명 했 는데 사실은 숫자의 값 을 비교 할 뿐만 아니 라 그 정밀 도 를 비교 할 수 있다.
그래서 우리 가 equals 방법 으로 두 수의 일치 여 부 를 판단 할 때 매우 엄격 하 다.
그렇다면 우리 가 두 빅 디 밀 값 이 같은 지 판단 하고 싶다 면 어떻게 판단 해 야 할 까?
BigDecimal 에서 compare To 방법 을 제 공 했 습 니 다.이 방법 은 두 숫자의 값 만 비교 할 수 있 습 니 다.두 숫자 가 같 으 면 0 으로 돌아 갑 니 다.
BigDecimal bigDecimal4 = new BigDecimal("1");
BigDecimal bigDecimal5 = new BigDecimal("1.0000");
System.out.println(bigDecimal4.compareTo(bigDecimal5));
이상 코드,출력 결과:0
그 소스 코드 는 다음 과 같다.
총결산
BigDecimal 은 높 은 정밀도 의 숫자 를 나타 내 는 데 매우 좋 은 유형 으로 풍부 한 방법 을 제공 합 니 다.
그러나 그의 equals 방법 을 사용 할 때 신중 해 야 한다.왜냐하면 그 는 비교 할 때 두 숫자의 값 을 비교 할 뿐만 아니 라 그들의 정밀도 도 비교 할 수 있 기 때문이다.이 두 가지 요소 중 하나 가 같 지 않 으 면 결과 도 false 이다.
독자 가 두 개의 BigDecimal 수 치 를 비교 하려 면 compare To 방법 을 사용 할 수 있다.
알 리 바 바 가 왜 BigDecimal 의 equals 방법 을 사용 하 는 것 을 금지 하 는 지 에 대한 자세 한 설명 은 여기까지 입 니 다.더 많은 관련 금지 BigDecimal equals 방법 등 값 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부탁드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
실수의 표현방식 - 부동소수점(IEEE 754)지수부 무한 소수, 혹은 엄청 긴 소수점을 가지는 실수는 오차를 낼 수 밖에 없습니다. 아래 부동소수점으로 표현하는 방식을 보면 알 수 있습니다. 소수점의 이동 칸 수 + bios => 지수부 지수부(8bit) 가수...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.