천간 avatar

[C언어] 2의 보수 코딩

codingman

Published: 15 Mar 2019 › Updated: 15 Mar 2019[C언어] 2의 보수 코딩

[C언어] 2의 보수 코딩

[C언어] 2의 보수 코딩


예전에 2의 보수에 대한 post를 작성 한 적이 있습니다. 문득 이 부분을 C언어로 코딩하면 재미있지 않을까 생각되어 한번 C언어로 코딩화 해보는 시간을 가져 봅니다.

1. 10진수를 2진수로 변환


C언어에서는 변수에 어떤 값을 넣더라도 그 값을 printf()문을 어떻게 출력 형식을 취하느냐에 따라서 그 결과를 다양하게 출력 할 수 있습니다. 정수를 "%0"로 취하면 8진수 형태로 출력 되고 "%x"로 취하면 16진수 형태로 출력이 됩니다. 참고로 2진수 형태는 printf()문의 출력형식은 없기 때문에 정수를 2진수 값으로 가정해서 자릿수 값을 출력해보는 코딩을 수작업으로 해보겠습니다.

예)
12 => 00001100

위와 같은 형태로 출력을 하게 만들려면 어떻게 해야 할까요. 12값을 2진수로 잘게 쪼개는 방법은 12을 계속 2로 나눈 몫을 나열하는 방법도 있지만 &연산을 이용하여 쉽게 쪼개는 방법을 취할까 합니다.

  1100
 &1000
--------
1000

이렇게 &연산자는 AND 연산자로 1과 1일 때 1이 나오고 1과 0일 때는 0이 나옵니다.

그래서 정수 12를 2진수로 출력 되게 하려면 다음과 같습니다.

1000 0000 => 0x80

의 값을 기준으로 12정수에 & 연산을 수행합니다. 총 8자리 비트를 비교해야 하기 때문에 루프문으로 8번 & 연산을 수행합니다. 참고로 각 자리비트를 비교해야 하기 때문에 쉬프트 연산을 별도로 0x80에 취해야 합니다.

1000 0000 => 0100 0000 => 0010 0000 ...

이런식으로 각 자리비트를 만들어서 & 연산을 수행해야 하는데 이 표현을 하려면 쉬프트 연산을 쉽게 표현이 됩니다.

b = 0x80;
b=b>>1;

이렇게 한칸씩 이동시키면 됩니다.

위 내용을 코딩화 하면,

int a=12;
int b=0x80;
int i;
int tmp[8];

for(i=0;i<8;i++){       
        if(a&b) tmp[i]=1;
        else tmp[i]=0;
        b=b>>1;
}   

[결과]
a1.jpg
이렇게 하면 12에 대한 각 자리비트의 1인지 0인지 확인을 통해 tmp[i]에 해당 자리 비트 값을 저장하게 됩니다.

2의 보수 변환


-12을 2의 보수를 취해 음수를 2진수 형태로 출력 해 볼까요.

예) 2의 보수 -12
12 =>
0000 1100
11110011

11110011+0000 0001 = 11110100

위 과정을 C언어로 코딩화 해야 합니다.

12를 2진화 해서 배열변수에 저장합니다.

for(i=0;i<8;i++){       
        if(a&b) tmp[i]=1;
        else tmp[i]=0;
        b=b>>1;
}   

-12를 2의 보수를 취하기 위해서 1을 0으로 0을 1로 변환

for(i=0;i<8;i++){
    printf("%d",tmp[i]);
    if(tmp[i]==1) tmp[i]=0;
    else tmp[i]=1;
}

마지막으로 +1을 더한다.

for(i=7;i>=0;i--){
    if(tmp[i]==1) tmp[i]=0;
    else {
        tmp[i]=1;
        break;
    }
}   

마지막 +1을 더하는 위 코딩을 자세히 보셔야 합니다. 약간 햇갈릴 수 있습니다. 역순으로 마지막 자리부터 1이면 +1을 하기 때문에 올림수로 계속 순차적으로 1일때는 해당 자리는 최종적으로 0이 되고 1이 올라가고 다음 비트자리가 1 or 0 이냐에 따라서 더하게 됩니다. 그런데 더하는 비트자리가 0이 되면 그 자리는 1이 되고 break 문으로 for문을 빠져 나오게 됩니다.

이렇게 해서 tmp[] 배열 변수에는 -12에 대한 2의 보수를 취한 2진수 값이 저장되게 됩니다.

3. 종합 코딩


이제는 정상적으로 위 과정이 동작하고 결과을 얻는지 확인 해야 겠지요.

[전체소스]

#include 

int main(int argc, char *argv[]) {
    
    int a=12;
    int b = 0x80;
    int i;  
    int tmp[8];
    
    for(i=0;i<8;i++){       
        if(a&b) tmp[i]=1;
        else tmp[i]=0;
        b=b>>1;
    }   
    printf("%d => \n",a);
    for(i=0;i<8;i++){
        printf("%d",tmp[i]);    
    }
    printf("\n");
    
    for(i=0;i<8;i++){
        printf("%d",tmp[i]);
        if(tmp[i]==1) tmp[i]=0;
        else tmp[i]=1;
    }
            printf("\n");
    for(i=0;i<8;i++){
        printf("%d",tmp[i]);    
    }
    printf("\n");
    for(i=7;i>=0;i--){
        if(tmp[i]==1) tmp[i]=0;
        else {
            tmp[i]=1;
            break;
        }
    }
    
    for(i=0;i<8;i++){
        printf("%d",tmp[i]);    
    }
    printf("\n");
    return 0;
}

위 코딩을 보시면 -12에 대한 2의 보수를 취한 2진수 값을 출력하는 코딩인데 왜 a에 12라는 양수가 저장되어 있냐고 이상하다고 생각하실 수 있습니다. 그 이유는 12라는 숫자를 기준으로 보수를 취하기 때문에 -12를 코딩에서는 선언할 수 없습니다. 1비트씩 쪼개서 배열변수에 넣는 거라서 양수 12를 기준으로 2의 보수를 취해 배열변수에 -12의 결과같을 얻도록 하기 위한 표현임으로 감안하셔서 보시기 바랍니다.

[결과]
a2.jpg

마무리


문득 떠오른 2의보수에 대한 C언어 코딩을 해 보았네요. 참고로 전체소스를 보면 꽤 긴 코딩이 이루어졌습니다. 중간 중간 결과를 printf()문으로 출력하다보니 불필요한 코딩이 많아졌는데 최종결과만 출력하게 수정하여 코딩을 줄여서 깔끔하게 정리해서 보시기 바랍니다.


Sponsored ( Powered by dclick )

dclick-imagead

Leave [C언어] 2의 보수 코딩 to:

Written by

나는 소망한다 내게 주어진 모든것들을

Read more #kr-dev posts


Best Posts From 천간

We have not curated any of codingman's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.

More Posts From 천간