ECMAScript 비트 연산자

비트 연산자는 숫자의 하위(즉, 숫자를 나타내는 32개의 비트)에서 작업을 수행합니다.

정수 다시 보기

ECMAScript 정수는 두 가지 유형이 있습니다. 부호 있는 정수(양수와 음수를 허용)와 부호 없는 정수(양수만 허용). ECMAScript에서 모든 정수 리터럴은 기본적으로 부호 있는 정수로 간주되며, 이는 무엇을 의미하는 걸까요?

부호 있는 정수는 31비트로 정수의 값을 나타내고, 32번째 비트는 정수의 부호를 나타냅니다. 0은 양수를 나타내고, 1은 음수를 나타냅니다. 범위는 -2147483648에서 2147483647입니다.

부호 있는 정수는 두 가지 방식으로 이진 형태로 저장될 수 있습니다. 하나는 양수를 저장하는 데 사용되고, 하나는 음수를 저장하는 데 사용됩니다. 양수는 진이진 형태로 저장되며, 앞 31비트의 각 비트는 2의 권한을 나타내며, 1번째 비트(비트 0)에서 시작하여 2를 나타냅니다.02를 나타내는 2번째 비트(비트 1)1사용되지 않은 비트는 0으로 채워지고, 무시됩니다. 예를 들어, 다음 그림은 숫자 18의 표현법을 보여줍니다。

32 비트 이진 표현의 부호 있는 정수

18의 이진 버전은 앞 5비트만 사용하고, 이들은 이 숫자의 유효 비트입니다. 숫자를 이진 문자열로 변환하면 유효 비트를 볼 수 있습니다:

var iNum = 18;
alert(iNum.toString(2));	// "10010" 출력

이 코드는 "10010"을 출력만 하고, 18의 32비트 표현은 아닙니다. 다른 자리수는 중요하지 않습니다. 왜냐하면 5비트만 사용하여 이 십진수를 결정할 수 있기 때문입니다. 다음 그림을 참고하세요:

5 비트 이진 표현의 정수 18

부정수도 이진 코드로 저장됩니다. 그러나 이진 보수 형태로 저장됩니다. 숫자의 이진 보수를 계산하는 단계는 세 가지 있습니다.

  1. 이 수의 비부호 버전의 이진 표현을 결정해야 합니다(예를 들어, -18의 이진 보수를 계산하려면, 먼저 18의 이진 표현을 결정해야 합니다)
  2. 이진 반전 코드를 구하기 위해서는 0을 1로, 1을 0으로 대체해야 합니다
  3. 이진 반전 코드에 1을 더합니다

-18의 이진 표현을 결정하려면, 먼저 18의 이진 표현을 얻어야 합니다:

0000 0000 0000 0000 0000 0000 0001 0010

다음은 이진 반전 코드를 계산하는 방법입니다:

1111 1111 1111 1111 1111 1111 1110 1101

마지막으로, 이진 반전 코드에 1을 더해보세요:

1111 1111 1111 1111 1111 1111 1110 1101
                                      1
---------------------------------------
1111 1111 1111 1111 1111 1111 1110 1110

따라서 -18의 이진 표현은 1111 1111 1111 1111 1111 1111 1110 1110입니다. 기억하시길, 부호 있는 정수를 처리할 때 개발자는 31번째 비트에 접근할 수 없습니다.

有趣的是,부정수를 이진 문자열로 변환하면 ECMAScript는 이진 보수의 형태로 표시하지 않고, 부호를 앞에 추가된 숫자의 절대값의 표준 이진 코드를 사용하여 출력합니다. 예를 들어:

var iNum = -18;
alert(iNum.toString(2)); // "-10010" 출력

이 코드는 "-10010"을 출력하며, 비트 31에 접근하지 않기 위해 이렇게 합니다. 간편성을 위해 ECMAScript는 간단한 방식으로 정수를 처리하여 개발자가 그들의 사용에 대해 걱정하지 않도록 합니다.

그러나 부호 없는 정수는 마지막 비트를 또 다른 비트로 처리합니다. 이 모드에서 32번째 비트는 숫자의 부호를 나타내지 않고, 값 2를 나타냅니다.31이 추가 비트로 인해 부호 없는 정수의 값 범위는 0에서 4294967295입니다. 2147483647보다 작은 정수의 경우 부호 있는 정수와 유사하게 보이지만, 2147483647보다 큰 정수의 경우 비트 31(부호 있는 정수에서 항상 0)을 사용해야 합니다.

부호 없는 정수를 문자열로 변환하면, 그들의 유효 비트만 반환됩니다.

주의:모든 정수 상수는 기본적으로 부호 있는 정수로 저장됩니다. ECMAScript의 비트 연산자 만이 부호 없는 정수를 생성할 수 있습니다.

비트 연산 NOT

비트 연산 NOT은 반대 기호(~)로 표시되며, ECMAScript에서 비트 연산자 중 비트 연산의 하나입니다.

비트 연산 NOT은 세 단계의 처리 과정을 거치는 것입니다:

  1. 연산자를 32비트 숫자로 변환
  2. 이진수를 이진 반대수로 변환
  3. 이진수를 부동소수점 수로 변환

예를 들어:

var iNum1 = 25;		// 25는 00000000000000000000000000011001입니다
var iNum2 = ~iNum1;	// 11111111111111111111111111100110로 변환
alert(iNum2);		// "-26" 출력

비트 연산 NOT은 숫자를 음수로 변환한 후 1을 뺀 것으로 실제로는, 25는 -26으로 변환됩니다. 다음과 같은 방법으로도 같은 결과를 얻을 수 있습니다:

var iNum1 = 25;
var iNum2 = -iNum1 -1;
alert(iNum2);	// "-26" 출력

비트 연산 AND

비트 연산 AND는 기호(&)로 표시되며, 숫자의 이진 형식에 직접 연산을 수행합니다. 각 숫자의 자리를 맞추고, 동일한 위치의 두 자리에 대해 다음과 같은 규칙을 사용하여 AND 연산을 수행합니다:

첫 번째 숫자의 비트 두 번째 숫자의 비트 결과
1 1 1
1 0 0
0 1 0
0 0 0

예를 들어, 25와 3을 AND 연산하려면 다음과 같은 코드입니다:

var iResult = 25 & 3;
alert(iResult);	// "1" 출력

25와 3이 AND 연산의 결과는 1입니다. 왜 그런가요? 다음과 같이 분석할 수 있습니다:

 25 = 0000 0000 0000 0000 0000 0000 0001 1001
  3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
AND = 0000 0000 0000 0000 0000 0000 0000 0001

25와 3에서 단 하나의 자리수(0번 자리)만 1로 채워져 있기 때문에, 다른 자리수는 모두 0으로 생성되어 결과는 1입니다.

비트 연산 OR

비트 연산 OR은 기호(|)로 표시되며, 숫자의 이진 형식에 직접 연산을 수행합니다. 각 자리를 계산할 때, OR 연산자는 다음과 같은 규칙을 사용합니다:

첫 번째 숫자의 비트 두 번째 숫자의 비트 결과
1 1 1
1 0 1
0 1 1
0 0 0

AND 연산자를 사용한 예제를 계속 사용하여 25와 3을 OR 연산하면 다음과 같은 코드입니다:

var iResult = 25 | 3;
alert(iResult);	// "27" 출력

25와 3이 OR 연산의 결과는 27입니다:

25 = 0000 0000 0000 0000 0000 0000 0001 1001
 3 = 0000 0000 0000 0000 0000 0000 0000 0011
--------------------------------------------
OR = 0000 0000 0000 0000 0000 0000 0001 1011

두 수 중에서 4 개의 자리수가 1로 채워져 있으며, 이 자리수가 결과로 전달됩니다. 이진 코드 11011은 27입니다.

비트 연산 XOR

비트 연산 XOR는 부호(^)로 표시되며, 물론 이진 형식에 직접 연산됩니다. XOR는 OR와 다릅니다. 한 비트가 1로 저장된 경우에만 1을 반환합니다. 진리 표는 다음과 같습니다:

첫 번째 숫자의 비트 두 번째 숫자의 비트 결과
1 1 0
1 0 1
0 1 1
0 0 0

25과 3을 XOR 연산하는 코드는 다음과 같습니다:

var iResult = 25 ^ 3;
alert(iResult);	//출력 "26"

25과 3을 XOR 연산한 결과는 26입니다:

 25 = 0000 0000 0000 0000 0000 0000 0001 1001
  3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
XOR = 0000 0000 0000 0000 0000 0000 0001 1010

두 숫자에서, 1이 저장된 비트는 총 4개입니다. 이 비트는 결과로 전달됩니다. 이진 코드 11010은 26입니다.

왼쪽 이동 연산

왼쪽 이동 연산은 두 개의 작은 부호로 표시됩니다(<<)。그것은 숫자의 모든 비트를 지정된 수량으로 왼쪽으로 이동시킵니다. 예를 들어, 숫자 2(이진 10으로 동일)를 5비트로 왼쪽으로 이동하면, 결과는 64(이진 1000000으로 동일)입니다:

var iOld = 2;		//이진 10
var iNew = iOld << 5;	//이진 1000000 십진수 64

주의:왼쪽 이동 비트를 이동할 때, 숫자의 오른쪽에 5개의 공백 비트가 추가됩니다. 왼쪽 이동 연산은 이 비트를 0으로 채우고, 결과를 완전한 32비트 숫자로 만듭니다.

숫자 2를 왼쪽으로 이동 연산

주의:왼쪽 이동 연산은 숫자의 부호 비트를 유지합니다. 예를 들어, -2를 5비트로 왼쪽으로 이동하면 -64를 얻습니다. “부호는 여전히 32비트에 저장되어 있습니까?”는 물론입니다. 그러나 이는 ECMAScript 백엔드에서 수행되며, 개발자는 32번째 비트를 직접 접근할 수 없습니다. 음수의 이진 문자열 형식을 출력하면, 표시되는 것도 음수 형식입니다(예를 들어, -2는 -10으로 표시됩니다。)

부호 정수 이동 연산

부호 정수 이동 연산자는 두 개의 큰 부호로 표시됩니다(>>)。그것은 32비트 숫자의 모든 비트를 전체로 오른쪽으로 이동시키고, 해당 숫자의 부호(양수 또는 음수)를 유지합니다.부호 정수 이동 연산자는 왼쪽 이동 연산과 정 반대입니다. 예를 들어, 64를 5비트로 오른쪽으로 이동하면 2로 변환됩니다:

var iOld = 64; // 이진 1000000
var iNew = iOld >> 5; // 이진 10, 십진수 2

동일하게, 비트 이동 후 공백이 생깁니다. 이번에는 공백이 숫자의 왼쪽에 있지만, 기호 비트 이후에 있습니다. ECMAScript는 기호 비트의 값을 사용하여 이 공백을 채우고, 완전한 숫자를 생성합니다. 다음 그림과 같이 보여집니다:

숫자 64를 부호 있는 오른쪽으로 이동 연산

유서지 않은 오른쪽 이동 연산자

유서지 않은 오른쪽 이동 연산자는 세 개의 더 큰 괄호(>>>)로 표시되며, 유서지 않은 32비트 숫자의 모든 비트를 전체로 오른쪽으로 이동시킵니다. 양수의 경우, 유서지 않은 오른쪽 이동 연산자의 결과는 유서지 않은 오른쪽 이동 연산자와 같습니다.

유서지 않은 오른쪽 이동 연산자의 예로, 64를 5비트로 오른쪽 이동하면 2가 됩니다:

var iOld = 64; // 이진 1000000
var iNew = iOld >>> 5; // 이진 10, 십진수 2

음수의 경우, 상황은 다릅니다.

유서지 않은 오른쪽 이동 연산자는 모든 공백을 0으로 채웁니다. 양수의 경우, 이는 유서지 않은 오른쪽 이동 연산자와 같은 작업을 수행하며, 음수의 경우 음수는 양수로 처리됩니다.

유서지 않은 오른쪽 이동 연산자의 결과는 32비트의 양수이므로, 음수의 유서지 않은 오른쪽 이동 연산자는 항상 매우 큰 숫자를 얻습니다. 예를 들어, -64를 5비트로 오른쪽 이동하면 134217726을 얻습니다. 이러한 결과를 어떻게 얻을 수 있습니까?

이를 구현하려면, 이 숫자를 유서지 않은 등가형식으로 변환해야 합니다. 숫자 자체는 유서지 않은 숫자지만, 다음과 같은 코드를 통해 이 형식을 얻을 수 있습니다:

var iUnsigned64 = -64 >>> 0;

그런 다음, Number 타입의 toString()를 사용하여 실제 비트 표현을 얻습니다. 기본值为 2:

alert(iUnsigned64.toString(2));

이는 11111111111111111111111111000000을 생성하며, 유서지 않은 정수 -64의 이진 보수 표현이며, 그러나 유서지 않은 정수 4294967232와 같습니다.

이 이유로 무표시 오른쪽 이동 연산자를 사용할 때 주의해야 합니다.