개발이야기/CSAPP
[CSAPP] 비트연산
Study & Stack
2025. 5. 29. 23:36
728x90
비트는 어떻게 정보를 표현할까?
💡 정보의 해석
- 컴퓨터는 같은 비트 패턴도 문맥에 따라 다르게 해석해요.
- 0x41 → 문자 'A' (ASCII) 또는 숫자 65
- 0x00000041 → 정수로 해석하면 65, float로 해석하면 엉뚱한 값
🧵 문자열 표현 in C
- 문자열은 char 배열로 구성되고, 마지막에 \0 (널 문자)로 끝나요.
- 예: "12345"는 실제로 [0x31, 0x32, 0x33, 0x34, 0x35, 0x00]으로 저장됩니다.
🌍 텍스트 인코딩과 유니코드
- ASCII는 영어에만 적합, 다른 언어(예: 한글, 그리스어)는 표현 불가
- 그래서 나온 것이 Unicode, 특히 UTF-8은 ASCII와 호환되며 다국어 표현 가능
부울 대수와 비트 벡터의 세계
🔢 기본 논리 연산
연산기호의미
NOT | ~ | 반전 |
AND | & | 둘 다 1일 때만 1 |
OR | | | 둘 중 하나가 1이면 1 |
XOR | ^ | 다를 때 1 |
🧠 직관 예시 (w = 4)
a = 0110
b = 1100
------------------
a & b = 0100
a | b = 1110
a ^ b = 1010
~b = 0011
🧰 비트 마스크 활용 예시
- x & 0xFF → 하위 1바이트만 추출
- x | 0xFF → 하위 1바이트를 모두 1로 설정
- x ^ x → 항상 0
🧭 집합 표현으로 확장
- [01101001]은 {0,3,5,6} 집합을 의미해요.
- &는 교집합, |는 합집합, ~는 여집합처럼 작동합니다.
비트 연산 실전 예시와 C 표현식
🔍 C언어에서의 표현 방식
~0x41 = 0xBE // 반전
0x69 & 0x55 = 0x41 // AND
0x69 | 0x55 = 0x7D // OR
🪄 스왑 트릭: 임시변수 없이 값 바꾸기
void inplace_swap(int* x, int* y) {
*y = *x ^ *y;
*x = *x ^ *y;
*y = *x ^ *y;
}
- XOR의 특성 (a ^ a = 0)을 이용해 스왑 구현
시프트 연산: 비트를 밀어 계산 속도 UP
⏩ 좌우 시프트 연산
연산자 | 설명 |
<< | 왼쪽 시프트, 곱셈 효과 |
>> | 오른쪽 시프트 |
📘 논리 시프트 vs 산술 시프트
- 논리 시프트: 왼쪽에 0을 채움 → unsigned에 사용
- 산술 시프트: 왼쪽에 부호 비트를 채움 → signed에 사용
예시 (8비트 기준)
0xD4 = 11010100
0xD4 << 2 = 01010000 // 왼쪽 시프트 (논리)
0xD4 >> 3 = 00011010 // 오른쪽 시프트 (논리)
🧯 주의사항
- x << 32처럼 단어 길이 이상의 시프트는 비표준 동작이 될 수 있어요!
핵심 요약: 비트를 정복하자!
✅ 비트는 해석 방식에 따라 숫자, 문자, 명령어가 될 수 있어요.
✅ 논리 연산은 비트를 조작하고, 집합처럼 다룰 수 있어요.
✅ 시프트 연산은 빠른 계산과 마스킹에 유용해요.
✅ 부울 대수와 비트 연산은 하드웨어와 시스템 프로그래밍의 기초입니다.
728x90