컴퓨터 시스템에서 음수를 표현하거나 뺄셈 연산을 처리할 때 보수(complement) 개념이 핵심적으로 사용됩니다. 이 글에서는 C 언어를 사용하여 주어진 이진수에 대한 1의 보수와 2의 보수를 구하는 방법을 예제와 함께 단계별로 살펴보겠습니다.
먼저 개념을 간단히 정리하면 다음과 같습니다.
- 1의 보수: 이진수의 모든 비트를 반전시킵니다. 즉, 0은 1로, 1은 0으로 바꿉니다.
- 2의 보수: 1의 보수를 구한 뒤 최하위 비트에 1을 더하면 됩니다.
예제
다음 예제를 통해 동작 과정을 확인해 보겠습니다.
입력은 다음과 같습니다.
이진수를 입력하세요: 10010001
출력은 다음과 같습니다.
10010001의 1의 보수: 01101110
10010001의 2의 보수: 01101111
알고리즘
주어진 이진수에 대한 2의 보수를 구하는 알고리즘은 다음과 같습니다.
1단계 − 시작합니다.
2단계 − 실행 중에 이진수를 입력받습니다.
3단계 − 원본 이진수를 strdp 변수에 복사해 둡니다.
4단계 − len := strlen(str)
5단계 − i = 0부터 len-1까지 다음을 반복합니다.
5.1단계 − 만약 str[i] == '1'이라면
5.1.1단계 − str[i]를 '0'으로 변경합니다.
5.2단계 − 그렇지 않으면
5.2.1단계 − str[i]를 '1'로 변경합니다.
5.3단계 − i := i + 1
6단계 − mask := 1
7단계 − i = len-1부터 0까지 다음을 반복합니다.
7.1단계 − 만약 mask == 1이라면
7.1.1단계 − 만약 str[i] == '1'이라면
7.1.1.1단계 − str[i] := '0'
7.1.1.2단계 − mask := 1 (캐리 유지)
7.1.2단계 − 그렇지 않으면
7.1.2.1단계 − str[i] := '1'
7.1.2.2단계 − mask := 0 (캐리 종료)
8단계 − 2의 보수를 출력합니다.
9단계 − 종료합니다.
여기서 mask 변수는 덧셈 시 발생하는 자리올림(carry)을 추적하는 역할을 합니다. 오른쪽 끝 비트부터 왼쪽으로 이동하며 1을 더하고, 자리올림이 더 이상 발생하지 않으면(mask = 0) 나머지 비트는 그대로 유지됩니다.
C 프로그램
다음은 주어진 이진수에 대한 2의 보수를 구하는 C 프로그램입니다.
#include <string.h>
#include<stdio.h>
main(){
char str[32],strdp[32];
int mask,i;
printf("Enter a binary number:");
scanf("%s",str);
strcpy(strdp,str);
for(i=0;i<strlen(str);i++) /* computing 1's complement */{
if(str[i]=='1')
str[i]='0';
else
str[i]='1';
}
printf("1\'s complement of %s is %s\n",strdp,str);
mask=1;
for(i=strlen(str)-1;i>=0;i--){
if(mask==1){
if(str[i]=='1'){
str[i]='0';
mask=1;
}
else{
str[i]='1';
mask=0;
}
}
}
printf("2\'s complement of %s is %s",strdp,str);
}
실행 결과
위 프로그램을 실행하면 다음과 같은 결과가 출력됩니다.
Enter a binary number:11001110
1's complement of 11001110 is 00110001
2's complement of 11001110 is 00110010
정리
이 프로그램의 핵심 로직은 두 부분으로 나눌 수 있습니다. 첫 번째 반복문에서는 문자열을 앞에서부터 훑으며 각 비트를 반전시켜 1의 보수를 구하고, 두 번째 반복문에서는 뒤에서부터 훑으며 mask(자리올림) 값을 이용해 1을 더해 2의 보수를 완성합니다. strcpy()로 미리 복사해 둔 strdp 덕분에 원본 이진수를 출력에 그대로 활용할 수 있다는 점도 눈여겨볼 만합니다.