[JS] 비트연산자 종류, 설명 및 예제

Janet·2023년 4월 11일
0

JavaScript

목록 보기
21/26

비트 연산(Bitwise operator)

  • 논리연산자의 AND, OR과 헷갈릴 수 있으나 논리연산자는 기호를 두 개씩(&&, ||), 비트연산자는 한 개씩(&, |) 사용한다.
  • 비트 연산자란 2진수(binary)를 연산할 때 사용하는 연산자이다.
  • 참고로, JavaScript는 비트를 표현할 때 최대 32비트까지 표현할 수 있다.

AND 비트연산(&) : a & b

  • AND 비트 연산자(&)는 두 개의 피연산자의 각 자리마다 대응하는 비트가 모두 1일 경우 1을 반환합니다. 10진수인 두 정수를 2진수로 변환 했을 때, 두 수가 1이 일치하는 자리를 찾아 1을 반환, 나머지는 0으로 반환한다. 이후 2진수 → 10진수로 변환한 값을 리턴 함.
        9 (base 10) = 00000000000000000000000000001001 (base 2)
        14 (base 10) = 00000000000000000000000000001110 (base 2)
                       --------------------------------
    14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
    14 & 9 // 8
    
    let a = 8;
    console.log(a.toString(2)); // 1000
    
    // 아래 예제와 같이, 대응하는 비트가 없는 경우 0 반환
    5 & 2; // 0
    // 5: 00000000000000000000000000000101
    // 2: 00000000000000000000000000000010

OR 비트연산(|) : a | b

  • OR 비트 연산자(I)는 두 개의 피연산자의 각 자리의 대응하는 비트가 연산자 둘 중 한 쪽만 1인 경우 혹은 둘 다 1인 경우 1을 반환하고, 둘 다 0인 경우 0으로 반환한다.
        9 (base 10) = 00000000000000000000000000001001 (base 2)
        14 (base 10) = 00000000000000000000000000001110 (base 2)
                       --------------------------------
    14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)
    14 | 9 // 15
    
    let a = 15;
    console.log(a.toString(2)); // 1111

XOR 비트연산(^) : a ^ b

  • 대응되는 비트가 서로 다르면 1을 반환, 같으면 0을 반환함. (비트 XOR 연산)
        9 (base 10) = 00000000000000000000000000001001 (base 2)
        14 (base 10) = 00000000000000000000000000001110 (base 2)
                       --------------------------------
    14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
    14 ^ 9 // 7
    
    let a = 7;
    console.log(a.toString(2)); // 111

NOT 비트연산(~) : ~a

  • 다른 연산자와는 다르게 연산을 진행하는 피연산자는 하나뿐으로, 비트를 1이면 0으로, 0이면 1로 반전시킴. (비트 NOT 연산) 비트 NOT 연산자는 "비트 뒤집기" 또는 "비트 반전"이라고도 부른다.
  • But, JS의 경우 연산할 때는 2의 보수 방식으로 처리되지만 출력시에는 양수 비트에 -기호를 사용하여 표현하기 때문에 주의해야 한다.
    let [a, b] = [5, -5];
    console.log(a.toString(2)); // 101
    console.log(b.toString(2)); // -101

🔷 2의 보수 방식으로 음수 비트의 정수값 구하는 법

  1. 0101 (2진수) = 5 (10진수)이라는 양수의 비트가 있다.

  2. 1의 보수 방식으로 비트를 뒤집으면 1010 (2진수)이다.

  3. MSB(최상위 비트)가 1로 시작하는 비트는 음수이므로 0을 가진 비트의 값을 계산한다. 0을 가진 비트의 값은 2² + 2⁰ = 5이다.

  4. 2의 보수는 1의 보수 방식에서 1을 더한 값이므로 5 + 1 = 6이고 음수 기호를 붙여 최종적으로 -6이 된다.

      2³  2²  2¹  20   1   0   1  (base2) =  5 (base 10)
       1   0   1   0  (base2) = -6 (base 10)					
     	   4   +   1 = 5 + 1 = 6 => -6
    
    console.log(~5); // -6

LEFT SHIFT 비트연산(<<) : a << b

  • 왼쪽 시프트 (<<) 연산자는 첫 번째 피연산자를 명시된 비트 수(32의 나머지)만큼 왼쪽으로 이동합니다. 왼쪽으로 이동된 초과 비트는 폐기됩니다. 오른쪽은 움직인 비트 수 만큼 0비트로 채워집니다.
        9 (10진수): 00000000000000000000000000001001 (2진수)
                   --------------------------------
    9 << 2 (10진수): 00000000000000000000000000100100 (2진수) = 36 (10진수)
    
    9 << 2; // 36 
    // 9 * (2 ** 2) = 9 * (4) = 36
    // 9 * Math.pow(2, 2) = 9 * 4 = 36
    
    9 << 3; // 72
    // 9 * (2 ** 3) = 9 * (8) = 72
    // 9 * Math.pow(2, 3) = 9 * 8 = 72

LEFT SHIFT 할당 연산자(<<=) : a <<= b

  • 왼쪽 시프트 할당 (<<=) 연산자는 지정된 비트 수 만큼 왼쪽으로 비트를 이동시키고 그 결과를 변수에 반영합니다.
    x <<= y 
    // x = x << y
    
    let a = 5;
    console.log(a.toString(2));
    // 00000000000000000000000000000101
    
    a <<= 2;
    // 00000000000000000000000000010100
    console.log(parseInt(10100, 2)); // 20
    console.log(a); // 20
    // 변수 a는 지정된 비트 수(2) 만큼 왼쪽으로 이동되고, 그 결과는 변수 a에 반영된다.

RIGHT SHIFT 비트연산(>>) : a >> b

  • 부호를 유지하면서 지정한 수만큼 비트를 전부 오른쪽으로 이동시킴. (right shift 연산)

RIGHT SHIFT 비트연산(>>>) : a >>> b

  • 지정한 수만큼 비트를 전부 오른쪽으로 이동시키며, 새로운 비트는 전부 0이 됨.

  • 양수에서는 >>와 동일하게 동작하지만 음수일 경우 다르다. 1의 보수로 비트의 반전(0,1을 반대로 뒤집기)한 다음, 새로운 비트를 0으로 채우게 되는데, 양수 비트와 달리 음수 비트의 경우 0인 비트의 값들을 계산하게 되므로, 큰 값이 될 수 있다. 다음 예제 참고 ⬇️

    // a >>> b
    const a = 5 >>> 2;
    const b = -5 >>> 2;
       
    console.log(a); //1
    //  00000000000000000000000000000101 (base 2) = 5 (base 10)
    //  00000000000000000000000000000001 (base 2) = 1 (base 10) 
    // (우측으로 2비트 이동하고 새로운 비트 전부 0으로 채워 줌)
       
    console.log(b); //1073741822
    // -00000000000000000000000000000101 (base 2) = -5 (base 10)
    //(=11111111111111111111111111111010) (1의 보수로 비트를 뒤집은 형태)
    //  00111111111111111111111111111110 (base 2) = 1 (base 10)
    // (우측으로 2비트 이동하고 새로운 비트 전부 0으로 채워 줌)
    // 0인 비트의 값들을 계산하면 1073741822```
    
  • 자료 출처: MDN 문서 및 각종 자료들 참고

profile
😸

0개의 댓글