2012-03-26 2 views
6

왜 자바 -2147483648을 반환하지 결과 예상 반환하지 않습니다?비트 시프트 조작을

예상 결과

.. 볼프람 알파 내 계산기 실험 9 223 372 036 854 775 808 인 I 시험 :

System.out.print ((길이) (1 < < (63)));

답변

27

은 긴 캐스팅 먼저 다음 (1 << 63)을 라인에 대해

System.out.print((long)(1 << (63))); 

을 주목해야 할 중요한 일이있다. 결과적으로, 실제로는 왼쪽으로 시프트하면서 정수가되므로 긴 캐스트는 효과가 없습니다. 이것이 63 비트 왼쪽으로 시프트하는 것이 min보다 오히려 최소 정수를 제공하는 이유입니다.

하지만 또 다른 중요한 점이 있습니다. Java long은 항상 서명되어 있으므로 심지어 라인이

System.out.print(1L << 63); 

이 음수가됩니다. 2의 보수로, 가장 왼쪽 비트가 1 일 때마다 숫자는 음수입니다.

그 숫자가 최대 길이보다 큰 있기 때문에 실제로, 숫자 2 자바 원시 형의 = 9223372036854775808 63을 대표 할 수 없으며, long 최대 원시 형이다. 하지만이 번호는 BigInteger으로 표시 할 수 있습니다. 심지어 코드

BigInteger.ONE.shiftLeft(63) 
+0

오, 고마워요, 지금은 정말 분명합니다 –

+0

+1, 실용적인 솔루션도 포함되어 있습니다. 추신. 나는 당신이 2^63을 좀 더 읽기 쉬운 것으로 편집하도록 자유를 가져 갔다고 생각하지 않기를 바란다. – amit

+0

@amit 아니, 전혀 괜찮습니다. 감사! –

6

만약 integer overflow [배] 데 함께 63 좌측 시프트를 통해 생성 할 수있다.

1 << 32 == 1 
1 << 31 == -2147483648 [ becuase this is the binary representation in 2's complement for -2147483648] 
1 << 63 == 1 << (32 + 31) == (1 << 32) << 31 == 1 << 31 == -2147483648 

당신이 (long)(1 << (63))

당신은 단지 long에 [ -2147483648입니다] 1 << (63)의 결과를 캐스팅 - 그리고 그것의 값을 변경하지 않습니다.

+0

넘쳐 흐르는 것을 설명해 주셔서 감사합니다! 나는이 코드에 대한 설명을 OpenJDK의 BitSet 구현에서 찾았다. [long firstWordMask = WORD_MASK << fromIndex; long lastWordMask = WORD_MASK >>> -InIndex; ]이 경우 WORD_MASK는 길지만. – ruizpauker

관련 문제