Epistemology

The truth is out there.

컴퓨터가 빼기를 하는 방법: 1번째 글

2025-08-23

이 글은 이진수로 뺄셈을 하는 방법을 소개하는 글입니다. 좀 더 자세히 설명하면 컴퓨터가 어떻게 뺄셈을 하는지 개념적으로 설명하고자 하는 글입니다. 컴퓨터는 기본적으로 이진수를 가지고 연산하기 때문에 이 글 또한 컴퓨터에서 어떻게 이진수 뺄셈을 하는지 설명하고자 합니다.

우리가 뺄셈할 때 알아야 할 것 중의 하나가 ‘빌림수’라는 개념입니다. 뺄셈을 할 때, 왜 이 개념이 필요한지 예를 들어 봅시다. 253 - 176을 하려고 할 때, 우리는 우선 253의 마지막 숫자인 3에서 176의 마지막 숫자인 6을 빼려고 합니다. 그런데 36보다 작기 때문에 뺄셈을 할 수 없습니다. 이때 필요한 것이 ‘빌림수’입니다. 일반적으로 그 앞의 숫자인 5에서 1을 빌려와, 즉 10을 빌려와서, 이 둘을 합친 13에서 6을 빼게 됩니다.

이런 과정이 바로 ‘빌림수’를 이용하여 뺄셈을 하는 것입니다. 이렇게 복잡한 과정을 컴퓨터에게 알려주는 것보다 더 편리한 방법이 있는데 바로 ‘보수(complement)’라는 개념을 이용하는 것입니다. 이 보수라는 개념은 10진수 뺄셈보다 2진수 뺄셈에서 더 효과적입니다. 이 글에서 왜 그런지 살펴보겠습니다.

이 개념을 사용하기 전에 우선 뺄셈이 결국 음수를 더하는 것과 같다는 것을 상기할 필요가 있습니다. 즉 253 - 176-176 + 253과 같습니다. 이때 수식에서 만약 같은 수를 더하고 빼고 더한다면, 최종 계산 결과에 영향을 주지 않습니다. 다시 말해 1000 - 176 + 253 - 1000과 같이, 처음에 1000을 더하고 1000을 뺀다면, 앞의 식과 같은 결과가 나옵니다. 이를 조금 더 변형하면 999 - 176 + 253 + 1 - 1000도 같은 결과가 나온다는 것도 알 수 있습니다. 즉 9991을 더하고 한번에 1000을 빼도 그 계산 결과가 바뀌지 않습니다.

여기서 999 - 176 부분이 앞에서 말한 ‘보수’를 이용하는 부분입니다. 176의 보수를 구하는 것과 999에서 176을 빼는 것은 동일합니다. 특정 숫자 x9로만 이루어진 숫자에서 빼면, 그 숫자를 x의 9의 보수라고 부릅니다. 176의 9의 보수는 999 - 176을 계산한 823입니다. 위 계산에 이 결과를 추가해 봅시다. 원래의 식은 다음과 같았습니다.

999 - 176 + 253 + 1 - 1000

여기에 9의 보수를 사용하면 다음과 같이 됩니다.

823 + 253 + 1 - 1000

이 식에서 앞의 덧셈을 모두 계산하면 1077 - 1000이 됩니다. 그리고 마지막 뺄셈을 하면, 77이 나오게 됩니다. 이건 원래 계산하고자 했던 253 - 176 = 77의 결과와 같습니다. 이처럼 복잡하게 계산하는 이유는 ‘빌림수’라는 개념을 사용하지 않고 뺄셈을 하기 위해서입니다. 다시 말해 176의 보수를 더한 다음 1을 더하고 1000을 빼면 되는 것입니다. 이렇게 하면 빌림수를 사용하지 않고 뺄셈을 할 수 있게 됩니다.

그러면 이번에는 앞의 식에서 두 숫자를 바꿔서 뺀 결과가 음수가 되는 식을 만들어 보겠습니다. 바꿔 만든 식은 다음과 같습니다: 176 - 253. 이것을 9의 보수를 이용해 풀어 봅시다. 이 뺄셈을 앞에서처럼 변형해보겠습니다.

999 - 253 + 176 + 1 - 1000

우선 253의 9의 보수를 구해 봅시다. 9의 보수를 구하기 위해서는 999에서 253을 빼면 됩니다. 이 결과는 746이고, 이 숫자가 253의 9의 보수입니다. 이 값을 이용해 윗 식을 변경하면 다음과 같이 됩니다.

746 + 176 + 1 - 1000

176 + 746 + 1을 하면 923가 됩니다. 앞에서 9991을 더했기 때문에 더한 값에서 1000을 빼면, 923 - 1000 = -77이 됩니다. 결과가 정확하게 나왔습니다. 같은 수를 더하고 뺐기 때문에 당연히 최종 결과에는 아무런 영향을 주지 않습니다.

이렇게 계산하는 것이 단지 ‘빌림수’라는 것을 이용하지 않는 것을 빼고는 별로 실익이 없는 것처럼 보입니다. 그러나 2진수에서 이런 방식을 사용하면 뺄셈 계산이 쉬워집니다. 앞에서 설명한 것처럼 십진수에서는 9의 보수가 있다면, 이진수에는 1의 보수가 있습니다. 이진수에서는 특정 숫자 x1로만 이루어진 숫자에서 빼면, 그 숫자를 x의 ‘1의 보수(ones’ complement)’라고 부릅니다.

앞에서 계산한 것을 이진수로 해봅시다. 우선 253 - 176-176 + 253이 같은 계산이라는 것에서부터 출발해 봅시다. 253을 2진수로 표현하면 1111_1101이고 1761011_0000입니다. 그러면 -176 + 253을 이진수로 표현하면 다음과 같습니다. 참고로 이진수 숫자를 읽기 쉽게 4자리마다 밑줄, _을 추가하겠습니다.

-1011_0000 + 1111_1101

이 식에서 1111_11110000_0001을 더하고, 마지막에 이 두 숫자의 합인 1_0000_0000을 빼면, 같은 수를 더하고 뺐기 때문에 계산에 영향이 없습니다. 이를 수식에 적용해 봅시다.

1111_1111 - 1011_0000 + 1111_1101 + 0000_0001 - 1_0000_0000

여기서 맨 앞 부분인 1111_1111 - 1011_0000에서는 앞에서 소개한 보수를 이용하고 있는 부분입니다. 십진수에서 9의 보수를 구하는 방법과 다르게, 이진수에서는 1의 보수를 구하는 것은 쉽습니다. 이진수에서 특정 숫자 x의 1의 보수를 구하기 위해서는 직접 빼는 것보다, 1의 보수를 구하고자 하는 숫자를 반전하면 쉽게 구할 수 있습니다. 1111_1111 - 1011_00001011_0000의 1의 보수를 구하는 식이고 계산 결과는 0100_1111이 됩니다. 이 값은 단순하게 01을 바꿔준 것과 동일합니다. 이런 아이디어 때문에 컴퓨터는 이진수의 1의 보수를 쉽게 구할 수 있습니다. 이를 적용하면 다음과 같이 됩니다.

0100_1111 + 1111_1101 + 0000_0001 - 1_0000_0000

여기서 앞의 두 수를 더하면 다음과 같습니다.

1_0100_1100 + 0000_0001 - 1_0000_0000

그리고 마지막으로 0000_0001을 더하면 다음과 같습니다.

1_0100_1101 - 1_0000_0000

마지막으로 1_0000_0000을 빼면 됩니다. 이 숫자를 빼는 것은 맨 앞자리 1만 제거하면 되는 것입니다. 결국 계산 결과는 다음과 같습니다.

1_0100_1101 - 1_0000_0000 = 0100_1101

0100_1101은 십진수로 77입니다. 결국 같은 결과가 나왔습니다. 계산 방법을 정리하면, 빼고자 하는 값의 1의 보수를 더하고 0000_0001을 더한 다음, 맨 앞자리 1을 제거했습니다.

다음으로 앞에서 했던 것과 마찬가지로 앞의 식에서 두 숫자를 바꿔서 뺀 결과가 음수가 되는 식을 만들어 보겠습니다. 바꿔 만든 식은 다음과 같습니다.

176 - 253

이것을 이진수로 바꿔 1의 보수를 이용해 풀어 봅시다. 176 - 253-253 + 176과 같은 계산이라는 것에서부터 출발해 봅시다. 253을 2진수로 표현하면 1111_1101이고 1761011_0000입니다. 그러면 -253 + 176을 이진수로 표현하면 다음과 같습니다.

-1111_1101 + 1011_0000

이 식을 앞에서 했던 방법을 가져와서 변경하면 다음과 같습니다.

1111_1111 - 1111_1101 + 1011_0000 + 0000_0001 - 1_0000_0000

앞의 두 숫자는 1111_1101의 1의 보수를 구하는 것입니다. 바로 쉽게 할 수 있습니다.

0000_0010 + 1011_0000 + 0000_0001 - 1_0000_0000

앞의 세 숫자를 더하면 다음과 같습니다.

1011_0011 - 1_0000_0000

그러나 이번에는 다른 문제가 생겼습니다. 작은 수에서 큰 수를 빼야 하는 문제입니다. 직관적으로 작은 수에서 큰 수를 뺄 수 없기 때문에, 큰 숫자인 뒷 숫자에서 작은 앞 숫자를 빼고 마이너스, -를 추가하면 -0100_1101이라고 하면 될 것 같습니다. 그러나 문제는 컴퓨터의 가장 기본적인 부품인 CPU는 원칙적으로 전기 신호 ‘켜짐(1)‘과 ‘꺼짐(0)만을 이해할 수 있다는 것입니다. 원칙적으로 컴퓨터는 -0100_1101을 처리할 수 없습니다. 그러면 어떻게 해야 할까요? 다음 글에서 해결 방법에 대해서 알아보겠습니다.

그래서 모든 숫자를 01의 조합으로 처리하고 저장해야, 이를 계산하는 CPU도 최대한 단순하고 효율적으로 처리할 수 있습니다. 음수 또한 -0100_1101과 같이 마이너스 기호를 사용하지 않고 01으로 저장해야 합니다.

이때 필요한 것이 ‘2의 보수(Two’s complement)’입니다. 2의 보수는 컴퓨터에서 정수(양의 정수, 음의 정수, 0을 포함)를 저장하고 처리하는 가장 일반적인 방법입니다. 2의 보수란 어떤 수의 ‘1의 보수’에 1을 더한 값이라고 생각하면 됩니다.

우리는 이미 이 2의 보수를 가지고 176 - 253을 계산해 봅시다. 앞에서도 이야기했지만, 이 식은 -253 + 176과 같은 계산이고, 숫자를 이진수로 바꾸면 다음과 같이 됩니다.

-1111_1101 + 1011_0000

앞에서 말한 것처럼 1111_1101을 뺀다는 것은 1111_1101의 2의 보수를 더한다는 것과 같습니다. 이 2의 보수는 1111_1101을 반전하고 1을 더하면 됩니다. 반전을 하면, 0000_0010이 되고, 여기에 1을 더하면 0000_0011이 됩니다. 이 2의 보수를 앞의 식에 적용하면 다음과 같습니다.

0000_0011 + 1011_0000

이 식의 계산 결과는 다음과 같습니다: 1011_0011 이를 10진수로 바꾸면 179가 됩니다. 앗! 이상한 결과가 나왔습니다. 이를 처리하기 위해서는 많은 일을 해야 합니다. 글이 너무 길어지기 때문에 다음 글에서 쓰겠습니다.