[MySQL] 비트연산

niz w·2025년 1월 24일

SQL

목록 보기
15/17

비트 연산은 숫자를 이진수(binary)로 변환한 뒤 연산을 수행하는 것이다.

📣 연산자


1. AND (&)

각 자리가 모두 1일 때만 연산 결과가 1이 나옴

SELECT 10 & 3 AS RESULT;

10은 1010
  3은 0011로 이진수를 추출할 수 있다.

각 자리가 모두 1이어야 하므로 0010의 결과가 나오고 십진수로 2에 해당한다.



2. OR (|)

SELECT 10 | 3 AS RESULT;

각 자리가 하나라도 1이면 연산 결과가 1이 나옴

10은 1010
  3은 0011

하나라도 1이면 되므로 1011의 결과가 나오고 십진수로 11에 해당한다.



3. XOR (^)

SELECT 10 ^ 3 AS RESULT;

각 자리에서 하나만 1이면 연산 결과가 1이 나옴

10은 1010
  3은 0011

하나만 1이어야 하므로 1001의 결과가 나오고 십진수로 9에 해당한다.



4. NOT (~)

모든 비트를 반전시키는 것으로 1은 0, 0은 1로 바꿈

SELECT ~10 AS RESULT;

10은 1010

0101의 결과가 나오고 십진수로 5에 해당할 거라고 생각된다.

하지만!!
~1010 = ...11110101

이를 2의 보수 해석법으로 하게되면...
11110101을 다시 반전시키고 => 00001010
여기에 1을 더하면 => 00001011
이는 십진수로 11에 해당하므로 결과는 -11이 출력된다!


🚨2의 보수 표현!!!
여기서 2의 보수 표현이라는 내용을 보았다.


음수를 이진수로 표현하는 방법 중 하나라고 한다.
양수와 음수를 같은 이진수로 표현할 수 있게 도와주는 것이다.


2의 보수 계산!!

  • 음수의 절댓값을 이진수로 변환
  • 이진수의 모든 비트 반전
  • 반전된 값에 1 더하기

    Example

    1. -10의 경우 절댓값은 10 이므로 이진수로는 00001010이다.
    2. 모든 비트를 반전하면 11110101이 되고,
    3. 반전된 값에 1을 더하면 11110110이 된다.


      결국 -10 => 11110110 이 되는 것이다.


      여기에 추가로 ~ 결과까지 뽑아보자면!
      1111011000001001의 반전값이기에 9의 반전값에 해당하게 된다!!

👉 결론!!
~에 해당하는 비트 연산 값은 -(n+1)의 정수값이 결과로 출력된다!!



5. 왼쪽 시프트 (<<)

비트를 왼쪽으로 이동시킨 뒤, 오른쪽 빈 자리는 0으로 채움

SELECT 10 << 2 AS RESULT;

10은 1010이므로
왼쪽으로 이동시키기 때문에 오른쪽에 0을 2개 붙인다고 생각하면 된다.

101000의 결과가 나오고 십진수로 40에 해당한다.



6. 오른쪽 시프트 (>>)

비트를 오른쪽으로 이동시킨 뒤, 왼쪽 빈자리는 부호 비트로 채움

SELECT 10 >> 2 AS RESULT;

10은 1010이므로
10의 결과가 나오고 십진수로 2에 해당한다.


하단 부호비트 설명을 공부하고 나서... 10 이 1010이면 음수 아니야!??! 라고 생각했다;;;
하지만 비트 길이에 따라 달라진다!
보통 MySQL에서는 32비트 이상으로 처리하므로 1000000000 00000000 00000000 00001010 으로 저장되어서 양수로 인식되는 것이다.


🚨 부호 비트
오른쪽 시프트 내용 중에 부호 비트라는 말이 나와서 찾아보았다!
이는 산술적인 오른쪽 시프트에서 숫자의 부호를 유지하지 위함이라고 한다.

논리적 오른쪽 시프트
단순히 왼쪽0을 채워넣어 오른쪽으로 미는 방식이다.
1011 -> 0101 이 된다.

산술적 오른쪽 시프트
왼쪽부호 비트을 채워 넣는다.
0이면 양수, 1이면 음수를 의미한다.

예를 들어,
0110은 양수 6 / 1110은 음수인 -2 (2의 보수 표현)를 나타낸다.

위의 설명을 통해 논리적, 산술적 시프트를 해보면!! (ex. -10 >> 2)
숫자 -10은 8 비트로 11110110에 해당한다.

  • 논리적 오른쪽 시프트 => 00111101 => 양수가 되었다...
  • 산술적 오른쪽 시프트 => 1로 시작하는 음수이므로 왼쪽에도 1을 붙여준다 => 11111101 => -3을 의미한다.

보면 산술적 시프트는 부호를 그대로 유지했다.




📣 활용 예제


1. 해당 자리 비트 확인하기

만약 주어진 숫자의 2번째 자리 비트가 0인지 1인지 확인하고 싶은 경우!

6 & 2 -> 110 & 010 -> 010 -> 2
4 & 2 -> 100 & 010 -> 000 -> 0

결과 값의 십진수가 0이 나오는 경우 그 자리마저 1이 일치하지 않는다는 의미이므로
주어진 수의 이진법 상 2번째 자리는 0임을 알 수 있다.

이렇게 해당 자리의 비트를 확인하는 방법이며,
1, 2, 4, 8 의 숫자로 확인하면 된다.
각각 0001, 0010, 0100, 1000 이므로!!



🤔만약 이와 달리 1,3번째 자리를 확인해야하는 상황이라면,
1, 3번째만 1인 숫자와 비교하면 된다.


01015에 해당하므로 이와 비교하면,

6 & 5 -> 0110 & 0101 -> 0100 -> 4
13 & 5 -> 1101 & 0101 -> 0101 -> 5

1, 3번째 모두 1인지 보려면 => 결과가 5와 일치하는 지 확인
1, 3번째 중 하나라도 1인지 보려면 => 결과가 0보다 큰 지 확인



2. 권한 확인하기

  • 1 : 해당 권한 활성화
  • 2 : 해당 권한 비활성화

=> 이를 통해 권한을 부여할 수 있다고 한다.

  • 0001 : 읽기 권한
  • 0010 : 쓰기 권한
  • 0100 : 실행 권한
  • 1000 : 관리자 권한

A&B > 0인 경우 B권한 활성화
A&B = 0인 경우 B권한 비활성화를 의미하므로

읽기 권한이 있는가? => 0101 & 0001 로 확인 => 0001이므로 TRUE
쓰기 권한이 있는가? => 0101 & 0010 로 확인 => 0000이므로 FALSE



3. 권한 추가 및 제거

추가는 OR 연산자( | )를 사용한다.
=> A | B이면 B 권한을 추가한다는 의미가 된다.
ex) 0101 | 0010 = 0111 (7) (실행, 읽기 권한에 쓰기 권한 추가)

제거는 ANT NOT 연산자(& ~)를 사용한다.
=> A &~ B는 권한 B를 제거한다는 의미가 된다.
ex) 0101 & ~0100 = 0101 & 1011 = 0001 (읽기 권한만 남기)




📣 비트 연산 함수

1~5번은 상단의 연산자 부분과 동일한 내용이다!


1. BIT_AND()

SELECT BIT_AND(10, 3);
=> SELECT 10 & 3 AS RESULT;
=> 0010
=> 2 출력


2. BIT_OR()

SELECT BIT_OR(10, 3);
=> SELECT 10 | 3 AS RESULT;
=> 1011
=> 11 출력


3. BIT_XOR()

SELECT BIT_XOR(10, 3);
=> SELECT 10 ^ 3 AS RESULT;
=> 1001
=> 9 출력


4. BIT_SHIFT_LEFT()

SELECT BIT_SHIFT_LEFT(10, 2);
=> SELECT 10 << 2 AS RESULT;
=> 101000
=> 40 출력


5. BIT_SHIFT_RIGHT()

SELECT BIT_SHIFT_RIGHT(10, 2);
=> SELECT 10 >> 2 AS RESULT;
=> 10
=> 2 출력



6. BIT_COUNT()

주어진 숫자를 이진법으로 나타냈을 때, 1의 개수를 반환

SELECT BIT_COUNT(10);
=> 1010에서 1의 개수이므로 2 반환



7. CONV()

숫자를 다른 진법으로 변환

SELECT CONV(5, 10, 2);
=> 5라는 10진수2진수로 변환
=> 101 출력


SELECT CONV('101', 2, 10);
=> 101라는 2진수10진수로 변환
=> 5 출력



8. BIN()

주어진 숫자를 2진수 문자열로 변환

SELECT BIN(5);
=> '101' 반환 (타입은 문자열)



9. HEX()

주어진 숫자를 16진수 문자열로 변환

SELECT HEX(255);
=> 'FF' 반환



10. UNHEX()

주16진수 문쟈열을 바이트로 변환

SELECT UNHEX('4D7953514C');
=> '4D7953514C'를 바이트로 변환한 값 반환



0개의 댓글