반응형
참고
1. char 타입 4bit 교환
2. 4bit 단위로 교환
3. 1bit 교환
char 타입 4bit 교환
char는 1byte = 8bit이므로 아래와 같이 4bit씩 양 옆으로 옮겨주면 비트가 교환된다.
예를 들어 char a = 0xA9라면 0x9A가 된다.
typedef unsigned char uc;
uc change4Bit(unsigned char value)
{
return (value << 4 | value >> 4);
}
전체 코드는 다음과 같다.
#include <stdio.h>
typedef unsigned char uc;
uc change4Bit(unsigned char value)
{
return (value << 4 | value >> 4);
}
int main()
{
uc a = 0xA9;
uc b = change4Bit(a);
printf("before : 0x%02X\n", a);
printf("after : 0x%02X\n", b);
return 0;
}
4bit 교환
int는 4byte = 32bit로 이루어져 있고, 4bit가 8개로 이루어져 있다.
8개의 4bit 중 두 위치를 변경하는 코드는 비트 연산을 이용해서 아래와 같이 구현할 수 있다.
(입력되는 pos의 범위는 0 ~ 7)
typedef unsigned int ui;
ui change4Bit(ui value, ui pos1, ui pos2)
{
pos1 *= 4;
pos2 *= 4;
ui mask1 = (0xF << (pos1));
ui mask2 = (0xF << (pos2));
ui bit1 = (value & mask1) >> pos1;
ui bit2 = (value & mask2) >> pos2;
value &= (~(mask1 | mask2));
value |= ((bit1 << pos2) | (bit2 << pos1));
return value;
}
아래의 코드를 실행해서 정상적으로 동작하는지 확인해 보자.
#include <stdio.h>
typedef unsigned int ui;
ui change4Bit(ui value, ui pos1, ui pos2)
{
pos1 *= 4;
pos2 *= 4;
ui mask1 = (0xF << (pos1));
ui mask2 = (0xF << (pos2));
ui bit1 = (value & mask1) >> pos1;
ui bit2 = (value & mask2) >> pos2;
value &= (~(mask1 | mask2));
value |= ((bit1 << pos2) | (bit2 << pos1));
return value;
}
int main()
{
int a = 0x76543210;
printf("a : 0x%x\n", a);
for (int i = 0; i < 8; i++)
{
for (int k = 0; k < 8; k++)
{
int b = change4Bit(a, i, k);
printf("%d <-> %d 0x%08x\n", i, k, b);
}
}
return 0;
}
long 타입의 경우는 0xF에 ull을 추가해야 정상적으로 동작한다. (입력되는 pos의 범위는 0 ~ 15)
typedef unsigned long long int ull;
ull change4Bit(ull value, ull pos1, ull pos2)
{
pos1 *= 4;
pos2 *= 4;
ull mask1 = (0xFull << (pos1));
ull mask2 = (0xFull << (pos2));
ull bit1 = (value & mask1) >> pos1;
ull bit2 = (value & mask2) >> pos2;
value &= (~(mask1 | mask2));
value |= ((bit1 << pos2) | (bit2 << pos1));
return value;
}
마찬가지로 아래 코드를 실행해서 테스트해 보자.
#include <stdio.h>
typedef unsigned long long int ull;
ull change4Bit(ull value, ull pos1, ull pos2)
{
pos1 *= 4;
pos2 *= 4;
ull mask1 = (0xFull << (pos1));
ull mask2 = (0xFull << (pos2));
ull bit1 = (value & mask1) >> pos1;
ull bit2 = (value & mask2) >> pos2;
value &= (~(mask1 | mask2));
value |= ((bit1 << pos2) | (bit2 << pos1));
return value;
}
int main()
{
ull a = 0xABCDEF98765432AB;
for (int i = 0; i < 16; i++)
{
for (int k = 0; k < 16; k++)
{
ull b = change4Bit(a, i, k);
printf("%d <-> %d 0x%llX\n", i, k, b);
}
}
return 0;
}
1bit 교환
4bit 교환을 응용하여 1bit 단위로도 비트를 교환할 수 있다.
int의 경우 입력되는 pos의 범위는 0 ~ 31이 된다.
typedef unsigned int ui;
ui change1Bit(ui value, ui pos1, ui pos2)
{
ui mask1 = (0x1 << (pos1));
ui mask2 = (0x1 << (pos2));
ui bit1 = (value & mask1) >> pos1;
ui bit2 = (value & mask2) >> pos2;
value &= (~(mask1 | mask2));
value |= ((bit1 << pos2) | (bit2 << pos1));
return value;
}
정상적으로 1 비트가 교환되는지 확인해 보자.
#include <stdio.h>
typedef unsigned int ui;
template <typename T>
void printBitNumber(T number)
{
unsigned int bitSize = sizeof(number) * 8;
T mask = (1ull) << (bitSize - 1);
printf("%d", (number & mask) == mask);
mask = (1ull) << (bitSize - 2);
for (int i = 1; i < bitSize; i++)
{
printf("%d", (number & mask) == mask);
mask >>= 1;
if (i % 8 == 7) printf(" ");
}
putchar('\n');
}
ui change1Bit(ui value, ui pos1, ui pos2)
{
ui mask1 = (0x1 << (pos1));
ui mask2 = (0x1 << (pos2));
ui bit1 = (value & mask1) >> pos1;
ui bit2 = (value & mask2) >> pos2;
value &= (~(mask1 | mask2));
value |= ((bit1 << pos2) | (bit2 << pos1));
return value;
}
int main()
{
int a = 0x76543210;
printf("a : 0x%x\n", a);
for (int i = 0; i < 32; i++)
{
for (int k = 0; k < 32; k++)
{
int b = change1Bit(a, i, k);
printf("%d <-> %d ", i, k);
printBitNumber(b);
}
}
return 0;
}
반응형
'개발 > C, C++' 카테고리의 다른 글
C++ - 폴더, 파일 관리 함수 정리 with sys/stat.h, dirent.h, fstream (0) | 2023.09.09 |
---|---|
여러가지 나머지 연산 방법 테스트 (0) | 2023.08.15 |
C, C++ - 비트 뒤집기 (Reverse Bits) (0) | 2023.07.30 |
C, C++ - 2차원 비트맵 뒤집기, 회전하기 (Rotate, Flip 2D Bitmap) (0) | 2023.07.30 |
C, C++ - 1차원 비트 회전하기 (Rotate Bits of a Number) (0) | 2023.07.30 |
댓글