다음과 같은 if
상태입니다.
if (i == -i && i != 0)
Java에서이 조건에 대해 어떤 값 i
이 반환 true
됩니까?
Java에서 2의 보수 표기법 을 i
고려 하는 것과 같은 가치를 생각할 수 없습니다 .
나는 또한이 조건이 (Java와의 맥락에서) 어떤 답을 가지고 있는지에 대한 대수적 증거를 갖고 싶습니까?
답변
int
작동하는 유일한 값은 Integer.MIN_VALUE
입니다.
2의 보수 방식을 사용하여 정수가 부정되기 때문 입니다.
사용
System.out.println(Integer.toBinaryString(Integer.MIN_VALUE));
당신 Integer.MIN_VALUE
은
10000000000000000000000000000000
음의 값을 고려하여 제 스와핑에 의해 수행 0
및 1
제공되는
01111111111111111111111111111111
추가 1
하면
10000000000000000000000000000000
내가 준 링크에서 볼 수 있듯이 Wikipedia는 가장 많은 음수로 문제를 언급하고 유일한 예외라고 지정합니다.
2의 보수에서 가장 음수는 유일한 예외이기 때문에 때때로 “이상한 숫자”라고 불립니다.
물론 변수에 Long.Min_Value
저장하면 동일한 현상이 발생합니다 long
.
참고 이 자바의 int의 바이너리 저장에 관한 만들어진 선택에만 때문이다 . 예를 들어 다른 (나쁜) 해결책은 단순히 최상위 비트를 변경하고 다른 비트를 변경하지 않고 부정하는 것이었을 수 있습니다. 이것은 MIN_VALUE로이 문제를 피할 수 있었지만 2 개의 다른 0
값과 복잡한 이진 산술 을 만들었 을 것입니다. 예를 들어?).
답변
당신이 찾고있는 가치는 Integer.MIN_VALUE
입니다.
나는 또한이 조건이 (자바와의 맥락에서) 어떤 답을 가지고 있는지에 대한 대수적 증거를 갖고 싶습니다.
Stack Exchange에서는 주제를 벗어났습니다. 그러나 Java 정수 ( JLS 4.2 ) 의 정의부터 시작할 수 있습니다.
“정수 유형은 byte, short, int 및 long이며 값은 8 비트, 16 비트, 32 비트 및 64 비트 부호있는 2의 보수 정수입니다.”
과
“정수 유형의 값은 다음 범위의 정수입니다 … int의 경우 -2147483648에서 2147483647까지 포함”
그리고 Java 단항 ‘-‘연산자의 정의 ( JLS 15.15.4 ) :
“정수 값의 경우 부정은 0에서 빼는 것과 동일합니다. Java 프로그래밍 언어는 정수에 대해 2의 보수 표현을 사용하고 2의 보수 값의 범위는 대칭이 아니므로 최대 음의 int 또는 long을 부정하면 결과가 나타납니다. 동일한 최대 음수입니다.이 경우 오버플로가 발생하지만 예외는 발생하지 않습니다. 모든 정수 값 x에 대해 -x는 (~ x) +1과 같습니다. “
답변
지금까지 주어진 답변 외에도 …
총 4 개의 값이 있습니다.
int i = Integer.MIN_VALUE;
long i = Long.MIN_VALUE;
Integer i = Integer.valueOf(Integer.MIN_VALUE);
Long i = Long.valueOf(Long.MIN_VALUE);
래핑 된 값은 래핑 해제되므로이 식에도 적용됩니다.
참고 : Math.abs 문서.
public static int abs (int a)
int 값의 절대 값을 반환합니다. 인수가 음수가 아니면 인수가 반환됩니다. 인수가 음수이면 인수의 부정이 반환됩니다.
인수가 가장 음의 표현 가능한 int 값인 Integer.MIN_VALUE의 값과 같으면 결과는 동일한 값인 음수입니다.
과
public static long abs (long a)
long 값의 절대 값을 반환합니다. 인수가 음수가 아니면 인수가 반환됩니다. 인수가 음수이면 인수의 부정이 반환됩니다.
인수가 가장 음의 표현 가능한 long 값인 Long.MIN_VALUE의 값과 같으면 결과는 동일한 값인 음수입니다.
Math.abs가 음수를 반환 할 수 있다는 것은 놀라운 일입니다. 이는 a) 이러한 경우 -MIN_VALUE에 대한 양수 값이 없기 때문에 발생합니다. b) -
계산을 수행 하면 오버플로가 발생합니다.
또한 흥미로운 것은 Byte.MIN_VALUE, Short.MIN_VALUE가이를 수행하지 않는 이유입니다. 이는 이러한 -
유형에 int
대해 유형 이 변경되어 오버플로가 발생하지 않기 때문 입니다.
Character.MIN_VALUE는 0이므로 문제가 없습니다.
Float.MIN_VALUE 및 Double.MIN_VALUE는 다른 의미를 갖습니다. 0보다 큰 표현 가능한 가장 작은 값입니다. 따라서 그들은 그 자체가 아닌 유효한 음수 값을 가지고 있습니다.
답변
다른 사람들이 언급했듯이 이것은 Integer.MIN_VALUE
. 증명에 관해서는 이진법이 아닌 이해하기 쉬운 설명을 제공하겠습니다.
참고 Integer.MIN_VALUE
동일 -2^31
또는 -2147483648
과 Integer.MAX_VALUE
동일 2^31-1
또는 2147483647
. -Integer.MIN_VALUE
is 2^31
, Integer에 비해 너무 커서 (과거 MAX_VALUE
이므로) Integer 오버플로가 발생하여 Integer.MIN_VALUE
다시 만듭니다. MIN_VALUE
0을 제외하고는 음수에 해당하지 않는 유일한 숫자 이기 때문에이를 수행하는 유일한 정수입니다 .
답변
modulo 2^32
산술을 사용한 임시 대수 증명 :
i == -i
로 쓸 수있다 2 * i == 0
(이 추가 i
양면) 또는 i << 1 == 0
.
이 방정식에는 두 가지 형태의 해가 있습니다 i == 0 >> 1
. 즉 0b
, 10000000000000000000000000000000b
하나 0
또는 1
왼쪽 으로 이동하여 얻습니다 .
i == 0
제외 되는 솔루션 은 남아 있습니다 i == 100000000000000000000000000000000b
.
답변
너무 교육적이지 않을 수도 있지만 생각하는 대신 다음 코드를 실행할 수 있습니다.
for (int i = Integer.MIN_VALUE; i <= Integer.MAX_VALUE; i++)
{
if (i == -i && i != 0)
{
System.out.println(i);
}
}
그것이 인쇄되는 것을보기 위해
-2147483648
-2147483648
무한히 🙂