본문 바로가기
임베디드 개발/펌웨어

2의 거듭제곱에 대한 나머지 연산 최적화 및 bit mask 생성

by eteo 2024. 4. 8.

 

 

 

2의 거듭제곱으로 나머지 연산을 수행할 때는 % 연산자 대신 비트 연산을 사용해 연산속도를 최적화할 수 있다.

 

예를 들어, 어떤 수 x에 대해 x % 8 의 결과를 구하고 싶다면, x를 7과 비트 단위로 AND 연산하는 것과 결과가 같으므로 x & 7 으로 대체할 수 있다.

 

예시.

#include <stdio.h>

#define BUFSIZE 8

int main() {
    int x = 10;
    int result = x & (BUFSIZE - 1);
    printf("Result: %d\n", result);

    return 0;
}

 

 

 

 

위와 같이 알아내고자 하는 bit를 전부 1로 셋하고 & 연산으로 값을 추출하는 것은 비트 마스크기법이다. 관련글을 쓴 김에 mask를 생성하고 사용하는 방법에 대해 좀 더 글을 써보겠다.

 

 

펌웨어 프로그래밍을 하다 보면 특정 비트만 선택적으로 추출하거나 조작해야할 상황이 자주 발생한다. 이때 비트 마스크와 시프트 연산을 사용해 원하는 작업을 수행할 수 있는데 비트 마스크를 생성할 때는 타겟 비트 개수 - 1을 시프트연산하여 타겟 위치에는 1을 나머지엔 0을 배치하면 된다.

 

아래는 16비트 변수에서 오프셋 4 위치에서 시작하여 연속된 3개의 비트를 추출하고 그 뒤에 해당 비트를 전부 0으로 클리어 하는 예시이다.

 

 

#include <stdio.h>

#define BITS_NUM    3
#define BITS_OFFSET 4

int main() {
    unsigned short value = 0xABD6;
    unsigned short mask = ((1 << BITS_NUM) - 1) << BITS_OFFSET;

    printf("Extracted Value: 0x%X\n", (value & mask) >> BITS_OFFSET);
    
    value &= ~mask;
    
    printf("Cleared Value: 0x%X\n", value);

    return 0;
}