(컴퓨터공학입문) 010. 정수의 덧셈과 뺄셈

정수의 덧셈과 뺄셈

이전 포스팅에서 정수를 2의 보수로 표현하는 방법에 대해서 알아보았다.

참고 (컴퓨터공학입문) 009. 정수 표현

이번엔 2의 보수로 표현된 수로 덧셈과 뺄셈을 하는 방법에 대해서 알아보자.

1. 정수의 덧셈

편리한 이해를 위해, 16비트로 정수를 표현한다고 가정하자.

6 + 7 = 13

6과 7을 16비트 2진수로 나타내보자.

6(10)=0000000000000110(2)7(10)=0000000000000111(2)6_{(10)} = 0000000000000110_{(2)} \\ 7_{(10)} = 0000000000000111_{(2)}

덧셈이므로 각 비트들을 더하면서 올림 처리를 반복하면 아래와 같은 결과가 나온다.

13(10)=0000000000001101(2)13_{(10)} = 0000000000001101_{(2)}

위처럼 양수 두 개의 피연산자 덧셈은 어렵지않게 이해할 수 있다.

(-6) + 7 = 1

이번엔 피연산자 중 음수가 존재하느 경우에 대해서 알아보자.

먼저 -6을 2의 보수 표현으로 나타내면 아래와 같다.

6(10)=0000000000000110(2)6(10)=1111111111111010(2)6_{(10)} = 0000000000000110_{(2)} \\ -6_{(10)} = 1111111111111010_{(2)}

-6을 그대로 7과 더해보자.

6(10)=1111111111111010(2)7(10)=0000000000000111(2)-6_{(10)} = 1111111111111010_{(2)} \\ 7_{(10)} = 0000000000000111_{(2)}

더한 결과는 아래와 같다.

1(10)=0000000000000001(2)1_{(10)} = 0000000000000001_{(2)}

실제로 더해보면 자릿수의 올림이 반복되어서 가장 앞에 부호 비트는 넘어서는 값이 발생하는데

자릿수를 벗어나게 되는 값은 무시해서 원하는 결과를 얻는다.

(-6) + (-7) = (-13)

이번엔 피연산자가 모두 음수인 경우에 대해서 생각해보자.

-6과 -7을 각각 2의 보수로 표현하면 아래와 같다.

6(10)=1111111111111010(2)7(10)=1111111111111001(2)-6_{(10)} = 1111111111111010_{(2)} \\ -7_{(10)} = 1111111111111001_{(2)}

똑같이 각 자릿수를 더하면서, 표현 범위를 벗어나는 값을 버리면 아래와 같은 결과를 얻는다.

13(10)=1111111111110011(2)-13_{(10)} = 1111111111110011_{(2)}

30000 + 30000

30000을 2의 보수로 나타내보자.

30000(10)=0111010100110000(2)30000_{(10)} = 0111010100110000_{(2)}

덧셈연산을 수행하면 아래와 같은 결과가 나온다.

5536(10)=1110101001100000(2)-5536_{(10)} = 1110101001100000_{(2)}

2진수로는 60000 이지만 2의 보수로는 -5536으로 우리의 기대와는 다른 결과가 나왔다.

이처럼 표현 범위를 넘어서서 잘못된 혹은 의도하지않은 값이 나오는 현상을 오버플로우(overflow) 라고 한다.

2. 정수의 뺄셈

회로 중에는 뺄셈의 역할을 수행하는 감산기(subtractor)가 존재한다.

하지만 컴퓨터는 감산기가 아닌 가산기를 활용하여 뺼셈을 수행한다.

예를 들어 감산기가 존재한다면

57=25 - 7 = -2

라는 연산이 가능할 것이다.

하지만 컴퓨터는 가산기로 뺄셈을 수행하므로 아래와 같이 진행하게 된다.

5+(7)=25 + (-7) = -2

6 - 7 = 6 + (-7)

피연산자를 2의 보수로 표현해보자.

6(10)=0000000000000110(2)7(10)=1111111111111001(2)6_{(10)} = 0000000000000110_{(2)} \\ -7_{(10)} = 1111111111111001_{(2)}

각 자릿수를 더하면 아래와 같이 -1의 결과를 얻는다.

1(10)=1111111111111111(2)-1_{(10)} = 1111111111111111_{(2)}

-6 - 7 = (-6) + (-7)

피연산자를 2의 보수로 표현해보자.

6(10)=1111111111111010(2)7(10)=1111111111111001(2)-6_{(10)} = 1111111111111010_{(2)} \\ -7_{(10)} = 1111111111111001_{(2)}

각 자릿수를 더하면 아래와 같이 -13의 결과를 얻는다.

13(10)=1111111111110011(2)-13_{(10)} = 1111111111110011_{(2)}

-30000 - 30000 = (-30000) + (-30000)

-30000을 2의 보수로 나타내보자.

30000(10)=1000101011010000(2)-30000_{(10)} = 1000101011010000_{(2)}

두 수를 더하면 오버플로우가 발생하여 아래와 같은 결과값이 나온다.

5536(10)=0001010110100000(2)5536_{(10)} = 0001010110100000_{(2)}