◾ 어떤 숫자와 1을 &연산하면 홀수, 짝수 여부를 확인할 수 있다.

 

i번째 비트 추출

int getIthBit(int n, int i) {
    int mask = 1<<i;
    return n & mask;
}

 

 

i번째 비트 변경

◾ 1로 변경

void setIthBit(int& n, int i) {
    int mask = (1<<i);
    n = (n | mask);
}

 

◾ 0으로 변경

void clearIthBit(int& n, int i) {
    int mask = ~(1<<i);
    n = (n & mask);
}

 

◾ 0 또는 1로 변경

void updateIthBit(int& n, int i, int v) {
    clearIthBit(n, i);
    int mask = (v<<i);
    n = (n | mask);
}

 

 

i번째까지의 비트 변경

◾ 끝에서 i번째까지 0으로 변경

void clearLastBits(int& n, int i) {
    int mask = (-1 << i);
    n = (n & mask);
}

 

◾ i에서 j번째까지 0으로 변경

void clearBitInRange(int& n, int i, int j) {
    int a = (-1<<j+1);
    int b = (1<<i)-1;
    int mask = a | b;
    n = n | mask;
}

 

◾ i에서 j번째까지 임의의 비트로 변경 (replace)

void replaceBits(int& n, int m, int i, int j) {
    clearBitInRange(n, i, j);
    int mask = (m << i);
    n = (n | mask);    
}

 

 

2의 거듭 제곱수 확인

bool isPowerOfTwo(int n) {
    return !(n & (n-1));
}
/*
 1000 -> 8	 1001 -> 9
&0111 -> 7	&1000 -> 8
-----		 ----
 0000 -> 0	 1000 -> 8 (!=0)

어떤 숫자가 2의 거듭 제곱수라면 n & (n-1) == 0이 성립한다.

 

 

비트 개수 찾기

int countBit(int n) {
    int cnt = 0;
    
    while (n > 0) {
        cnt += (n & 1);
        n = n >> 1;
    }
    
    return cnt;
}

시간 복잡도는 O(logN)이다.

 

int countBitHack(int n) {
    int cnt = 0;
    
    while (n > 0) {
        n = n & (n-1);
        ++cnt;
    }
    
    return cnt;
}

1의 개수만큼 루프를 돌기때문에 조금 더 빠르다.

 

 

빠른 거듭제곱 계산

int fastExponentiation(int a, int n) {
    int ans = 1;
    
    while (n > 0) {
        int last_bit = n & 1;
        if (last_bit) ans *= a;
        a *= a;
        n = n >> 1;
    }
    
    return ans;
}

a^5 = a^(1+4)를 이용한다. 거듭제곱에 의한 오버플로우를 유의해야 한다.

비트 연산이 아닌 거듭제곱을 하게되면 시간복잡도는 O(n)이지만 비트 연산은 O(log n)이다.

 

 

10진수를 2진수로 변환하기

int convertToBinary(int n) {
    int ans = 0;
    int p = 1;
    
    while (n > 0) {
        int last_bit = n & 1;
        ans += last_bit * p;
        
        p *= 10;
        n = n >> 1;
    }
    
    return ans;
}

 

 

그 외 활용

◾ 배열 내의 유일한 값 찾기

어떤 배열에 단 하나의 값만 1개, 그외 다른 값은 2개씩 존재한다고 했을때 선형으로 접근하여 모든 수에 대해 xor 연산을 하면 유일한 값만 남게된다.

 

◾ 모듈러 연산

int power(int x, int y, int mod)
{
    int result = 1;
    while (y > 0) {
        int last_bit = y & 1;
        if (last_bit)
            result = (result * x) % mod;
        x = (x * x) % mod;
        y = y >> 1;
    }
    
    return result;
}

(a*b)%c = ((a%c)*(b%c))%c를 이용함과 동시에 빠른 거듭제곱 계산을 사용한다.

'이론 > 자료구조&알고리즘' 카테고리의 다른 글

Divide & Conquer  (0) 2023.02.10
Recursion Basics  (0) 2023.02.09
Vector Data Structure  (0) 2023.02.08
Pointers & Dynamic Memory  (0) 2023.02.07
2D Arrays  (0) 2023.02.07

+ Recent posts