JavaScript에서 산술 오른쪽 시프트와 음수의 논리적 오른쪽 시프트는 매우 혼란스럽습니다. 특히 논리적 오른쪽 시프트 >>>는 작은 음수라도 오른쪽 시프트 후에 매우 큰 숫자를 얻게 된다는 것을 알게 될 것입니다.
논리적 오른쪽 시프트에서는 부호 비트가 전체와 함께 오른쪽으로 이동하는 것으로 나타났습니다. 이는 부호가 없는 숫자의 이동과 동일합니다. 비트가 존재하지 않습니다. 먼저 논리적 오른쪽 시프트는 32비트 숫자를 생성해야 하며, 그 다음 음수의 부호 비트가 1이 되는데, 이는 32번째 비트부터 부호 비트까지의 위치가 모두 1로 채워진다는 것을 의미합니다. small? 예를 들어 -1, 논리 0비트만큼 오른쪽으로 이동한다는 표현은 1111 1111 1111 1111 1111 1111 1111 1111입니다. 이런 숫자는 양수로 처리됩니다! 따라서 -1이 논리적으로 N 비트만큼 오른쪽으로 이동하면 최종 결과는 모두 1이 됩니다!
왼쪽 시프트 연산은 숫자의 부호 비트를 유지합니다. 예를 들어, -2를 왼쪽으로 5비트 이동하면 64 대신 -64가 됩니다. "기호가 여전히 비트 32에 저장되어 있습니까?" 예, 그러나 이는 ECMAScript의 뒤에서 발생하며 개발자는 비트 32에 직접 액세스할 수 없습니다. 음수가 바이너리 문자열로 출력되더라도 마이너스 부호로 표시됩니다(예를 들어 -2를 입력하면 -10이 표시됩니다.)
부호 있는 오른쪽 시프트 연산
예 기호 오른쪽 시프트 연산자는 두 개의 보다 큰 기호(
var iOld = 64; //이진수 1000000과 동일
var iNew = iOld >> 5; 십진수 2. 마찬가지로 숫자를 이동하면 빈 공간이 생성됩니다. 이번에는 빈 비트가 숫자 왼쪽에 있지만 부호 비트 뒤에 있습니다. ECMAScript는 이러한 빈 비트를 부호 비트 값으로 채워 아래와 같이 완전한 숫자를 생성합니다.
부호 없는 오른쪽 시프트 연산자
부호 없는 오른쪽 시프트 연산자는 다음과 같습니다. 3보다 큼 기호(>>>)로 주어진 것은 부호 없는 32비트 숫자의 모든 숫자를 전체적으로 오른쪽으로 이동한다는 의미입니다. 양수의 경우 부호 없는 오른쪽 시프트 연산의 결과는 부호 있는 오른쪽 시프트 연산과 동일합니다.
부호 있는 오른쪽 시프트 연산의 예를 사용하면 64를 오른쪽으로 5비트만큼 시프트하면 2가 됩니다.
부호 없는 오른쪽 시프트 연산은 모든 빈 비트를 0으로 채웁니다. 양수의 경우 부호 있는 오른쪽 시프트 연산과 동일하게 작동하고 음수는 양수로 처리됩니다.
부호 없는 오른쪽 시프트 연산의 결과는 32비트 양수이므로 음수의 부호 없는 오른쪽 시프트 연산은 항상 매우 큰 숫자가 됩니다. 예를 들어 -64를 오른쪽으로 5비트 이동하면 134217726이 됩니다. 이런 결과가 나오면 어떨까요?
이를 달성하려면 숫자를 부호 없는 값으로 변환해야 합니다(숫자 자체는 여전히 부호가 있지만). 이는 다음 코드를 사용하여 얻을 수 있습니다:
var iUnsigned64 = -64 >>> 0;
그런 다음 숫자 유형의 toString()을 사용하여 기본 2를 사용하여 실제 비트 표현을 가져옵니다. 코드는 다음과 같습니다.
alert(iUnsigned64 .toString(2) ));
이것은 부호 있는 정수 -64의 2의 보수 표현인 1111111111111111111111111000000을 생성하지만 부호 없는 정수 4294967232와 같습니다.
이러한 이유로 부호 없는 오른쪽 시프트 연산자를 사용할 때는 주의하세요.
이제 음수의 산술적 오른쪽 이동에 대해 이야기해 보겠습니다.>>:
-9>>2=-3이라는 것을 알았는데, 왜 -3인가요?
우선 부호 비트는 변경되지 않고 오른쪽 시프트에 참여하지 않습니다. 그런 다음 9의 오른쪽 시프트 중에 가장 낮은 비트가 1이면 오른쪽 이후에도 가장 낮은 비트가 1입니다. 옮기다! 이것은 매우 이상합니다.