진법과 보수

2025. 9. 11. 16:20·Develop/Algorithm

컴퓨터공학을 배우게 된다면 2진법, 10진법 혹은 1의 보수, 2의 보수와 같은 개념을 접하게 됩니다.

오늘은 이 진법과 보수에 대해 튼튼히 개념을 쌓아보고자 합니다.

숫자

숫자는 '개수'를 세기 위한 아이디어에서 시작되었습니다. 

그러다가 없는 것을 표현하는 0, 손실을 의미하는 - 같은 개념들도 추가되기 시작했죠.

 

진법 (= 기수, radix)

진법은 한 자리에 몇가지 종류의 값이 들어갈 수 있는지를 의미합니다.

2진법은 한 자리에 2가지 종류의 값이 들어갈 수 있고, 10진법은 한 자리에 10가지 종류의 값이 들어갈 수 있습니다.

 

예를 들어 10진법에서 138(백삼십팔)이라는 숫자를 예시로 들어보겠습니다. 

138은 총 3자리로 이루어져 있으며, 각 자리는 다음과 같이 구성됩니다.

 

[1][3][8]

 

이때 [ ] 안에 들어갈 수 있는 값은 0~9까지 총 10가지입니다. 그래서 10진법입니다.

 

또다른 예시로, 2진법에서 011이라는 숫자를 생각해봅시다.

011 또한 총 3자리로 이루어져 있으며, 각 자리는 다음과 같이 구성됩니다.

 

[0][1][1] 

 

이때 [ ] 안에 들어갈 수 있는 값은 0~1까지 총 2가지입니다. 그래서 2진법입니다.

 

따라서 n진법 == 한자리에 n가지 종류의 값을 넣어 숫자를 표현하는 방식 입니다.

 

 

진법의 표현식

결국 진법은 숫자를 나타내는 방법을 의미합니다.

한 자리에 2가지 값을 넣든, 10가지 값을 넣든 동일한 숫자를 나타낼 수 있어야합니다.

 

그렇다면 위의 10진법 예시와 2진법 예시를 다시 가져와봅시다.

 

10진법에서 138이라는 숫자는

[1][3][8] = 1 *(10 ^ 2) + 3 * (10 ^ 1) + 8 * (10^0) 을 의미하고,

 

2진법에서 011이라는 숫자는

[0][1][1] = 0 * (2^2) + 1 * (2^1) + 1 * (2^0) 을 의미합니다.

 

이는 다음과 같은 n진법에 대한 일반식을 유도할 수 있습니다.

[a][b][c] 라는 숫자에 대해 n진법일 때,
a * (n^2) + b * (n^1) + c * (n^0) 라는 숫자를 의미한다.

 

진법간의 변환 

2진법 <-> 10진법으로 변환을 예시로 들어봅시다.

인간은 대부분 기본적으로 10진법을 사용하고 있습니다. 인간의 손가락이 10개이기 때문입니다.

 

"열 개가 존재한다" 를 숫자로 나타내봅시다. 이를 10진법과 2진법으로 나타내면 다음과 같습니다.

10진법: 10 
2진법 : 1010

 

한 자리에 들어갈 수 있는 값의 개수는 결국 경우의 수와 이어집니다.

2진법에서는 0000은 0을 뜻하고 0001은 1을 뜻합니다.

그다음 2를 의미하려면 왼쪽의 비트를 활용하여 0010 이라고 표기하고, 3을 의미하려면 0011 이라고 표현해야합니다.

 

차례 대로 표현할 수 있는 방식대로 표현을 하는겁니다. 

 

2진법 -> 10진법으로 변환하는 방법은 그저 차례대로 1 + 2 + 4 + 8.. 등 켜져있는 bit를 계산하면 됩니다.

10진법 -> 2진법으로 변환하는 방법은 2로 나누고 나머지를 기록, 몫이 0이 될 때까지 반복한 뒤 나머지를 거꾸로 읽으면 됩니다.

 

 

보수

보수는 간단하게 보충하는 수라고들 많이 알고 있으실텐데, 와닿지 않을겁니다.

목적성에 집중하여 설명하면, 보수는 뺄셈(-)을 덧셈(+)으로 표현하기 위해 필요한 수를 보수라고 표현합니다. 

의미에 집중하여 설명하면, 보수는 어떤 수를 기준값(기수, radix)에서 뺀 나머지를 의미합니다.

 

보수가 필요한 이유

덧셈으로만 계산하는 것은 훨씬 그 계산이 가볍고 빠릅니다. 따라서 고대 수학자들은 보수라는 개념을 생각해냈습니다.

이는 현대에 와서도 마찬가지입니다. 뺄셈은 구현하기가 덧셈에 비해 복잡합니다. 뺄셈 회로를 만드려면 복잡도가 올라갑니다.

 

그래서 기계식 계산을 하는 주판을 두들기며 주산을 하던 시대에도, 덧셈으로 뺄셈을 처리했습니다.

컴퓨터 공학에서도 이 개념을 차용해왔습니다. 따라서 cpu도 보수를 이용하여 뺄셈을 덧셈으로 변환하여 처리합니다.

 

특히 cpu에서는 1의 보수가 아닌 2의 보수 방식으로 뺄셈을 처리합니다.

이렇게 됨으로써 좀 더 간편하게 계산을 처리하고, 중복된 0의 표현도 방지합니다. 

어떻게 계산이 간편해지는가?
: 1의 보수로 계산을 한다면 결국 최종 결과에서 end-arround-carry를 반영해주어야합니다.
즉 carry값이 발생 시 LSB (가장 작은 비트)에 +1을 해주어야합니다. 이 과정을 처리하기 위해서는 회로의 추가 설계를 유발합니다.

중복된 0의 표현? 
: 단순하게 1의 보수로 계산한다면, 0001이라는 숫자의 보수는 1110이 될겁니다.
근데 이런 경우에는 0000이라는 숫자의 보수는 1111이 되고, 0이 +0, -0 2가지 방식으로 중복 표현됩니다.

 

(n-1)의 보수 , n의 보수 

n진법에서 유의미한 보수는 딱 2가지 입니다.

(n-1)의 보수 , n의 보수 

 

예를 들어 2진법에서는

1의 보수, 2의 보수가 유의미합니다.

 

10진법에서는

9의 보수, 10의 보수가 유의미합니다.

 

(n-1)의 보수가 있기에 n의 보수도 유의미해집니다.

(n-1)의 보수에다 +1을 한 값이 n의 보수 이기 때문입니다.

 

예를 들어 9의 보수는 9에서 각 자리수를 뺀 값을 의미합니다.

따라서 156의 9의 보수는 999-156 = 843 입니다.

이때 10의 보수는 여기에 1을 더한 844입니다.

 

또다른 예시를 들어봅시다. 이번에는 2의 보수와 1의 보수를 봅시다.

011 이라는 2진법 숫자가 존재할 때, 1의 보수는 각 자리에서 1을 뺸 숫자입니다.

따라서 011의 1의 보수는 111 - 011 = 100 입니다. (2진법에서 1의 보수는 결국, 숫자를 반대로 뒤짚는거나 마찬가지입니다. 1-> 0, 0->1)

011의 2의 보수는 100에 1을 더한 101 입니다.

 

참고로 n의 보수를 만들기 위해 (n-1)의 보수에서 +1을 해주는 건 end-arround-carry라고 합니다. 

 

 

보수를 사용하여 뺄셈해보기

바로 위에서 (n-1)의 보수가 있어야 n의 보수가 존재한다고 했습니다.

실제로 저희 뺄셈에서는 (n-1)의 보수를 보충한 n의 보수를 자주 사용합니다. 

 

위에서 들었던 10진법, 2진법 예시를 다시 사용하겠습니다.

156의 10의 보수 : 844

011의 2의 보수 : 101

 

10진법에서는 10의 보수를, 2진법에서는 2의 보수를 "더하면" 그게 결국 뺄셈이 됩니다.

즉, 472 - 156 이라는 수식은 472 + 844(156의 10의 보수) 와 동일한 결과를 뱉습니다.

 

472+ 844 = 1315 라는 값이 나오는데, 저희는 오직 최대 3자리만 이용합니다. 따라서 4번째 자리인 1은 날립니다.

그럼 315라는 값이 되는데, 이는 472-156의 값과 동일합니다. 

 

이진법 뺄셈인 111 - 011도 111 + 101로 변환이 가능합니다. 이는 111 + 101 = 1100 이라는 값이 되는데, 

overflow가 일어난 4번째 자리인 1은 마찬가지로 버립니다. 그럼 100이 됩니다. 

10진법으로 표현하면 7 - 4를 한 셈인데, 3(이진법:100)이 잘 나오네요.

 

보수의 수학적 원리 (cpu가 1의 보수를 사용할 경우,  추가 보정이 필요하다는 증명)

여기부터는 생략하셔도 됩니다. 하지만 궁금하신 분들이 있으실까봐 직접 정리해보았습니다.

왜 cpu가 1의 보수가 아닌 2의 보수를 사용하는지, 추가 보정이 왜 필요하게 된 것인지를 증명한 수식입니다.

 


 

 

 

 


긴 글 읽어주셔서 감사합니다.

'Develop > Algorithm' 카테고리의 다른 글

정렬 비교 함수 (compare)  (0) 2025.09.20
비트마스킹 (with 비트 연산자)  (1) 2025.09.11
모듈러 연산  (0) 2025.03.23
완전 탐색, 백트래킹  (2) 2024.11.16
트리 순회(Tree traversal) - 후위, 전위, 중위  (0) 2024.11.06
'Develop/Algorithm' 카테고리의 다른 글
  • 정렬 비교 함수 (compare)
  • 비트마스킹 (with 비트 연산자)
  • 모듈러 연산
  • 완전 탐색, 백트래킹
ocahs
ocahs
개발 내용을 담습니다.
  • ocahs
    ocahs 개발 블로그
    ocahs
  • 전체
    오늘
    어제
    • 분류 전체보기 (47)
      • Develop (47)
        • Frontend (25)
        • Javascript (7)
        • Algorithm (14)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    재귀타입
    promise reject
    요청의 역사
    Promise
    번들러
    비트 연산자 활용 예시
    JS
    line sweeping
    Working Set Model
    vite
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
ocahs
진법과 보수
상단으로

티스토리툴바