블로그 이미지
하루, 글. 그림. 영상매체. 표현을 도와주는 기기들. 도전 중. 동화다아아
    동화다아아

    카테고리

    분류 전체보기 (176)
    잡담 (1)
    IT 기기-리뷰&뉴스 (7)
    리뷰 - 도서 (1)
    리뷰 - 영상 (0)
    리뷰 - 그림/음악 (1)
    내장형 하드웨어 (163)
    Total
    Today
    Yesterday
     

    컴퓨터를 포함한 각종 논리회로에서 음수를 표현하는 방법은 다음 3가지가 있다.


    1. 부호 절대 값 (Sign-Magnitude)

    2. 1의 보수 (1's Complement)

    3. 2의 보수 (2's Complement)


    그런데 실제로 널리 사용되는 것은 2의 보수 방식이다. 이유는 회로가 간단해지기 때문이다.


    1. 부호 절대 값 (Sign-Magnitude)


    부호 절대 값 방식은 가장 쉽게 생각할 수 있는 방식이다. MSB(최상위비트)을 부호비트(0이면 양수, 1이면 음수)로 사용하고, 나머지는 절대 값을 표현한다. 4비트 정수를 예로 들면,


    0000 +0      1000 -0

    0001 1        1001 -1

    0010 2        1010 -2

    0011 3        1011 -3

    0100 4        1100 -4

    0101 5        1101 -5

    0110 6        1110 -6

    0111 7        1111 -7


    그런데 부호 절대값 방식에는 몇 가지 문제가 있다. 우선 0이 두 개(+0과 -0)나 존재하기 때문에, 둘 다 0으로 인식하도록 해야 한다. 심각한 문제는 덧셈과 뺄셈을 할 때이다. 인간이 직접 계산할 때처럼 부호와 절대값을 따로 분리해서 계산해야 하고, 음수를 더함으로써 뺄셈을 구현할 수가 없어서 뺄셈기를 따로 구현해야 한다. 그러면 인간이 덧셈과 뺄셈을 수행할 때의 과정을 살펴보자.


    2(10) + 3(10) = 0 010 + 0 011 = 0 101 = 5(10)

    (양수끼리 더했으므로 양수) <덧셈기 사용>


    -2(10) + -3(10) = 1 010 + 1 011 = 1 101 = -5(10)

    (음수끼리 더했으므로 음수) <덧셈기 사용>


    3(10) - 2(10) = 0 011 - 1 010 = 0 001 = 1(10)

    (절대값이 큰 수에서 작은 수를 뺐으므로 양수) <뺄셈기 사용>


    2(10) - 3(10) = 0 010 - 1 011 = -(011 - 010) = 1 001 = -1(10)

    (절대값이 작은 수에서 큰 수를 뺄 경우에는 순서를 바꿔서 빼고 결과는 음수) <뺄셈기 사용>


    인간에게는 매우 쉬운 일이지만, 위의 모든 사항을 고려하여 계산을 수행하는 회로를 만드는 것은 쉬운 일이 아니다. 그리고 <, >, <=, >= 등의 비교연산을 수행할 때 다음과 같은 모순이 생긴다.


    3(10) > 2(10) = 0011 > 0010 = TRUE

    -2(10) > -3(10) = 1010 > 1011 = FALSE (???)


    위와 같이 음수의 경우는 반대가 되므로 이를 구분해야 한다. 사실 비교연산은 뺄셈을 한 후 결과의 부호를 가지고 판단하기 때문에 이는 덧셈과 뺄셈 문제와 동일하다.



    2. 1의 보수 (1's Complement)


    1의 보수 방식은 부호 절대 값 방식에서 단순히 음수의 순서를 뒤집은 것이다.


    0000 +0      1000 -7

    0001 1        1001 -6

    0010 2        1010 -5

    0011 3        1011 -4

    0100 4        1100 -3

    0101 5        1101 -2

    0110 6        1110 -1

    0111 7        1111 -0


    음수의 순서를 뒤집기만 한 것이라 별것 아닌 것 같지만 사실 엄청난 유리함이 있다. 우선 재미있는 성질이 하나 생긴다. 비트를 반전시키면 부호가 바뀌게 된다. 다행히 비트반전은 쉽게 구현할 수 있다. 그리고 MSB가 0이면 양수, 1이면 음수라는 성질은 그대로 유지된다.


    3(10) = 0011 >> 1100 = -3(10)

    -6(10) = 1001 >> 0110 = 6(10)


    뿐만 아니라 부호 절대 값 방식에서 골칫거리였던 것이 깔끔하게 해결된다. 부호와 절대 값을 따로 계산하지 않아도 되고, 음수를 더하는 방식으로 뺄셈을 할 수 있게 된다. 단, 캐리가 발생하면 LSB(최하위비트)에 1을 더해줘야 한다.


    2(10) + 3(10) = 0010 + 0011 = 0101 = 5(10) <덧셈기 사용>

    -2(10) + -3(10) = 1101 + 1100 = 1001 + 0001 = 1010 = -5(10) (캐리 발생) <덧셈기 사용>

    3(10) - 2(10) = 0011 + 1101 = 0000 + 0001 = 0001 = 1(10) (캐리 발생) <덧셈기 사용>

    2(10) - 3(10) = 0010 + 1100 = 1110 = -1(10) <덧셈기 사용>


    어째튼 덧셈과 뺄셈이 매우 간단해졌다. 음수의 비교연산 모순도 해결되었다.


    3(10) > 2(10) = 0011 > 0010 = TRUE

    -2(10) > -3(10) = 1101 > 1100 = TRUE


    그런데 여전히 0이 두 개인 것과 캐리를 처리해야 하는 문제가 남아있다. 즉, 0000과 1111을 둘 다 0으로 처리해야 하고, 계산과정에 캐리가 발생됐는지 감시해서 LSB에 1을 더해주는 회로를 구성해야 한다.


    3(10) - 3(10) = 0011 + 1100 = 1111 >> 0000


    게다가 위와 같이 실제 계산과정에서 발생하는 0은 항상 -0인 1111이다.


    3. 2의 보수 (2's Complement)


    2의 보수 방식도 단순해서 그저 눈에 거슬리는 -0을 없애기만 한 것이다.


    0000 0        1000 -8

    0001 1        1001 -7

    0010 2        1010 -6

    0011 3        1011 -5

    0100 4        1100 -4

    0101 5        1101 -3

    0110 6        1110 -2

    0111 7        1111 -1


    -0이 없어지고 대신 -8(10)이 등장한 것 외에는 별것 아닌 것 같지만, 1의 보수 방식의 골칫거리였던 -0 문제와 캐리를 처리해야 하는 문제가 사라진다. 2의 보수 방식에서는 부호를 바꾸려면 비트를 반전한 다음 LSB에 1을 더하면 된다.


    3(10) = 0011 >> 1100 + 0001 = 1101 = -3(10)

    -6(10) = 1010 >> 0101 + 0001 = 0110 = 6(10)


    -0는 아예 없으니 이미 해결됐고, 이제 캐리를 처리하지 않아도 되는지 직접 계산해보자.


    2(10) + 3(10) = 0010 + 0011 = 0101 = 5(10)

    -2(10) + -3(10) = 1110 + 1101 = 1011 = -5(10) (캐리 발생)

    3(10) - 2(10) = 0011 + 1110 = 0001 = 1(10) (캐리 발생)

    2(10) - 3(10) = 0010 + 1101 = 1111 = -1(10)


    위에서 캐리가 발생했을 때, LSB에 1을 더해주지 않아도 결과가 정확한 것을 확인할 수 있다. 이제 덧셈이든 뺄셈이든 그냥 더하기만 하면 된다. 이제 구현해야 하는 회로가 무척 간단해졌음을 알 수 있다.


    2의 보수 방식의 장점을 요약하면 다음과 같다.


    •MSB가 0이면 양수, 1이면 음수라는 성질이 유지된다.

    •음수를 더하는 방식으로 뺄셈을 할 수 있다.

    •음수의 비교연산에서 발생하는 모순이 해결된다.

    •0이 두개나 존재하는 모순이 해결된다.

    •덧셈과 뺄셈을 구현할 때 캐리를 처리하지 않아도 된다.


    ※ 16진수의 사용은 2진수가 너무 표현이 길어지므로 컴퓨터에 가까우면서 효율을 높이기 위해 사용한다.


    그렇다면 왜 이 보수가 필요한 것일까?

    컴퓨터에서 빼기 계산을 하는 것은 매우 어려운 회로가 필요하다. 반면, 더하기 루틴은 쉽다. 그래서 빼기를 더하기 처럼 사용하기위한 편법으로 보수를 사용하는 것이다.


    4비트로 예를 들어서 알아보자.

    먼저 1의 보수는 0은 1로 1은 0으로 변환하는 것이다. 따라서 숫자 7의 1의 보수는 7은 2진수로 0111(4비트인경우)이며 이것의 1의 보수는 1000 입니다.


    2의 보수는 1의 보수에 1을 더한 것으로 1000 + 1 = 1001 이 된다.

    1의 보수 1000과 2의 보수 1001 둘다 -7을 나타내기 위한 것이다. 그냥 10진수로 빼기를 한다면 4-2 = 2가 된다. 이것을 더하기 형식으로 바꿔보면 4 + (-2) = 2 인데 이진수로 표시하기 위해서 4와 -2를 표시해보면


    4 = 0100

    -2

        => 0010 (10진수 +2)

        => 1101 (1의 보수..)

        => 1110 (2의 보수 : 1의 보수+1)


    4+(-2)

       => 0100 + 1110

       => 10010

       => 0010 (4비트이기 때문에 위에 한 비트는 버림)

       => 2 (10진수로 변환)

    이런 식으로 빼기 연산도 더하기 연산으로 처리 할 수 있게 하는 것이다. 그럼 2의 보수를 많이 사용하는 이유가 무엇일까? 그것은 표시하는 수의 개수에 있다.


    0을 1의 보수와 2의 보수로 표현하면

    0000 ( 4비트의 0)

    1111 ( 1의 보수 0)

    10000 (2의 보수 : 1의 보수 + 1)

    0000 ( 2의 보수 : 4비트로 처리하기 위해 앞에 1비트를 버림)


    위에 예를 보면 0을 표현하는데 1의 보수는 0000, 1111 둘다 0이다다. 2의 보수에는 0000만 0이되고, 이렇게 된 표시할 수 있는 한 바이트(8비트)당 수의 크기는

    1의 보수인 경우 : -127 ~127 => 총 255개

    2의 보수인 경우 : -128~127 => 총 256개

    2의 보수를 취하므로 인해서 1개의 수를 더 표시할 수 있게 된다. 그러므로 당연히 2의 보수가 효율적이다. 


    [참고]

    1의 보수, 2의 보수

    (http://blog.naver.com/dreamincalm?Redirect=Log&logNo=130081559335)

    1의 보수와 2의 보수가 필요한 이유
    (http://blog.naver.com/PostView.nhn?blogId=dreamincalm&logNo=130081559815&categoryNo=0&parentCategoryNo=25&viewDate=&currentPage=1&postListTopCurrentPage=1&from=search)


    Posted by 동화다아아
    , |

    최근에 달린 댓글

    최근에 받은 트랙백

    글 보관함