1. 언어란 무엇인가
언어는 기호의 집합으로 구성된다. 그리고 언어가 제대로 작동할려면 의사소통하는 당사자들이 모두 같은 문맥(context)를 공유해야한다. Toto 라는 단어는 '오즈의 마법사'에 나오는 개를 뜻하기도 하지만 변기를 생산하는 일본 기업을 뜻할 수도 있다.
많은 프로그래밍 언어에서 context를 사용하는데, 이런 개념을 알고 이해하면 이해가 더 쉬운 것 같다. 예를 들어 자바 스프링에서는 context에 bean들을 저장하는데, 이것은 특정 객체 안에서 사용할 다른 객체의 정확한 뜻을 저장해놓는 것이라고 생각하면 도움이 될 것 같다. moneyTransferService라는 계좌이체 객체 속에서 accountRepository라는 저장소 객체가 userAccountRepository 인지, bankAccountRepository인지 정확한 뜻을 context에 기록해두는 것이다.
2. 비트와 논리연산
비트
비트(bit) : 2진법을 사용한다는 뜻의 바이너리(bianry)와 숫자를 뜻하는 디지트(digit)가 기묘하게 합쳐진 말이다. 바이너리는 두 가지 부분으로 이뤄진 어떤 대상을 뜻하고, 디지트 라는 말은 10진수를 표현하는 10가지 기호(0~9)를 뜻한다. 컴퓨터는 비트를 이용하여 모든 정보를 표현하고 해석한다. 즉 비트는 컴퓨터의 기본 연산 단위이다.
논리연산
"추운가?", "비가 오고 있는가?"와 같이 예/아니오로 표현할 수 있는 질문은 비트로 표현할 수 있다. "파티 장소는 어디인가?"라는 질문은 참/거짓으로 표현이 안되기 때문에 한 비트만으로는 표현할 수 없다. "춥거나 밖에 비가 오고 있다면 코트를 입어라" 라거나 "눈이 오고 있고 학교에 가는 날이 아니라면 스키를 탄다"가 참이라고 할 수 있다. 각 질문 사항을 하나의 비트로 본다면 다른 비트들이 표현하는 내용으로부터 새로운 비트를 만들어내는 동작을 논리 연산(logic operation)이라고 한다.
불리언 대수
대수가 수에 대한 연산 규칙의 집합인 것처럼, 불리언 대수도 비트에 대해 사용할 수 있는 연산 규칙의 집합이다. 기본 불리언 대수는 NOT, AND, OR 세가지 이며, XOR이라는 합성 연산이 있다. XOR은 두 비트의 값이 다른 경우에만 참이 된다(엑스오알 이라고 발음). a XOR b는 (a OR b) AND (NOT(a AND b))와 같다. 기본 불리언 연산을 조합하여 다른 연산을 만들 수 있음을 알 수 있다.
드모르간의 법칙
드모르간의 법칙은 a AND b라는 연산은 NOT(NOT a OR NOT b)와 같다는 것이다. 드모르간의 법칙이 없었다면 'NOT 춥다 AND NOT 비가 온다' 라는 논리를 'NOT NOT 춥다 OR NOT NOT 비가온다' 라는 양식을 사용해야했을 것이다. 자연어를 사용하긴 했지만, 이런 상황은 컴퓨터 프로그래밍을 하다보면 자주 발생할 수 있는 상황이다. 다시 말해서 부정에 부정을 하면 긍정이 된다는 논리로 요약할 수도 있다. 부정에 부정을 하는 것보다는 긍정으로 표현하는 것이 훨씬 간단하게 결과를 낼 수 있는 방법이다.
3. 비트와 수
이번에는 수를 비트로 표현해본다. 비트로 논리를 표현하는 것보다는 조금 더 복잡하다.
정수를 비트로 표현하는 방법
비트는 2진수를 기반으로 하기 때문에 우리가 보통 수를 표현할 때 사용하는 10진수를 표현하기 위해서는 2진수로 변환이 필요하다.
비트연산
2진수를 더하거나 빼는 것은 간단한 일이므로 생략해도 될 것 같다. 그러나 추가적으로 알아두어야할 개념들이 몇개가 있다.
MSB, LSB
2진수에서 가장 오른쪽의 비트를 가장 작은 유효 비트(LSB, Least Significant Bit)라고 부르고, 가장 왼쪽의 비트를 가장 큰 유효 비트(MSB, Most Significant Bit)라고 부른다. 10진수로 표현된 5028을 2진수로 변환하면 다음과 같은 결과가 나올 것이다.
비트가 총 13개 필요한데, 실제로는 미리 정해진 수의 비트를 한 덩어리로 만들어서 표현하기 때문에, 8비트씩 끊어서 아래와 같이 표시한다. 어떤 값을 표현하는데 필요한 비트에서 왼쪽에 추가된 0들을 leading zero라고 부른다.
비트와 덧셈
2진수 덧셈
덧셈은 앞서 배운 논리 연산자로 표현이 가능하다. 각 자리수의 합은 A XOR B로 표현이 가능하고 올림이 발생하면 A AND B로 표현이 가능하다. 1(001)과 5(101)을 합산하는 경우를 생각해보면 A XOR B는 100이다. 그리고 A AND B는 001인데, 이것은 올림을 표현하는 것이므로 맨 오른쪽 자리에서 1을 올려서 010으로 생각할 수 있다. A XOR B, A AND B의 결과를 더하면 110이며 이것이 001과 101을 더한 결과가 된다.
오버플로(overflow)와 언더플로(under flow)
9(1001)과 8(1000)을 더한 결과는 17(10001)이다. 그런데 표현단위가 4비트로만 존재한다면 맨 왼쪽 MSB는 표현할 방법이 없다. 따라서 결과가 1(0001)로 표시된다. 컴퓨터에서는 조건 코드 레지스터(또는 상태 코드 레지스터, condition code register)라는 것이 있어서 여러 정보를 담을 수 있는데 이런 오버플로가 발생한 경우를 대비하여 오버플로 비트가 있다. 만약 음수를 더하는 경우가 발생해서 MSB에서 1을 빌려오게 된다면, 이런 경우를 언더플로라고 부른다.
비트와 음수
비트로 음수를 표현하는 대표적인 방법은 3가지가 있다. 부호와 크기, 1의 보수, 2의 보수 방법이다.
부호와 크기(sign and magnitude)
4비트로는 0~15까지 16개의 수를 표현할 수 있다. 그런데 음수를 표현하기 위해서 MSB를 부호로 활용하면 음수를 표현할 수 있다. +1은 0001 이니까, -1은 1001로 표현하는 식이다.
다만 이 경우 +0(0000)을 -0(1000)으로 대칭으로 표기해야하므로 1자리수가 낭비된다. 또한 +1(0001)과 -1(1001)을 그대로 더하면 1010이 되는데 이것은 기대하는 결과인 0이 아니라 -2를 표시하게 된다.
1의 보수(one's complement)
양수의 모든 비트를 뒤집는 방식이다. +1(0001) 대비 -1(1110)으로 표현한다. 그러나 이 방식도 +0(0000), -0(1111)로 숫자가 낭비된다. 그리고 오버플로가 발생한 경우 순환 올림(end-around carry)라는 방식이 필요하다. +2(0010)과 -1(1110)을 더하면 10000이 되는데 4비트이므로 순환 올림을 적용하여 MSB를 LSB로 전달해서 +1(0001)로 덧셈의 결과를 산출해내는 방식이다. 순환 올림은 논리적으로는 크게 어렵지 않으나 이런 처리를 위해서는 하드웨어가 추가적으로 필요하기 때문에 좋지 않은 방식이다.
2의 보수(two's complement) ★
하드웨어 추가없이 XOR과 AND 연산만을 활용하기 위해서 어떤 수에 더했을 때 결과가 0이 나오는 수를 보수로 취하는 방식이다. +1(0001)에 어떤 수를 더해서 0000이 나오도록 할려면, -1을 1111로 정의하면 된다. 이런 수는 기존 수의 각 자릿수를 NOT을 이용하여 뒤집고, 1을 추가하는 방법으로 구할 수 있다. 즉 +1(0001)의 전체 NOT은 1110이고, 여기서 1을 더해 1111이 -1(1111)이 되는 방식이다.
이럴 경우 +0(0000)의 보수는 0000이 되어 -0을 따로 사용할 필요가 없어서 비트의 낭비가 없어지게 된다. 그리고 -2(1110)과 -3(1101)을 덧셈하는 경우 오버플로를 무시한 결과는 -5(1011)이 되는데 이것은 5(0101)에 2의 보수의 규칙을 적용한 것과 같음을 알 수 있다. 그래서 보통 2의 보수 방식으로 음수를 표현한다.
참조
1. [책] 한 권으로 읽는 컴퓨터 구조와 프로그래밍
'Computer Science > Introduction' 카테고리의 다른 글
4. 비트처리 하드웨어 : 릴레이, 진공관, 트랜지스터, 논리게이트 (0) | 2022.04.10 |
---|---|
3. 디지털 게인과 증폭 회로: gain, distortion, threshold, cutoff, saturation (0) | 2022.04.10 |
2. 컴퓨터 내부의 언어 체계 - 비트와 실수, 텍스트 표현 (0) | 2022.02.02 |
2. 컴퓨터의 정보 표현 (0) | 2020.06.30 |
1. Hardware (0) | 2020.06.28 |