본문 바로가기

무언가 만들기 위한 지식/C,C++,Embedded C

[ALL] 2진수 출력(Bit Masking)


Embedded나 통신부분에서 테스트를 하다보면 2진수로 출력해가며 확인해야할 때가 꼭 생긴다.
2진수로 출력하는 방법에는 보통
1. 우리가 어렸을 때 수학시간에 배운방식으로 2로 나누어서 배열에 저장해서 출력하는 방식도 있지만
2. 가장 효율적인 것은 bit Masking 기법을 통해 출력하는 것이다.

비트 마스킹이란, 각 비트(bit)별로 0인지 1인지를 비트처리연산자(&,|등)를 통해 검출해 내는 과정이다.
이과정에서는 주로

shift연산자와 &(AND)을 통해 검출해 낼 수 있고,
(1을 해당 비트로 shift 한후 대상과 &하여 0이 나오면 0 아니면 1로 판단)
shift연산자와 |(OR)을 통해 Set이 가능하다.
(1을 해당 비트로 shift 한후 대상과 |하면 해당 비트가 1로 Set)
shift연산자와 &(AND)를 통해 Clear가 가능하다.
(1을 해당 비트로 shift한후 ~를 통해 0과 1을 반전 시킨후 &를 하면  해당 비트가 0으로 Set)
shift연산자와 ^(XOR)을 통해 Invert가 가능하다.
(1을 해당 비트로 shift한후 대상과 ^를 하면 해당비트가 반전된다.)

네트워크에서도 0과 1을 32개의 bit의 집합인 int Type으로 Table형식으로 만들어 사용이 가능하다.
그럼 int Type 32개의 Table보다 훨씬 절약적인 관리가 가능해진다.

또한 Embedded System등에서는 Device컨트롤하는 Register(32bit)에서 Set과 Clear 등으로 제어하기도 하므로 익숙해야 한다.

그럼 2진 출력코드를 보도록 하자.
[작성환경 : Window XP   작성툴 : Visual Studio 6.0   컴파일러 : Visual Studio 6.0    사용언어 : C]

stdio.h에 주어지는 printf 함수에서 16진수와 8진수 출력은 o와 x옵션으로 출력이 가능하다.
(#옵션은 앞에 진수표기를 해준다.)
그러나 2진수 출력의 경우 옵션에 존재하지 않기 때문에 따로 구현해야 한다.
printfBinary함수가 이를 출력하는 함수이다.
간단한 해석을 곁들이자면
14 Line에서는 총 32bit이므로 31부터 0까지 반복을 하겠다는 것이고,
15 Line에서 위에서 언급한 비트연산자를 이용한 계산과 if(삼항연산자 [?:])문을 이용하여 처리한다.
16~21 Line을 주석처리하면 총 32bit가 0과 1로 나타낸다. 때에 따라 주석처리 해주어서 확인할때도 존재한다.
즉 핵심은 15 Line의 이해이다.
for Loop상의 증감변수 i를 통해 1을 shift한후 &한 모습을 볼 수 있다. 여기서의 &는 검출 을 위한 연산이다.
AND를 하면 결과값이 0 or 0이 아닌 수가 나오게 된다. 이를 if문을 통해 참 거짓으로 연산을 수행하게 된다.
그리고 check라는 Mode 상태를 주어 1이 나올때까지 출력하지 않다가, 한번 1이 나오면 다음부터는 무조건 출력하는 과정이다.

필자가 작성한 건 아니고, 자주 사용하게 되어 여기저기 쓸만한 코드를 약간 수정해서 사용하고 있다.
함수내에서 bit의 경우 어차피 0또는 1만 존재하면 되므로 1byte짜리 변수를 사용하면 좋다. 그래서 필자는 char를 사용하였다.^_^



<Test 결과 값, 기본 값으로 14를 입력받았다.>