답변:
>>
산술 시프트 오른쪽, >>>
논리 시프트 오른쪽입니다.
산술 시프트에서 부호 비트는 숫자의 부호를 유지하도록 확장됩니다.
예를 들어, 8 비트로 표현 된 -2는 11111110
(가장 중요한 비트는 음의 가중치를 가지므로)입니다. 산술 시프트를 사용하여 오른쪽으로 1 비트 이동하면 11111111
-1이됩니다. 그러나 논리적 인 오른쪽 이동은 값이 부호있는 숫자를 나타낼 수 있다는 것을 신경 쓰지 않습니다. 단순히 모든 것을 오른쪽으로 옮기고 왼쪽에서 0으로 채 웁니다. 논리 시프트를 사용하여 -2를 1 비트 오른쪽으로 시프트하면 다음과 같이 01111111
됩니다.
2^k
, 이것이 모두의 답변이라는 것이 이상하다는 것을 알게되었습니다. 비트 열은 숫자가 아니며 >>
항상 모든 비트 열에서 사용할 수 있습니다. 비트 열이 수행하는 역할과 '기호'개념이 있는지 여부에 관계없이 항상 동일한 작업을 수행합니다. 피연산자가 부호있는 숫자로 해석 되지 않는 경우에 대한 토론으로 이미 큰 대답을 확장해도 괜찮 습니까? 불만이 이해가 되나요?
String
로 간주 될 수 있다고 생각합니다 char[]
. 그는 a char
가 숫자가 아니라고 말하지 않고있다. 그는 단지 부호없는 숫자 라고 말하고 있습니다. 그가 잃어버린 곳이라고 생각합니다.
>>>
부호없는 시프트입니다. 0을 삽입 >>
하고 부호 비트를 확장합니다.
시프트 연산자에는 왼쪽 시프트
<<
, 부호있는 오른쪽 시프트>>
및 부호없는 오른쪽 시프트가>>>
있습니다.의 값은 부호 확장
n>>s
이있는n
오른쪽으로 이동 된s
비트 위치입니다 .의 값
n>>>s
이고n
오른쪽 시프트s
와 비트 위치 제로 확장 .
System.out.println(Integer.toBinaryString(-1));
// prints "11111111111111111111111111111111"
System.out.println(Integer.toBinaryString(-1 >> 16));
// prints "11111111111111111111111111111111"
System.out.println(Integer.toBinaryString(-1 >>> 16));
// prints "1111111111111111"
긍정적 인 대응 물을 더 명확하게하기 위해
System.out.println(Integer.toBinaryString(121));
// prints "1111001"
System.out.println(Integer.toBinaryString(121 >> 1));
// prints "111100"
System.out.println(Integer.toBinaryString(121 >>> 1));
// prints "111100"
양수이기 때문에 부호있는 시프트와 부호없는 시프트는 0을 가장 왼쪽 비트에 추가합니다.
그들은 둘 다 오른쪽 시프트하지만 >>>
입니다unsigned
로부터 문서 :
부호없는 오른쪽 시프트 연산자 ">>>"는 0을 가장 왼쪽 위치로 이동하고 ">>"뒤의 가장 왼쪽 위치는 부호 확장에 따라 다릅니다.
>>>
서명되지 않았다고 생각 하지만 왜 그럴까요 7>>32=7
? 나는 한 번에 한 번의 이동을 한 루프를 실행했으며 32
이동 후 다시 돌아 오는 것을 보았습니다 7
. 이것이 이해할 수있는 유일한 방법은 각 숫자가 바뀔 때마다 "외곽 원"에 들어갔다는 것입니다. 32
교대 후 , 그것은 어떻게 든 다시 원래 위치에 도달했지만 분명히 그것은 여전히 타당하지 않습니다. 무슨 일이야?
논리 오른쪽 시프트 ( v >>> n
)는 비트 위치에서 비트 v
가 오른쪽으로 시프트 n
되고 0이 왼쪽에서 시프트 된 값을 반환합니다 . 이진수로 작성된 8 비트 값의 이동을 고려하십시오.
01111111 >>> 2 = 00011111
10000000 >>> 2 = 00100000
비트를 부호없는 음이 아닌 정수로 해석하면 논리 오른쪽 이동은 숫자를 해당하는 2의 거듭 제곱으로 나누는 효과가 있습니다. 그러나 숫자가 2의 보수 표현 인 경우 논리 오른쪽 이동은 음수를 올바르게 나누지 않습니다. . 예를 들어, 비트가 부호없는 숫자로 해석 될 때 위의 두 번째 오른쪽 이동은 128에서 32로 이동합니다. 그러나 Java에서 일반적인 것처럼 비트가 2의 보수로 해석되면 -128에서 32로 이동합니다.
따라서 2의 거듭 제곱으로 나누기 위해 이동하는 경우 산술 오른쪽 이동 ( v >> n
)이 필요합니다. 비트 위치에서 비트 v
가 오른쪽으로 이동 한 값을 반환하고 v의 가장 왼쪽 비트의n
사본이 왼쪽 에서 이동 된 값을 반환합니다 .
01111111 >> 2 = 00011111
10000000 >> 2 = 11100000
비트가 2의 보수 표현의 숫자 인 경우, 산술 오른쪽 시프트는 2의 거듭 제곱으로 나눠지는 효과가 있습니다. 가장 왼쪽 비트가 부호 비트이기 때문에 작동합니다. 2의 거듭 제곱으로 나누면 부호가 동일하게 유지되어야합니다.
비트 단위 및 비트 시프트 연산자 에 대해 자세히 알아보십시오
>> Signed right shift
>>> Unsigned right shift
비트 패턴은 왼쪽 피연산자에 의해 제공되며 오른쪽 피연산자에 의해 이동할 위치 수입니다. 부호 오른쪽 시프트 연산자 >>>
이동 제로 가장 좌측에 위치를 ,
가장 왼쪽 위치 >>
는 부호 확장에 따라 다릅니다.
간단히 말해서 >>>
항상 0 을 가장 왼쪽 위치로 이동시키는 반면 >>
숫자의 부호를 기준으로 이동합니다. 즉 음수의 경우 1, 양수의 경우 0입니다.
예를 들어 양수뿐만 아니라 음수도 사용하십시오.
int c = -153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.println(Integer.toBinaryString(c <<= 2));
System.out.println();
c = 153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
산출:
11111111111111111111111111011001
11111111111111111111111101100100
111111111111111111111111011001
11111111111111111111111101100100
100110
10011000
100110
10011000
System.out.println(Integer.MAX_VALUE + ": " + String.format("%32s", Integer.toBinaryString(Integer.MAX_VALUE)).replace(' ', '0'))
; 정수 MAX_VALUE : 01111111111111111111111111111111;
정수 MIN_VALUE : 10000000000000000000000000000000;
-1 : 11111111111111111111111111111111;
0 : 00000000000000000000000000000000;
1 : 00000000000000000000000000000001
오른쪽 시프트 논리 연산자 ( >>> N
)는 비트를 N 위치 만큼 오른쪽으로 시프트 하여 부호 비트를 버리고 N 가장 왼쪽 비트를 0으로 채 웁니다. 예를 들면 다음과 같습니다.
-1 (in 32-bit): 11111111111111111111111111111111
>>> 1
작업이 된 후 :
2147483647: 01111111111111111111111111111111
오른쪽 시프트 산술 연산자 ( >> N
)는 비트를 N 위치만큼 오른쪽으로 시프트하지만 부호 비트는 유지하고 N 가장 왼쪽 비트는 1로 채 웁니다. 예를 들면 다음과 같습니다.
-2 (in 32-bit): 11111111111111111111111111111110
>> 1
작업이 된 후 :
-1: 11111111111111111111111111111111