디지털 회로와 연산

개요

본 문서에서는 컴퓨터가 어떻게 연산을 하는지 알아봅니다.

목표

  • 각 논리 회로에 대해서 이해합니다.
  • 컴퓨터가 어떻게 숫자를 연산하는지 이해합니다.

논리회로

  • 반도체는 전기가 흐르는 도체와 흐르지 않는 부도체 성격을 조건에 따라 선택할 수 있습니다.
  • 흐르냐(1), 흐르지 않느냐(0)의 두 전류의 흐름을 통해서 연산을 할 수 있습니다.
  • 이 논리게이트를 도대체 어디에 사용하는 걸까요?
  • 이론상 4가지 논리회로(AND, OR, XOR, NOT)를 이용하여 CPU를 만들 수 있습니다.

반가산기

  • 2진수 1 + 1은 2진수 10입니다.
  • A가 1, B가 1이면 XOR 연산의 결과 SUM은 0입니다.
  • 동시에 A가 1, B가 1이면 AND 연산의 결과 Carry(자리올림)은 1입니다.
  • 반 가산기로는 1비트 덧셈만 가능합니다.

전가산기

  • 이전 캐리를 같이 가산하여 나아갑니다.
  • 4비트 연산을 할 경우 4개의 전가산기를 사용합니다.
  • 반가산기와는 다르게 여러 비트의 연산이 가능하다는 의미입니다.
  • 전가산기를 지날 때마다 다음 전가산기에 캐리를 넘겨줍니다.

보수

  • 컴퓨터는 가산기으로만 이뤄져있습니다.
    뺄셈도 덧셈연산을 사용합니다.
    여기서 보수의 개념이 필요합니다.
  • 10진수 9의 보수는 1입니다.
    더해서 10이되는 숫자를 보수라 정의하기 때문입니다.
    n진수 x의 보수 y 는 다음과 같습니다.
    y=nay = n - a
  • 10진수에서의 보수를 사용한 빼기 연산의 예는 다음과 같습니다.
    12 - 9 = 3이라고 할 때 10진수 9의 보수는 1이고
    12와 1를 더하면 13이 됩니다.
    이때 13에서 1의 자리수 3이 우리가 찾고자 하는 값입니다.
    10진수에서의 9의 보수는 1이고 이를 10의 보수라 부릅니다.
  • 2진수에서의 보수는 2의 보수라 합니다.
    2의 보수는 다음과 같이 구합니다.
    1의 보수 + 1
    즉 0은 1, 1은 0으로 뒤집고 1을 더하면 구할 수 있습니다.
  • 2의 보수를 구하는 예시는 다음과 같습니다.
    0010 → 1의보수를 취하면 1101 → 1101에서 0001을 더하면→ 1110
  • 4비트 연산에서 2의 보수를 통해서 2진수의 뺄셈을 연산하는 예시는 다음과 같습니다.
    우선 10진수 연산으로 입니다.
    3-2 = 1
    위 연산을 이진수로 바꾸면 다음과 같습니다.
    0011 - 0010
    여기서 0010을 1의보수를 취해줍니다.
    0011 +1101
    그다음 1101에서 0001을 더해줍니다.
    0011 + 1110
    그 다음 값을 계산하면 다음과 같습니다.
    1 0001
    4비트 연산이므로 여기서 맨 앞에 가장 높은 자리수를 무시한 값이 우리가 찾는 값입니다.
    즉, 답은 0001 = 1 입니다.

덧셈만 하면 컴퓨터를 구현할 수 있다.

  • 컴퓨터는 보수를 사용하여 더하는 방식으로 빼기를 합니다.
    위 예시에서 보듯 자리올림된 값을 무시하기 때문입니다.
    이런 방식을 사용한다면 이론상 CPU를 만들 수 있습니다.
  • 곱셈은 그럼 어떻게 할 것이냐? 라고 질문하실 수 있을 겁니다.
    그렇지만 곱셈은... 덧셈을 여러번 한 것에 불과합니다.
    7*3=21 은 7을 3번 더한 것입니다.
    즉, 7+7+7 = 21 입니다
  • 그.....렇다면 나누기는 어떻게 할 것이냐? 라고 물어본다면 이것 또한 덧셈을 사용하면됩니다.
    사실 뺄셈이지만 뺄셈도 덧셈으로 표현됩니다.
    9 / 3 은 아래와 같이 표현됩니다.
    9 - 3 = 6 이는 3보다 크거나 같습니다.
    6 - 3 = 3 이는 3보다 크거나 같습니다.
    3 - 0 = 0 여기서 마무리 됩니다.
    이제 몇 번 뺄셈을 했는지 확인합니다.
    3번 했군요!
    피제수를 제수로 여러번 빼면 그것이 나눗셈입니다.
    결국 우리가 찾는 3을 만나게 되었습니다.

나눗셈에서 주의할 점

  • 위에서 보듯 컴퓨터가 나누기를 하는 과정을 이해했다면 다음과 같은 수식이 문제가 있다는 걸 눈치채실 겁니다.
  • 7/0 =?????
  • 컴퓨터의 나눗셈 논리로 식을 전개해나가면,
    7 - 0 = 7은 0보다 크거나 같습니다.
    7 - 0 = 7은 0보다 크거나 같습니다.
    .... 이것을 무한히 반복하게 될 것입니다.
    그래서 CPU에서는 이런 연산을 할 경우 문제가 생기게 됩니다.
    심각하면 CPU가 폭발할 수 있다고 하는데... 무섭군요.
    하지만 저런 연산을 코딩한다고 컴퓨터가 폭발하진 않습니다.
    (어릴 때 뭐라도 잘못 누르면 컴퓨터가 터질까 두려워하던 시절이 있었죠)
    각 프로그래밍 언어마다 0으로 나누는 것에 대해서 대처하고 있기 때문입니다.
  • 참고로 코틀린에서 0으로 나누면 다음과 같은 일이 일어납니다.
    fun main(args: Array<String>) {
     print(7/0)
    }
    
    //결과
    Exception in thread "main" 
    java.lang.ArithmeticException: / by zero
    at MainKt.main(main.kt:2)
    연산예외가 발생하는 군요.
    언어차원에서 위와 같이 CPU가 터지는(?) 불상사를 막아주는 것 같습니다.

2진수에서는 왼쪽으로 밀면 곱셈이다

4비트에서 5를 2진수로 표현하면 0101입니다.
0101을 왼쪽으로 한 칸씩 이동시키면 다음과 같습니다
0 1010
이때 제일 오른쪽에 채워지는 수를 패딩이라 합니다.
패딩은 0으로 채웁니다.
이때 4비트 연산이므로 제일 높은 자리수는 무시합니다.
그리고 10진수로 변환하면 10입니다.
즉 왼쪽으로 한 칸 밀변 곱하기 2, 두 칸밀면 곱하기 4입니다.

2진수에서는 오른쪽으로 밀면 나눗셈이다

4비트에서 6을 2진수로 표현하면 0110 입니다.
0110을 오른쪽으로 한칸 이동시키면 다음과 같습니다.
0011 0
이때 제일 오른쪽에 있는 수를 무시합니다.
그리고 10진수로 변환하면 값은 3입니다.
즉 오른쪽으로 한 칸 밀면 나누기 2, 두 칸 밀면 나누기 4입니다.

마무리

컴퓨터의 모든 연산을 논리회로를 조합해 가산기를 만들어 수행합니다.
이를 통해서 사칙연산을 구현할 수 있고 이것을 쌓아가면서 우리가 사용하는 모든 프로그램이 되는 것이라 생각하면 될 것 같습니다.

좋은 웹페이지 즐겨찾기