나는 것으로 나타났습니다 java.lang.Integer
구현 compareTo
메서드는 다음과 같이 외모를 :
public int compareTo(Integer anotherInteger) {
int thisVal = this.value;
int anotherVal = anotherInteger.value;
return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}
문제는 빼기 대신 비교를 사용하는 이유입니다.
return thisVal - anotherVal;
답변
이것은 정수 오버플로 때문입니다. 경우 thisVal
매우 크고, anotherVal
그 이전부터 수율 인 결과 후자를 뺀 부정보다 더 큰 thisVal
어떤 음 범위 넘칠 수있다.
답변
두 숫자 값을 비교하는 뺄셈 “트릭”이 깨졌습니다 !!!
int a = -2000000000;
int b = 2000000000;
System.out.println(a - b);
// prints "294967296"
여기, a < b
아직 a - b
긍정적입니다.
이 관용구를 사용하지 마십시오. 작동하지 않습니다.
또한, 이 작업을 수행하더라도 , 그것은 것입니다 NOT 사실 비용 가독성에 상당한 성능 향상, 그리고 5 월을 제공합니다.
또한보십시오
- Java Puzzlers Puzzle 65 : 수상한 종류의 이상한 사가
이 퍼즐에는 몇 가지 교훈이 있습니다. 가장 구체적인 내용은 다음과 같습니다. 값 간의 차이가 절대로 크지 않을 것이라는 확신이없는 한 빼기 기반 비교기를 사용하지 마십시오
Integer.MAX_VALUE
. 보다 일반적으로int
오버플로에 주의하십시오 . 또 다른 교훈은 “영리한”코드를 피해야한다는 것입니다. 명확하고 올바른 코드를 작성하기 위해 노력하고 필요한 것으로 입증되지 않는 한 최적화하지 마십시오.
답변
간단히 말해서, int
유형은 두 임의 int
값 간의 차이를 저장할만큼 충분히 크지 않습니다 . 예를 들어 15 억에서 -15 억 사이의 차이는 30 억이지만 int
21 억보다 큰 값을 가질 수 없습니다.
답변
아마도 오버플로 / 언더 플로를 피하는 것입니다.
답변
오버플로 외에도 빼기 가 있는 버전 은 동일한 결과를 제공하지 않는다는 점에 유의해야 합니다 .
- 첫 번째 compareTo 버전은 -1, 0 또는 1의 세 가지 가능한 값 중 하나를 반환합니다.
- 마지막 줄을 빼기로 바꾸면 결과는 정수 값이 될 수 있습니다.
오버플로가 없다는 것을 알고 있다면 다음과 같이 사용할 수 있습니다.
public int compareTo(Integer anotherInteger) {
return sign(this.value - anotherInteger.valuel);
}