비트 연산

Ryan Ham·2024년 5월 15일
1

C++

목록 보기
2/26

비트 연산자는 논리 연산자에 비해 많이 쓰이지는 않지만 특정 상황에서 아주 강력한 쓰임새를 가질 수 있다. 일단 논리 연산자와 기호 부분에서 어떻게 다른지 알아보겠다.


기호 / 논리 연산자 / 비트 연산자

AND / && / &
OR / || / |
NOT / ! / ~

비트 연산자에만 존재

XOR / - / ^
left shift / - / <<
right shift / - / >>


상태 저장으로 비트 바라보기

11111111 // 1byte(8bit)

위와 같이 8 bit로 이루어진 어떤 변수가 있다고 가정해보자. 그러면, 일반적으로는 총 256개의 값을 표현할 수 있다고 이해한다. 하지만 각 자리의 비트를 하나의 상태로 가정한다면 이는 실제적인 2진법의 값과 상관없이 각 비트마다 1개, 총 8개의 상태를 저장하는 숫자가 된다. 이렇게 생각하는 이유는 비트 연산은 각 비트마다 연산이 들어가기 때문이다.


Bit shift

Bit shift 연산에는 left shift와 right shift가 존재한다. 이는 각각 <<와 >>로 표기하는데 코드로 예시를 들어보면 다음과 같다.

#include <iostream>

int main() {
    unsigned int num = 5;  // Binary: 00000000 00000000 00000000 00000101
    unsigned int leftShifted = num << 1;  // Shift left by 1 position
    
    unsigned int num = 20;  // Binary: 00000000 00000000 00000000 00010100
    unsigned int rightShifted = num >> 1;  // Shift right by 1 position

    std::cout << "Original number: " << num << std::endl;  // Output: 5
    std::cout << "After left shift by 1: " << leftShifted << std::endl;  // Output: 10
    // Binary after shift: 00000000 00000000 00000000 00001010
    
    std::cout << "Original number: " << num << std::endl;  // Output: 20
    std::cout << "After right shift by 1: " << rightShifted << std::endl;  // Output: 10
    // Binary after shift: 00000000 00000000 00000000 00001010

    return 0;
}

shift 연산은 2의 n승의 수행을 하는데에 있어서 일반적인 사칙연산보다 속도가 훨씬 빠르다고 하니, 2의 n승을 할때 적극적으로 사용해보자. 화살표 방향과 left/right shift의 이름을 묶어서 외우면 <<fmf 를 보고 left shift가 떠오를 것이고 그러면 왼쪽으로 숫자를 밀어서 그 만큼 값이 커진다라는 연상법으로 이해하면 훨씬 좋다!


signed와 unsigned의 부호 비트

기본적으로 cpp에서 변수를 선언하면 signed이다. 따라서 unsigned으로 변수를 선언하려면 변수 타입 앞에다가 따로 unsigned라고 붙여주어야 한다.

int x = 100;
unsigned int y = 100;

int로 예시를 들어보자면, int는 4byte이다. 즉, 8*4=>32bit의 자리수까지 표현이 가능한 변수 타입이다. 여기서 unsigned는 0 ~ 2^32 - 1까지의 값을 나타내고, signed는 -2^31 ~ 2^31 - 1 까지의 수를 나타내게 된다. unsigned에는 따로 부호 비트가 없으나 signed에는 제일 왼쪽비트(MSB)를 부호비트로 사용한다. MSB가 0이면 양수, 1이면 음수이다.

MSB가 음수일때 비트 값으로 해당 숫자를 구하는 것은 직관적으로 힘들 수 있다. 예시를 들어보자면 00000001이 1을 뜻한다면 11111111이 -1을 뜻하기 때문이다. 따라서 어떠한 음수에 해당하는 비트값을 구한다면 그 절댓값에 해당되는 양수 비트를 먼저 구한다음에 어떠한 값을 더해햐 0이 나오는지를 추정하는 것이 더 빠른 길이다. 이는 "2의 보수"라는 개념으로 발전하는데, 그 방법을 알면 빠르게 음수 값에 해당되는 비트를 계산할 수 있다.

profile
🏦KAIST EE | 🏦SNU AI(빅데이터 핀테크 전문가 과정) | 📙CryptoHipsters 저자

0개의 댓글