비트마스킹 예제

honeyricecake·2022년 6월 27일
0

C언어(학교 수업)

목록 보기
3/3

(학교 과제 문제를 변형한 문제입니다.)

int형 변수 x의 값이 76일 때
(1) x의 최하위 비트로부터 5번째 자리의 비트 값
(2) x의 최하위 비트로부터 4,3,2번째 비트를 1로 지정한 값
(3) x의 최하위 비트로부터 3,1번째 비트를 0으로 지정한 값
(4) x의 최하위 비트로부터 4,3번째 비트를 반대로 한 값

1번 문제는 비교적 간단하다

x의 5번째 자릿수를 k라 하자.
그럼 x를 4번 오른쪽 시프트 연산을 하면

이렇게 k가 첫번째 자리에 오게 된다.

그럼 (x>>4) & 1을 하면 k가 0이면 0 1이면 1을 얻게 되므로 k를 알 수 있게 된다.
(또는 (x>>4)0(x>>4)|0 을 해도 된다.)

2,3,4 문제를 풀기 전에 다음을 보자.

이를 알고 다시 한번 2번 문제를 보자.

뒤에서 4,3,2번째 비트를 무조건 1로 만들어야 한다.

그런데 위에서 보이듯이 k|1은 무조건 1이고 k|0은 k이다.

따라서 2진수 1110 = 8 + 4 + 2 = 14과 or연산한다면?
뒤에서 2번째, 3번째, 4번째 비트는 1이 되고 나머지는 그대로임을 알 수 있다.

그럼 3번 문제도 보자.

뒤에서 3,1번째 비트를 무조건 0으로 만들면 되는데

&0 이 비트를 0으로 만드는 작업을, &1이 비트를 그대로 유지하는 작업을 해줄 수 있다.

그런데 한가지 문제가 있다.

여기서는 76이 64 <= 76 < 128 이므로 7자리임을 알 수 있어서
(2진수는 2^(n - 1) 이상 2^n 미만 일 경우 n자리 수이다.)
1111010 과 & 연산을 하면 되지만 임의의 정수가 주어진다면 어떻게 할 것인가?

만약 9자리 이진수 111111111과 1111010을 &연산한다면 앞의 두자리는 0과 &연산되어 0이 되어버린다.

해결책은
정수의 범위가 주어진다는 가정하에
나올 수 있는 가장 큰 자릿수를 가졌으며 모든 비트가 1인 이진수 111111....1111 에서 1과 4를 뺀 수와 &연산하는 것이다.

일단, 수의 범위는 주어져야겠지만 수의 범위가 주어진다면
1과 4만 뺴면
111111....11111 - 1 = 111111...111110 이고
111111....11111 - 4 = 111111...111010 이므로 위의 연산을 일반화할 수 있다.

이는 정수 범위 내에서는 -1이며

그럼 (-1) -1 - 4 = (-6)과 비트 연산하면 정답이 나옴을 알 수 있다.

4번 문제는 3번보다는 쉽다.

뒤에서 4,3번째 비트만 반대로 하면 되므로

4,3번째 비트는 1과 나머지 비트는 0과 xor연산을 하면된다.

즉, 2진수 1100 = 8 + 4 = 12 와 xor연산을 하면 됨을 알 수 있다.

//소스 코드

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	int x = 76;

	printf("%d\n", ((x>>4) & 1));

	printf("%d\n", x | 14);  // 14은 1110

	printf("%d\n", x & (-6));

	printf("%d\n", x^12);  // 1은 xor하면 reverse , 0은 xor하면 그대로

}

정답은 순서대로 0, 78, 72, 64이다.

0개의 댓글