나는 영국 대학 시험에서 고급 프로그래밍 과정에서이 퍼즐을 넘었다 .
i가 지금까지 선언되지 않은 다음 루프를 고려하십시오.
while (i == i + 1) {}
while 루프가 영원히 계속되도록i
이 루프 앞에 있는의 정의를 찾으십시오 .
이 코드 스 니펫에 대해 동일한 질문을 던진 다음 질문 :
while (i != i) {}
나에게 분명했다. 물론이 다른 상황에서는 NaN
그렇습니다.하지만 저는 이전 상황에 갇혀 있습니다. 이것이 오버플로와 관련이 있습니까? 이러한 루프가 Java에서 영원히 반복되는 원인은 무엇입니까?
답변
우선, while (i == i + 1) {}
루프는의 값을 변경하지 않기 i
때문에이 루프를 무한대로 만드는 i
것은 만족 하는 값을 선택하는 것과 같습니다 i == i + 1
.
다음과 같은 많은 값이 있습니다.
“이국적인”것부터 시작해 보겠습니다.
double i = Double.POSITIVE_INFINITY;
또는
double i = Double.NEGATIVE_INFINITY;
이러한 값이 만족하는 이유 i == i + 1
는
JLS 15.18.2에 명시되어 있습니다. 숫자 유형에 대한 더하기 연산자 (+ 및-) :
무한대와 유한 값의 합은 무한 피연산자와 같습니다.
무한 값에 유한 값을 추가하면 무한 값이 생성되므로 이는 놀라운 일이 아닙니다.
즉, i
만족 하는 대부분의 값 i == i + 1
은 단순히 큰 double
(또는 float
) 값입니다.
예를 들면 :
double i = Double.MAX_VALUE;
또는
double i = 1000000000000000000.0;
또는
float i = 1000000000000000000.0f;
double
및 float
유형은 충분히 큰 걸릴 그렇다면, 제한된 정밀도를 가지고 double
또는 float
추가 값을 1
같은 값 발생합니다 그것.
답변
이 퍼즐은 Joshua Bloch와 Neal Gafter의 “Java Puzzlers : Traps, Pitfalls, and Corner Cases”책에 자세히 설명되어 있습니다.
double i = Double.POSITIVE_INFINITY;
while (i == i + 1) {}
또는:
double i = 1.0e40;
while (i == i + 1) {}
둘 다 무한 루프가됩니다. 왜냐하면 1
충분히 큰 부동 소수점 값을 추가해도 값이 변경되지는 않기 때문입니다. 그 이유는 후속 작업 1과 “격차를 해소”하지 않기 때문 입니다.
두 번째 퍼즐에 대한 참고 사항 (미래 독자 용) :
double i = Double.NaN;
while (i != i) {}
또한 NaN은 자체 2를 포함하여 부동 소수점 값과 같지 않기 때문에 무한 루프 가 발생합니다 .
1-Java Puzzlers : 함정, 함정 및 코너 케이스 (4 장-Loopy Puzzlers).
2- JLS §15.21.1
답변
double i = Double.POSITIVE_INFINITY;
답변
아이디어 : 부울은 어떻습니까?
bool i = TRUE;
이 경우가 i + 1 == i
아닌가?