코드를 약간 리팩토링하고 모든 표현식을 자체 줄에 유지하면 더 명확 해집니다.
var에 pos
및 MODULO
모두 범위 -2147483648과 2147483647
공지 사항에서 할 수있는, 즉 정확하게 : Integer.MAX_VALUE
== 2147483647
.
이
public static void main(String[] args) {
System.out.println("result: "
+ normalize(Integer.MAX_VALUE-1, Integer.MAX_VALUE));
System.out.println();
System.out.println("result: "
+ normalizeWithoutLongCast(Integer.MAX_VALUE-1, Integer.MAX_VALUE));
}
static int normalize(int pos, int MODULO) {
System.out.println("normalize()");
long mod = pos % MODULO;
System.out.println("mod: "+mod);
long sum = mod + MODULO; // this is where the overflow can occur
System.out.println("sum: "+sum);
return (int) (sum % MODULO);
}
static int normalizeWithoutLongCast(int pos, int MODULO) {
System.out.println("normalizeWithoutLongCast()");
int mod = pos % MODULO;
System.out.println("mod: "+mod);
int sum = mod + MODULO; // this is where the overflow can occur
System.out.println("sum: "+sum);
return (int) (sum % MODULO);
}
출력은 : 당신이 볼 수있는
normalize()
mod: 2147483646
sum: 4294967293
result: 2147483646
normalizeWithoutLongCast()
mod: 2147483646
sum: -3
result: -3
그래서, 문제가 sum = mod + MODULO;
단계에서 정확하게 발생 가장자리 케이스 (pos
가능한 한 큰 MODULO
)를 가지고가는 것은 좋은 예이다. MODULO
가 될 수
단지 약
Integer.MAX_VALUE
, 즉 행
1
정수 (정수 오버플로)보다 큰 값을 반환
만큼 약간 첨가 의미한다. 마찬가지로 이전 단계 (mod = pos2 % MODULO
)에서 mod
이 1
일 수 있으므로 오버플로가 발생할 수 있습니다.
캐스팅을 long
으로하면 오버플로가 염려없이 합계가 발생합니다. 물론 결과가 int
이 되려면 캐스트가 문제가 될 수 있습니다.
다행히도 마지막 표현식의 값 (sum % MODULO
)이 0
과 MODULO
사이이므로 문제가되지 않습니다. 그리고 MODULO
은 최대로 Integer.MAX_VALUE
(2147483647
) 일 수 있으므로 유효한 정수이므로 int
으로 다시 캐스팅 할 수 있습니다.
정상적인 int 범위 밖에서 값을 캡처 할 수 있습니다. 그런 다음 'int'로 캐스트하면'-2^32' 및 '2^32-1'외부의 값은 절사됩니다 또는 위로 각각. –