2의 보수 와 2진수의 음수표현 twos complement

이성묵·2021년 8월 19일
0

ComputerScience

목록 보기
1/1

2진법과 정수 표현

위치적 기수법 Positional Notation
각 숫자의 위치가 표현하는 계수들의 곱으로 표현하는 기수법이다.

진법 notation 이란?
N 을 Base 표준 적인 형태의 위치적 기수법. 일반적으로 사용하는 진법은 10진법, 2진법 16진법등이 있다.

우리가 일반적으로 실생활에서 사용하는 수의 표현은 10을 기수로 하는 10 진법입니다.
하지만 컴퓨터 에서는 0과 1로만 표현되는 2 진법 체계를 사용합니다.

컴퓨터는 스위치가 켜져있는가 1 on, 스위치가 꺼져있는가 0 off로 표현하는것이 오류를 최소화 하고 효율적이기 때문입니다.

수의 표현

N 진법의 수 k는 다음과 같이 표현 될수 있습니다.

k=xnbn+xn1bn1+...+x1b1+x0b0k=i=0nxibik = x_nb^n + x_{n-1}b^{n-1}+ ...+ x_1b^1+x_0b^0 \\ k = \sum_{i=0}^n x_ib^i

이에따라 10 진법 수 12(10)12_{(10)}를 풀어보면 (101×1)+(100×2)(10^1\times 1)+(10^0\times 2) 으로 표현됩니다.
121012_{10}을 이진법으로 표현하면 110021100_{2}이고 이를 풀어써보면
1×23+1×22+0×21+0×201\times 2^3 + 1\times 2^2 + 0\times 2^1 + 0\times 2^0 이 됩니다.

일반적으로 십진법의 수와 구별하기 위해 다음과 같이 쓴다.

1100b
1100(b)
0b1100 일반적인 프로그래밍 언어에서 사용됨

컴퓨터에서 2진법

컴퓨터에서 수의 표현은 컴퓨터의 처리 단위에 따라서 다릅니다.
32bit 컴퓨터에서는 121012_{10}0000 0000 0000 0000 0000 0000 0000 1100(2)0000\ 0000\ 0000\ 0000\ 0000\ 0000\ 0000\ 1100_{(2)} 로써 표현합니다.

컴퓨터에서는 수의 2진수 각 자리를 bit 라고 부릅니다.
4개의 bit는 nibble 8개의 bit는 byte라고 부르고 컴퓨터가 하나의 명령어로 실행될 수 있는 데이터를 워드 word라고 합니다.

nbit 컴퓨터라고 하는것은 register 의 크기 word를 뜻하는 것이고 한번에 표현할수 있는 최대값이 됩니다.

register 의 값을 초과하면 overflow 초과된 비트는 버려집니다.

워드 단위의 좌, 우를 구별하기 위해 가장 오른쪽 bit를 MSB Most Significant Bit라고 부르고, 가장 왼쪽의 bit 를 LSB Least Siginificant Bit 라고 부릅니다.

2진수의 덧셈

일반적으로 우리가 덧셈을 할때는 오른쪽에서 왼쪽 자릿수로 숫자들을 하나씩 더합니다.
세로셈법으로 12 + 9 를 계산하면 다음과 같습니다.

     1        12 +    9       21\ \ \ \ \ 1 \\ \ \ \ \ \ \ \ \ 12 \\ \ + \ \ \ \ 9 \\ \\ \rule{2cm}{0.4pt} \\ \ \ \ \ \ \ \ 21

1의 자리수 를 먼저 계산하고 2+9=10×1+92 +9 =10\times 1+9
1의 자리 연산에서 나온 받아 올림수 Carry 와 10 의 자리 연산을 수행합니다.
10(carry)+10=2010(carry) + 10 = 20

4bit 이진 수의 덧셈도 같은 방법으로 할수 있습니다.

1       1100+1001   110011\ \ \\ \ \ \ \ \ 1 1 0 0 \\ + 1 0 0 1 \\ \rule{2cm}{0.4pt} \\ \ \ \ 11001

하지만 컴퓨터에서 수의 표현은 한계가 정해져 있습니다.
앞서 예시를 든 4bit의 이진수는 최대 2412^4-1개의 수만 표현할수 있고 그이상 넘어서는 수의 표기가 불가능 합니다.
만약 최상위 비트 MSB의 연산결과가 carry를 발생시켜 정해져 있는한계를 넘는다면 overflow 가 발생했다고 말하고 데이터 용량을 넘어선 비트는 무시됩니다.
따라서 12 + 9 에서는 overflow가 발생했고 초과한 비트를 버리고 나온값은 1001이 됩니다.

2진수의 음수 표현

10진법의 음수 표현은 -5, -4 등 숫자 앞에 음의 부호를 붙여서 표기합니다.
하지만 2진수의 음수는 여러가지 방식으로 표현될 수 있습니다.

부호 절댓값 Sign and Magnitude

가장 직관적이고 간단한 방법을 양수와 음수를 구별할수 있도록 하나의 비트로 구분 하는 것 입니다.

편리하게 최상위 비트 MSB로 부호를 표시합니다.
하지만 이런 방식으로 음수를 표현하게 되면 몇가지 단점이 있습니다.

4bit 이진수를 나타내면 다음과 같습니다.

10진법2진법
40100
30011
20010
10001
+00000
-01000
-11001
-21010
-31011
-41100

첫번째로 0을 표현할때 -0 과 +0 으로 불필요하게 나누어집니다.

두번째로 두수의 덧셈을 할때 문제가 생깁니다.

4bit 2진수 5과 -5를 더해보겠습니다.

     0101+1101   10010\\ \ \ \ \ \ 0 1 0 1 \\ + 1 1 0 1 \\ \rule{2cm}{0.4pt} \\ \ \ \ 1 0 0 10

최상위 비트의 자리 올림수를 제외하면 덧셈의 결과는 2가 됩니다.
5+(-5)는 0이 나와야하는데 일반적인 덧셈 방법으로는 예상과 다른 결과가 나옵니다.

이를 개선하기 위해서는 부호값을 분리하여 뺄셈을 따로하는 방법을 사용해야 합니다.
사람에게는 간단한 일 이지만 컴퓨터의 논리회로 설계에서는 매우 복잡해 집니다.

보수 방식 'Method of Complement'

보수란?
보수 방식이란 같은 범위의 양수와 음수를 같은 덧셈 알고리즘 으로 연산할수 있게 만들어 주는 방법입니다.
주어진 자리 수에서 절반은 양수를 표현하고 나머지 절반은 각 양수의 덧셈 역원을 나타냅니다.
이러한 방식으로 어떤 수의 뺄셈은 주어진 수의 보수를 더하는 방식으로 이루어집니다. wiki

n 자리 수의 보수에는 두가지가 있습니다.

  • n-1 의 보수
  • n 의 보수

예를 들어 10진수에는 10의 보수와 9의 보수가 있습니다.

diminished radix complement n-1 의 보수

b 진법 수 x에 대한 n - 1 의 보수는 (bn1)x(b^n-1)-x 입니다.

두 수의 합이 밑이 되게 하는 수 자리 올림이 없는 최대 수 에서 1을 뺀것 입니다.

10진수를 예로 들면
1 의 보수는 8, 7 의 보수는 2, 99의 보수는 0 입니다.

9의 보수란 두수를 더해 9가 되게 만드는 수입니다.

2진수는 조금 더 간단한데 두 수를 더해 1이 되는 수입니다.
따라서 각 비트들을 반대로 뒤집은 수가 됩니다.

1001의 1의 보수는 11111001=(241)1001=01101111-1001= (2^4-1) -1001= 0110 이 됩니다.
bit 연산의 Not 연산과 동일합니다. Not(1001)=0110Not(1001)=0110

radix complement n 의 보수

n 자리수 b 진법 수 x에 대한 n 의 보수는 bnxb^n-x 입니다.

예를 들어 15에 대한 10의 보수를 구한다면 10215=7510^2-15=75 가 됩니다.

이는 n - 1 의 보수에서 1을 더함으로 구할수 있습니다.

1의 보수 Ones Complement

앞서 설명한 기수의 보수 방법으로 2진수를 표현해 보겠습니다.

1의 보수를 구하는 방법은 모든 자리수를 반대로 뒤집는 것 입니다. 1 ->0 , 0 -> 1
이는 논리 연산 Not 과 동일한 연산입니다.

1의 보수를 구해보면 다음과 같습니다.

10진법2진법10진법2진법
-7100070111
-6100160110
-5101050101
-4101140100
-3110030011
-2101020010
-1111010001
-01111+00000

부호 절대값 방식과 같이 0의 표현이 -0과 +0 두가지로 나누어졌습니다.

1의 보수 방식으로 4bit 수 5 에서 3을 빼보겠습니다.
5-3 을 계산하기 위해서 3의 보수를 구한후 이를 더해줍니다.

    1           0101+1100   10001\ \ \ \ 1\ \ \ \ \ \ \\ \\ \ \ \ \ \ 0 1 0 1 \\ + 1 1 0 0 \\ \rule{2cm}{0.4pt} \\ \ \ \ 1 0 0 01

결과는 10001이 나왔습니다. 최상위 비트에서 자리 올림수carry가 발생했고 이를 버리면 결과는 0001 이 됩니다. 5 - 3 의 결과는 2가 되어야 조금 이상한 결과가 나왔습니다.

다시 6 - 4 의 연산을 해보겠습니다.

11     0110+1011   100011 1 \\ \ \ \ \ \ 0 1 1 0 \\ + 1 0 1 1 \\ \rule{2cm}{0.4pt} \\ \ \ \ 1 0 0 0 1

최상위 비트 자리올림수를를 버린 결과는 0001 입니다. 다시 조금 맞지 않는 결과가 나왔습니다.

이번에는 5-5의 연산을 해보겠습니다.

     0101+1010    1111\\ \ \ \ \ \ 0 1 0 1 \\ + 1 0 1 0 \\ \rule{2cm}{0.4pt} \\ \ \ \ \ 1 1 1 1

결과는 1111 = -0 이 나왔습니다.
+0의 결과를 기대했지만 거의 비슷한 결과가 나왔습니다.

앞서 계산한 수들의 결과는 다음과 같습니다.

0101+1100=00010110+1011=00010101+1010=11110101+1100=0001 \\ 0110+1011=0001 \\ 0101+1010=1111

결과들을 보면 올바른 값과 모두 다르지만 패턴이 보입니다.

결과 값에서 항상 1을 더해주면 올바른 값이 나오게 됩니다.

0001+0001=00101111+0001=00000001+0001=0010\\ 1111+0001=0000

이렇게 최상위 비트에서 자리 올림수가 발생했을때는
최하위 비트에 1을 더해줌으로써 기대 했던 결과를 얻을수 있습니다.
이를 순환 자리 올림수 EAC end-around-carry 라고 합니다.

하지만 0 이 나오는 결과는 항상 -0 이 나오게 됩니다.

1의 보수는 부호 절대값 방식에서 부호비트를 제외하고 모두 뒤집는것과 같습니다.
비교 해보자면 -125 의 부호 절대값 방식은 1111 11011111\ 1101 이고 1의 보수 방식은 1000 00101000\ 0010 입니다.

1의 보수 방식은 부호 절대값 방식에서 생겼던 문제점을 해결할수 있지만 아직도 컴퓨터가 수행하기에는 조금 복잡합니다.

2의 보수 twos complement

1의 보수 방식은 0이 두가지 방식으로 표현된다는 문제와 자리올림수가 발생했을때 따로 처리 해주어야 한다는 단점이 있었습니다.

이런 단점들을 2의 보수 방식을 사용해서 해결할수 있습니다.

앞서 보았던 n의 보수방식으로 보수를 구하면 1의 보수에서 1을 더하면 됩니다.

2의 보수로 4 bit 2진수를 구해보면 다음과 같습니다.

10진법2진법
70111
60110
50101
40100
30011
20010
10001
00000
-11111
-21110
-31101
-41100
-51011
-61010
-71001
-81000

이렇게 표현된 수는 1의 보수 에서 1이 더해진 값을 각 양수에 대응 시키는 것과 같습니다.
또한 2의 보수로 수를 표현하면 -0 이 없어진 것을 볼수 있습니다.

4bit 수의 음수가 표현된 방식을 보면 최상위 비트를 23-2^3으로 보고 표현된 각 양수를 빼주는것 과도 같습니다.

7=23+(22+21+20)=1001-7 =-2^3 + (2^2 + 2^1 + 2^0) = 1001

같은 방식으로 16bit, 32 bit, 64bit 자리의 이진수의 보수도 구할수 있습니다.

-2를 32bit 로 나타내면 다음과 같습니다.
1111 1111 1111 1111 1111 1111 1111 11101111 \ 1111 \ 1111\ 1111\ 1111\ 1111\ 1111\ 1110

4bit 의 수는 같지만 앞서 나오는 모든 비트가 1로 써 표현됩니다.

몇가지 연산을 해보겠습니다.

5+(-5)

    111       0101+1011  10000\ \ \ \ 1 1 1 \ \ \\ \\ \ \ \ \ \ 0 1 0 1 \\ + 1 0 1 1 \\ \rule{2cm}{0.4pt} \\ \ \ 1 0 0 0 0

최상위 비트에서 발생한 자리올림수를 버리면 결과는 기대했던 결과인 0이 됩니다.

6+(-4)

11     0110+1100  100101 1 \\ \ \ \ \ \ 0 1 1 0 \\ + 1 1 0 0 \\ \rule{2cm}{0.4pt} \\ \ \ 1 0 0 1 0

이전과 같이 자리 올림수를 버리면 결과는 0010 = 2 가 됩니다 기대했던 결과와 같습니다.

2의 보수를 사용하면 덧셈과 뺄셈 연산도 정확하게 나오는 것을 볼수있습니다.

결론

CPU의 구성하는데 중요한 요소인 산술 논리 장치 ALU Arithmetic Logic Unit 가 있습니다.
모든 정수 연산은 ALU에서 하게 되는데 내부적으로 가산기 Adder를 사용해 덧셈 연산만 사용해 정수 연산을 수행하게 됩니다.

이렇게 뺄셈과 덧셈을 하나의 연산을 할 수 있다는 것은 조금 더 효율적인 회로 설계가 가능 하다는 뜻입니다. 이런 이유로 현대 컴퓨터의 대부분이 2의 보수 방식을 선택하고 있습니다.

잘못된 부분이 있다면 많은 지적 부탁드립니다.


참고자료

stranger's lab
method of complement
signed number representations
ben eater youtube
컴퓨터 구조와 설계 L. Howard Pollard p.73-76

0개의 댓글