1장 : 컴퓨터 내부의 언어 체계
컴퓨터는 어떤 말을 사용할까?
Last updated
컴퓨터는 어떤 말을 사용할까?
Last updated
1장에서는 컴퓨터의 언어를 배우기 시작한다.
언어는 정보를 서로 소통하기 위해 만들어졌는데 프로그래머가 해야 할 일은 컴퓨터에게 명령을 내리는 것이다.
그런데 컴퓨터는 사람의 말을 알아듣지 못한다.
따라서 사람이 컴퓨터의 말을 배워야 한다. 자연어와 컴퓨터 언어는 쓰인 기호나 제대로 된 기호 나열 방법, 사용법 등의 요소를 상당 부분 공유한다. 자연어가비문자 언어라는 것과 달리 컴퓨터 언어는 항상 문자 언어만 사용한다.
언어는 편의를 제공하기 위한 지름길이다.
모든 언어의 뜻은 기호의 집합으로 인코딩된다. 하지만 의미를 기호로 인코딩하는 것만으로는 충분하지 않다.
언어가 제대로 작동하려면 의사소통하는 당사자들이 모두 같은 문맥을 공유해서 같은 기호에 같은 뜻을 부여할 수 있어야 한다.
동일한 기호를 구분할 수 있는 요소는 문맥뿐인데, 언제나 문맥을 명확히 식별할 수 있는 것은 아니다. 컴퓨터 언어에도 마찬가지 문제가 있다.
문자 언어는 기호를 나열한 것이다. 기호를 정해진 순서대로 단어를만들 수 있다.
기호나 조합은 무궁무진한 가능성이 있다. 언어마다 기호와 기호 유형이 달라질 수 있고, 언어마다 순서도 다를 수 있다.
기호의 순서도 중요하다. ‘dog’와 ‘god’는 같지 않다.
기호가 들어갈 상자
상자에 들어갈 기호
상자의 순서
일부 언어에는 주변의 상자 안에 들어 있는 기호의 종류에 따라 상자에 들어갈 수 있는 기호를 제한하는 복잡한 규칙이 존재하기도 한다.
예를 들어, 어떤 기호들은 서로 인접한 상자에 들어 갈 수 없다.
먼저 상자에 대해 생각해보자.
자연어에서는 이 상자를 문자라고 부르고, 컴퓨터에서는 비트라고 부른다.
비트 = 바이너리(binary) + 디지트(digit)
바이너리 : 2진법 사용한다는 뜻으로, 두 가지 부분으로 이뤄진 어떤 대상을 뜻한다.
디지트 : 숫자를 뜻하며, 일상생활에서 쓰는 10진수를 표현 하는 10가지 기호(0~9)를 뜻한다.
기묘한 바이너리와 디지트의 결합인 비트로, 비트는 적은 비용으로 편리하게 기호를 담을 수 있음
비트는 2진법을 사용한다.
비트 상자에는 모스 부호의 점(.)과 선(-)처럼 두 가지 기호 중 하나만 담을 수 있다는 뜻
모스 부호는 두 기호를 여러 가지 방식으로 조합해 이어붙여서 복잡한 정보를 표현한다.
예를 들어 A는 점-선이고, B는 선-점-점-점, C는 선-점-선-점이다. 자연어와 마찬가지로 기호의 순서가 중요하다.
선-점은 A가 아니라 N이다.
기호라는 개념은 추상적이다. 실제로는 기호가 무엇이든 관계없다.
하지만 가장 중요한 것은 언어는 문맥 없이는 제대로 작동할 수 없다.
기호 자체는 무엇이든 될 수 있으며, 특정한 형태를 가질 필요가 없다.
예를 들어, 꺼짐/켜짐, 낮/밤, 쌀/보리 등 다양한 방식으로 표현될 수 있다.
언어는 문맥이 있어야 제대로 작동한다.
같은 기호라도 말하는 사람과 듣는 사람이 다르게 해석하면 혼란이 발생할 수 있음.
예: "U(점-점-선)"을 말하는 사람이 의도했지만, 상대가 "쌀-쌀-보리"로 해석하면 의미가 어긋남.
컴퓨터에서 계산을 수행하는 방식을 컴퓨팅이라 부름.
비트 자체는 의미가 없으며, 필요에 따라 의미를 부여하는 방식(척하기)이 중요.
예를 들어, "이 비트들은 파란색을 뜻한다고 가정하자"처럼 의미를 임의로 정할 수 있음.
표준적인 비트 사용법을 배우는 것도 중요하지만, 필요에 따라 자신만의 방식으로 비트를 활용하는 것을 두려워할 필요 없음.
프로그래밍은 본질적으로 비트에 특정 의미를 부여하는 과정이다.
컴퓨터에서 사용되는 기호와 비트는 본질적으로 문맥에 따라 의미가 달라지며, 필요에 따라 유연하게 해석될 수 있다. 프로그래밍은 이런 유연성을 바탕으로 다양한 표현을 가능하게 한다.
비트 사용법 중 하나는 “날씨가 추운가?”, “내 모자를 좋아하나?”와 같은 예/아니요 질문에 대 한 답을 표현하는 것이다.
이때 ‘예’를 참true이라는 용어로 부르고, ‘아니요’를 거짓false이라고 부른다.
다른 비트들이 표현하는 내용으로부터 새로운 비트를 만들어내는 이런 동작을 논리 연산logic operation이라고 한다.
불리언 대수Boolean algebra도 비트에 대해 사용할 수 있는 연산 규칙의 집합
일반 대수와 마찬가지로 결합 법칙, 교환 법칙, 분배 법칙을 불리언 대수에 적용할 수 있다.
입력 input
은 박스의 밖에 있고, 출력output
은 박스 안에 있다.
NOT: ‘논리적 반대’를 의미한다. 예를 들어, 거짓인 비트에 NOT을 하면 참이 되고 참인 비트에 NOT을 하면 거짓이 된다.
AND: 둘 이상의 비트에 작용한다. 2비트 연산인 경우 첫 번째 비트가 참이고 두 번째 비트도 참인 경우에만 결과가 참이 된다. 2비트보다 더 많은 비트에 연산을 적용하는 경우 모든 비트가 참이면 AND 연산의 결과도 참이다.
OR: 둘 이상의 비트에 작용한다. 2비트 연산인 경우 첫 번째 비트가 참이거나 두 번째 비트가 참이면 결과가 참이 된다. 2비트보다 더 많은 비트에 연산을 적용하는 경우 어느 한 비트라도 참이면 OR 연산의 결과도 참이다.
XOR: 이 배타적(exclusive OR)의 결과는 첫 번째 비트와 두 번째 비트가 다른 값인 경우에만 참이 된다. 즉, 두 값 중 어느 하나가 참이면 XOR도 참이지만 두 값이 모두 참이면 XOR의 결과는 거짓이다.
다른 연산을 사용해 XOR 연산을 만들 수 있다. 예를 들어, 두 비트에 대한 XOR 연산(a XOR b)은 (a OR b) AND (NOT(a AND b))와 같다. 이를 통해 기본 불리언 연산을 다양한 방식으로 조합해 똑같은 결과를 얻을 수 있다는 사실을 알 수 있다.
오거스터스 드모르간은 불리언 대수에 적용할 수 있는 법칙을 추가로 알아냈다. 발명자의 이름을 따서 드모르간의 법칙
이라고 한다.
a AND b = NOT(NOT a OR NOT b)
NOT
을 충분히 사용하면 AND 연산을 OR 연산
으로 대신할 수 있다(그리고 역으로 OR을 AND로 대신할 수 있다)는 뜻이다.
컴퓨터에서 입력을 항상 원하는 형태로 얻을 수만은 없기 때문에 이런 성질이 유용할 때가 있다. 자연어에서 이중 부정이 이와 비슷한 일을 한다.
지금까지 살펴본 긍정적인 논리positive logic에 더해 부정적인 논리negative logic를 기술하는 명제를 사용할 때
드모르간의 법칙
을 활용할 수 있다.
부정논리도 작동하나. 연산을 최소로 사용하면 비용을 최소화할 수 있다. 여기서는 NOT 연산을 수행하는 하드웨어에 실제로 돈이 들기도 하고, 다음 장에서 보겠지만 연산을 연쇄적으로 사용하면 계산이 느려진다.
드모르간의 법칙을 알면 두 번째 표가 표현하는 논리가 ‘춥다 OR 비가 온다’와 동등함을 알 수 있고, 훨씬 간단하게 결과를 계산할 수 있다.
비트를 사용해 수를 표현하는 방법을 알아보자. 수는 논리보다 더 복잡하지만 단어보다는 훨씬 단순하다.
우리는 손가락과 발가락이 10개이기 때문에 10진수를 사용함.
10가지 숫자(0~9)를 사용하며, 숫자는 오른쪽에서 왼쪽으로 자리값이 증가함.
각 자리값은 10의 거듭제곱(1, 10, 100, 1000 등)으로 표현됨.
예: 5,028 = 5×10³ + 0×10² + 2×10¹ + 8×10⁰
각 상자에 사용할 수 있는 기호는 1과 0 두 가지밖에 없다. 하지만 기호가 2개뿐이라고 문제가 되지는 않는다. 10진수에서 수를 표현할 수 없을 때는 더 큰 수를 표현하기 위해 상자 를 추가할 수 있었다
2진수는 0과 1만 사용하며, 자리값은 2의 거듭제곱(1, 2, 4, 8, 16, ...)을 기반으로 함.
10진수에서 자릿수를 늘려서 더 큰 수를 표현하는 것처럼, 2진수에서도 비트(자리)를 추가하면 더 큰 수를 표현할 수 있음.
1보다 큰 수를 표현하려면 새로 상자를 추가해야 함
예: 5,028을 2진수로 변환
5,028 = 1×2¹² + 0×2¹¹ + 0×2¹⁰ + 1×2⁹ + 1×2⁸ + 1×2⁷ + 0×2⁶ + 1×2⁵ + 0×2⁴ + 0×2³ + 1×2² + 0×2¹ + 0×2⁰
결과: 1001110100100₂
비트 개수가 많을수록 표현할 수 있는 값의 범위가 커짐. 표현할 수 있는 수의 범위가 커진다.
예:
4비트 → 0~15 (16개)
8비트 → 0~255 (256개)
16비트 → 0~65,535 (65,536개)
32비트 → 0~4,294,967,295 (약 43억 개)
64비트 → 0~18,446,744,073,709,551,615 (약 18경 개)
LSB (Least Significant Bit): 2진수에서 가장 오른쪽 비트 (값 변화가 가장 작음).
MSB (Most Significant Bit): 2진수에서 가장 왼쪽 비트 (값 변화가 가장 큼).
예: 5,028(1001110100100₂)에서 MSB는 맨 왼쪽 1, LSB는 맨 오른쪽 0
2진수에서 더 많은 비트를 사용할 경우, 앞쪽에 0을 추가해도 값은 변하지 않음.
10진수와 마찬가지로 가장 왼쪽에 있는 상자보다 더 왼쪽에 영(0)을 추가하면(이 런 식으로 추가된 영들을 리딩 제로leading zero라고 말한다)
어떤 값을 표현하는 데 필요한 최소한의 상자 개수보다 더 많은 상자를 추가할 수 있다.
예: 5,028을 16비트로 표현하면 0001001110100100
10진수에서도 5,028과 05,028은 같은 값
컴퓨터가 미리 정해진 수의 비트를 한 덩어리로 사용하도록 만들어졌기 때문에, 2진수를 쓸 때는 이런 식으로 항상 일정한 개수의 비트를 사용해 값을 표현하는 경우가 종종 있다.
10진 덧셈에서 오른쪽에서 왼쪽으로 각 자리의 숫자를 서로 더한 것처럼 마찬가지로, 2진수에서도 각 비트를 LSB에서 MSB 쪽으로 더하며 결과가 1보다 크면 1을 다음 자리(왼쪽)로 올린다.
이 글은 2진수 덧셈의 원리, 논리 연산을 활용한 계산 방식, 오버플로와 언더플로 개념을 설명한다.
10진수 덧셈: 오른쪽(Lowest Significant Bit, LSB)부터 더하며, 9를 초과하면 1을 올림.
2진수 덧셈: 1+1은 2이지만, 2진수에서는 2가 없으므로 10(1 올림, 0 유지)로 변환.
예) 1(001₂) + 5(101₂) = 6(110₂)
LSB(맨 오른쪽): 1+1 = 10 → 0을 남기고 1을 올림.
중간 자리: 0+0에 올림(1) 추가 → 1.
MSB(맨 왼쪽): 0+1 = 1.
최종 결과: 110₂ (10진수 6과 동일함).
XOR(배타적 논리합, Exclusive OR): 각 비트를 더한 결과를 결정.
0+0 = 0, 1+0 = 1, 0+1 = 1, 1+1 = 0 (올림 발생).
AND(논리곱, AND): 올림을 결정.
0 AND 0 = 0, 1 AND 0 = 0, 0 AND 1 = 0, 1 AND 1 = 1 (올림 발생).
예)
1 + 1 → AND(1), XOR(0) → 올림
1 + 0 → AND(0), XOR(1) → 올림 없음
3비트 이상 덧셈에서는 2비트 덧셈을 두 번 수행하면 됨.
오버플로: 덧셈 결과가 사용 가능한 비트 범위를 초과하는 경우.
예) 4비트로 9(1001₂) + 8(1000₂) = 17(10001₂) → MSB를 초과한 1이 손실됨(결과: 0001₂, 즉 1).
컴퓨터는 오버플로 비트를 사용하여 이런 문제를 감지.
언더플로: 뺄셈 시 MSB 위쪽에서 1을 빌려와야 하는 경우.
컴퓨터에는 조건 코드(상태 코드) 레지스터가 있어 몇 가지 이상한 정보를 담아둔다.
이런 정보 중에는 오버플로 비트overflow bit가 있고, 이 비트에는 MSB에서 발생 한 올림값이 들어간다.
이 비트값을 보면 오버플로가 발생했는지 알 수 있다
이에 해당하는 조건 코드도 컴퓨터에 들어 있다.
뺄셈은 사실상 덧셈으로 변환 가능 (예: 7 - 5 = 7 + (-5)).
음수를 표현하는 방법(2의 보수 등)을 설명할 예정.
2진수 덧셈은 XOR로 결과, AND로 올림을 계산하면 된다.
오버플로와 언더플로는 비트 범위를 벗어날 때 발생하며, 컴퓨터는 이를 감지하는 조건 코드를 사용한다.
음수 표현과 뺄셈은 덧셈으로 변환 가능하다.
오버플로우와 언더플로우 방지 방법
입력 유효성 검사: 사용자 입력을 받을 때 입력 값의 범위를 검사하여 유효한 값만 처리하도록 한다.
데이터 타입 변경: 더 큰 정수 데이터 타입을 사용하거나, 부호 없는 데이터 타입을 사용하여 정수 오버플로우를 줄일 수 있다
실제 세계에서 문제를 해결하려면 양수와 음 수를 모두 사용해야 하는 경우가 많다
1. 음수를 표현하는 필요성
앞 절까지는 양수만 다루었지만, 실제로는 양수와 음수를 모두 표현해야 하는 경우가 많다. 4비트로 표현할 수 있는 값이 16가지(0~15)이지만, 이를 음수를 포함하는 표현법으로 바꿀 수 있음. 비트의 해석 방식(문맥)을 다르게 하면 같은 비트 패턴도 다른 의미를 가질 수 있음.
기억하자. 언어는 문맥과 의미를 통해 작용하기 때문에 이 말은 비트들을 해석하는 새로운 문맥을 만들 수 있다는 뜻이다.
음수와 양수를 비교하기 위해 부호를 쓰는데 부호는 +, -로 2가지 값이 있으므로 이를 비트 하나로 표현할 수 있다.
가장 왼쪽 비트(MSB, Most Significant Bit)를 부호 비트로 사용하고, 나머지 비트는 숫자의 크기(절댓값)를 나타냄.
따라서 4비트 중에 3비트가 남고, 이를 사용하면 0부터 7까지 수를 표현할 수 있다.
MSB = 0 → 양수, MSB = 1 → 음수. (부호비트)
즉, 0부터의 거리(절댓값)을 표현하기 위해 사용하는 이런 방법을 부호와 크기 표현법이라고 말한다.
예:
0111₂
→ +7
1111₂
→ -7
0000₂
→ +0
1000₂
→ -0
(0이 두 개 존재하는 문제 발생!)
문제점
① 0이 두 가지로 표현됨
0000₂
= +0
, 1000₂
= -0
같은 숫자를 표현하는 방법이 두 개 존재하여 비효율적임.
비트를 구성하려면 돈이 듦, 낭비
② 연산이 제대로 동작하지 않음
예를 들어, +1(0001₂) + (-1)(1001₂)
을 연산하면
XOR과 AND 연산을 수행하면 결과가 1010₂(-2)
가 됨.
+1과 -1을 더하면 0이 나와야 하는데, -2가 나옴 → 연산 오류 발생.
③ 추가적인 연산 로직이 필요
덧셈, 뺄셈을 정상적으로 수행하려면 별도의 복잡한 논리 연산을 추가해야 함.
이러한 복잡성을 줄이기 위해 더 나은 방법이 필요함.
부호와 크기 표현법은 0이 중복되고 연산이 자연스럽게 수행되지 않기 때문에 현대 컴퓨터에서는 사용되지 않는다.
양수의 모든 비트를 뒤집으면(반전, NOT 연산) 음수가 된다.
예:
+7(0111₂) → -7(1000₂)
+3(0011₂) → -3(1100₂)
문제점
0이 두 가지(+0, -0)로 표현됨 → 0000₂ (+0)
과 1111₂ (-0)
, 부호와 크기 표현법과 같은 문제.
덧셈 시 순환 올림(End-Around Carry) 처리가 필요 → 복잡한 하드웨어 요구. → 비용이 더 든다.
순한올림이란 MSB 쪽에서 올림이 발생한 경우에 는 LSB로 올림을 전달해야 하는 것
1의 보수도 0이 중복되고 연산 처리가 복잡하여 현대 시스템에서 사용되지 않음.
1의 보수에 1을 더하면 2의 보수가 됨. 가장 널리 사용되는 음수 표현 방식이다.
특별한 하드웨어를 추가할 수 없고 XOR과 AND 연산만 사용해야 한다면 어떻게 일반 정수 사이의 덧셈을 할 수 있을까?
+1에 더했을 때 0이 나오는 비트 패턴을 찾고 이 패턴을 -1이라고 불러보자.
4비트 수의 경우 +1은 0001이다.
1111을 0001에 더하면 0000이 된다.
앞으로는 1111을 (4비트에서) -1을 표현하는 비트 패턴으로 사용하자.
2의 보수 변환 방법
부호가 있는 정수를 표현할 때 가장 널리 쓰이는 방법이다.
비트를 반전(즉 각 비트의 NOT을 취하고)
1을 더함 → 이때 MSB에서 올림이 발생하면 이 값은 버린다.
예제: 4비트 2의 보수 표현
2의 보수(4비트)
10진수 값
0111₂
+7
0110₂
+6
0101₂
+5
0100₂
+4
0011₂
+3
0010₂
+2
0001₂
+1
0000₂
+0
1111₂
-1
1110₂
-2
1101₂
-3
1100₂
-4
1011₂
-5
1010₂
-6
1001₂
-7
1000₂
-8
+1(0001₂) → -1(1111₂)
(비트 반전 1110₂
+ 1
)
+2(0010₂) → -2(1110₂)
(비트 반전 1101₂
+ 1
)
+7(0111₂) → -7(1001₂)
0이 중복되지 않음 → 0000₂ (+0)
만 존재함.
왜 2의 보수에서는 0이 하나만 존재하는가?
부호와 크기 표현법(Sign and Magnitude)과 1의 보수(One’s Complement) 방식에서는 +0과 -0이 중복해서 존재하는 문제가 있었다.
하지만 2의 보수에서는 0이 하나만 존재한다.
확인 과정:
0000₂
(0)의 모든 비트를 반전하면 → 1111₂
(1의 보수)
여기에 1을 더하면 → 0000₂
(초기 값과 동일)
따라서 0이 하나만 존재하게 됨.
덧셈 연산이 자연스럽게 동작 → +1(0001₂) + (-1)(1111₂) = 0000₂ (0)
하드웨어 구현이 간단 → 별도의 연산 처리 없이 정수 덧셈과 동일한 방식으로 수행 가능.
N비트의 2의 보수 표현법에서는 다음과 같은 범위를 표현할 수 있다.
int, Long 등 데이터 타입의 비트 수에 따라 표현할 수 있는 값의 범위가 달라짐 그렇기 때문에 프로그래머들은 거의 본능처럼 이런 계산을 수행한다.
비트 개수
값의 개수
표현 가능한 값의 범위
4비트
16개
-8 ~ 7
8비트
256개
-128 ~ 127
16비트
65,536개
-32,768 ~ 32,767
32비트
4,294,967,296개
-2,147,483,648 ~ 2,147,483,647
64비트
18,446,744,073,709,551,616개
-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
2의 보수 표현법에서는 가장 큰 양수는 011...111 (N-1개의 1)이고, 가장 작은 음수는 100...000 (N비트에서 MSB만 1, 나머지는 0).
비트 개수가 커지면 표현할 수 있는 값의 범위가 지수적으로 증가한다.
2의 보수에서는 N비트일 때 표현할 수 있는 정수의 범위는
−(2N−1) (2N−1−1)- (2^{N-1}) \text{ ~ } (2^{N-1} - 1)
7. 음수 변환(2의 보수) 손으로 계산하는 방법
예제: -13
을 8비트 2의 보수로 변환
13
을 2진수로 변환 → 0000 1101₂
비트 반전(NOT 연산) → 1111 0010₂
1을 더함 → 1111 0011₂
(2의 보수)
-13
의 2의 보수 표현 = 1111 0011₂
같은 4비트 숫자라도 표현법에 따라 해석이 달라질 수 있다. 문맥에 따라 표현하는 값이 달라질 수 있다는 점을 꼭 염두에 둬야 한다.
예제: 1111₂
부호와 크기(Sign and Magnitude) → -7
1의 보수(One’s Complement) → -0
2의 보수(Two’s Complement) → -1
즉, 같은 2진수라도 어떤 표현법을 사용하느냐에 따라 해석이 달라지므로, 사용 중인 표현법을 정확히 알아야 한다.
2의 보수로 변환하는 방법을 익히면 손으로 직접 음수를 표현할 수 있다.
양수를 2의 보수로 변환 (예: -6)
6을 2진수로 변환 → 0110₂
비트를 반전 (NOT 연산) → 1001₂
1을 더함 → 1010₂
(즉, -6의 2의 보수 표현)
따라서 -6
의 4비트 2의 보수 표현은 1010₂
가 된다.
2의 보수를 이용한 뺄셈 (예: 5 - 3)
5의 2진수 표현: 0101₂
3의 2진수 표현: 0011₂
-3
을 구하려면 비트 반전 후 1을 더함
0011₂
→ 1100₂
(반전)
1101₂
(1을 더함 → -3
)
이제 5 + (-3)
을 계산
0101₂
+ 1101₂
결과: 10010₂
→ 5비트지만, 4비트만 보면 0010₂
즉, 2(10진수)로 정상적으로 계산됨!
1. 현대 컴퓨터가 2의 보수를 사용하는 이유
덧셈 연산을 동일한 방식으로 처리 가능 → 별도의 하드웨어 필요 없음.
0이 하나만 존재 → 저장 공간 낭비 없음.
CPU에서 음수 연산이 효율적으로 가능 → 1의 보수, 부호와 크기 방식보다 처리 속도가 빠름.
2. 프로그래밍 언어에서의 2의 보수
대부분의 프로그래밍 언어(C, Java, Python)는 2의 보수를 사용해 음수를 표현.
예제:
메모리에서 -5
는 2의 보수 형태(예: 1111 1011₂)로 저장됨.
2의 보수 표현법은 현대 컴퓨터에서 가장 널리 사용되는 음수 표현 방식이다.
0이 하나만 존재하기 때문에 불필요한 중복이 없음.
비트 수에 따라 표현할 수 있는 정수의 범위가 달라지며, 비트 수가 증가할수록 범위가 지수적으로 증가함.
같은 2진수라도 어떤 표현법을 사용하는지에 따라 해석이 달라질 수 있으므로 항상 사용 중인 표현법을 알아야 함.
2의 보수를 사용하면 덧셈과 뺄셈이 자연스럽게 이루어지며, 연산이 효율적이고 하드웨어 구현이 용이함.
컴퓨터에서 덧셈을 수행할 때 XOR(배타적 논리합, Exclusive OR)과 AND(논리곱) 연산을 활용하는 이유는 하드웨어 구현이 간단하고 효율적이기 때문이다.
만약 XOR 대신 다른 논리 연산을 사용하려 하면, 별도의 추가 연산 장치가 필요할 수도 있다.
2진수 덧셈을 살펴보면, 각 비트의 덧셈 결과는 다음과 같다.
0
0
0
0
0
1
1
0
1
0
1
0
1
1
0
1
여기서
합(Sum) = A XOR B
올림(Carry) = A AND B
이렇게 하면 덧셈을 수행하는 회로(반가산기, Half Adder)를 XOR과 AND만으로 만들 수 있다.
덧셈 결과를 결정하는 기본적인 규칙을 따르려면 다음과 같은 계산이 필요하다.
0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 0
(올림 발생)
XOR이 아니라 다른 논리 연산(예: OR, AND, NAND, NOR 등)을 사용하면 문제 발생 예를 들어, OR을 사용하면:
1 OR 1 = 1
이므로, 1 + 1의 결과가 1이 되어 잘못된 값이 나옴.
이 때문에 XOR을 사용하지 않으면 정확한 덧셈을 수행하기 위해 더 복잡한 논리 회로가 필요하게 된다.
만약 XOR을 사용하지 않고 덧셈을 수행하려면,
덧셈을 위한 맞춤형 논리 회로를 추가해야 함.
덧셈을 제대로 수행하려면 다른 조합의 논리 연산을 거쳐야 하므로, 연산 속도가 느려질 수 있음.
XOR 없이 덧셈을 하려면, 더 많은 게이트(AND, OR, NAND 등)를 사용하여 원하는 결과를 만들도록 설계해야 함.
이런 이유로 XOR이 없는 덧셈 회로를 만들면 하드웨어 복잡성이 증가하고, 기본적인 덧셈을 수행하는데 더 많은 비용과 전력 소비가 필요할 수 있다.
컴퓨터의 산술 논리 연산 장치(ALU, Arithmetic Logic Unit)
는 XOR과 AND를 조합하여 덧셈 연산을 수행한다.
반가산기(Half Adder)
입력: A, B
Sum(합) = A XOR B
Carry(올림) = A AND B
전가산기(Full Adder)
입력: A, B, 이전 자리에서 넘어온 Carry
Sum(합) = (A XOR B) XOR Carry_in
Carry_out(새로운 올림) = (A AND B) OR (Carry_in AND (A XOR B))
XOR 없이 덧셈을 구현하려면 더 복잡한 논리 연산과 조합 회로가 필요해진다.
XOR을 사용하면 덧셈 연산을 가장 간단한 논리 회로로 구현할 수 있다.
만약 XOR을 사용하지 않으면, 별도의 복잡한 논리 회로와 추가적인 하드웨어가 필요해지며, 덧셈 연산 속도도 느려질 수 있다.
이 때문에 모든 CPU와 연산 회로에서는 XOR을 기반으로 덧셈을 수행하고 있다.
지금까지는 정수를 2진수로 표현하는 방법을 살펴봤다. 그렇다면 실수는 어떻게 표현할 수 있을 까?
밑이 10인 실수에는 10진 소수점decimal point이 포함된다. 따라서 밑이 2인 경우, 실수를 표기하기 위해 2진 소수점을 표현할 방법
이 필요하다.
여기서도 정수의 경우와 마찬가지로 문맥에 따라 실수를 표현하는 방법이 달라질 수 있다.
2진수를 사용해 소수를 표현하기 위해 2진 소수점의 위치를 임의로 정하는 방법이 있다. 소수점의 위치가 항상 일정하기 때문에 이런 방식을 고정소수점 fixed-point 표현법
이라고 부른다
예를 들어, 4비트를 사용한다고 하면:
2비트는 정수 부분
2비트는 소수 부분
이렇게 정해진 비트 수를 사용해 고정된 위치에서 정수와 소수를 나눠 표현한다.
정수 표현 방식과 유사함 → 일반적인 2진수 표현에서 소수점을 미리 지정한 위치에 둔다.
소수 부분은 2의 거듭제곱
으로 표현됨 → 10진 소수(1/10, 1/100 등)와 달리, 2진 소수는 1/2, 1/4, 1/8, 1/16 등으로 표현된다.
연산이 간단함 → 정해진 자리 수를 기준으로 덧셈, 뺄셈 연산을 수행할 수 있다.
고정된 범위 내에서만 표현 가능 → 표현할 수 있는 값의 범위가 제한적
표현 가능한 수의 범위가 제한됨
비트 수가 고정되어 있어, 매우 큰 수나 매우 작은 수를 정확하게 표현하기 어렵다
예를 들어, 4비트 고정소수점에서는 0~3¾
사이의 값만 표현 가능하므로, 4
이상의 값이나 1/8
같은 더 작은 수는 표현할 수 없음.
메모리 사용 비효율
더 정밀한 실수를 표현하려면 더 많은 비트가 필요하지만, 비트가 제한되어 있기 때문에 메모리 낭비가 발생할 수 있음.
예를 들어, 32비트를 사용하여 실수를 표현한다고 할 때, 16비트 정수 + 16비트 소수
로 나눈다면, 작은 값도 32비트를 차지하게 됨.
다양한 크기의 수 표현 어려움
플랑크 상수(6.63×10⁻³⁴)처럼 매우 작은 수와, 아보가드로 수(6.02×10²³)처럼 매우 큰 수를 함께 표현하기 어려움.
이를 해결하려면 몇백 비트가 필요하므로 비효율적임.
쓸모 있는 범위의 실숫값을 표현하기 위해 필요한 비트 개수가 너무 많기 때문에 범용 컴퓨터에서 이런 방식을 사용하는 경우는 드물다.
범용 컴퓨터는 일반적인 문제를 해결하기 위해 만들어진 컴퓨터라서 그런식으로 불린다.
고정소수점 표현법은 범용 컴퓨터에서는 잘 사용되지 않지만, 특정한 목적을 가진 컴퓨터(DSP, Digital Signal Processor)에서 사용되기도 한다.
디지털 신호 처리(DSP): 오디오, 영상 처리 등의 작업에서 일정한 정밀도를 유지하면서 연산 속도를 빠르게 하기 위해 사용됨.
임베디드 시스템(Embedded Systems): 메모리와 연산 자원이 제한된 환경에서는 고정소수점이 부동소수점보다 더 효율적임.
고정소수점 방식의 한계를 극복하기 위해 부동소수점(Floating-Point) 표현 방식이 등장했다.
부동소수점 방식은 소수점의 위치를 고정하지 않고 이동할 수 있도록 하는 방식이다.
예를 들어, 1.23 × 10³
과 같은 형태로 수를 표현하면, 큰 수나 작은 수도 효율적으로 표현할 수 있음.
IEEE 754 표준을 따라 32비트(단정도) 및 64비트(배정도) 부동소수점 방식이 범용 컴퓨터에서 사용됨.
고정소수점과 부동소수점 개념을 잘 이해하려면 10진 소수를 2진 소수로 변환하는 방법을 알아두는 것이 유용하다.
예를 들어, 0.625(10진수)
를 2진수로 변환하는 과정은 다음과 같다.
0.625 × 2 = 1.25
→ 정수 부분 1
, 소수 부분 0.25
0.25 × 2 = 0.50
→ 정수 부분 0
, 소수 부분 0.50
0.50 × 2 = 1.00
→ 정수 부분 1
, 소수 부분 0.00
결과적으로, 0.625(10진수) = 0.101(2진수)
하지만 10진수로 깔끔하게 표현되는 소수라도 2진수에서는 무한 반복되는 경우가 있음.
예를 들어, 0.1(10진수)
를 2진수로 변환하면 0.0001100110011...(반복)
형태로 끝없이 이어진다.
이런 반복 소수는 부동소수점 연산에서 오차를 발생시키는 원인 중 하나다.
부동소수점(Floating-Point) 표현법은 소수점 위치를 고정하지 않고 이동할 수 있도록 설계된 수 표현 방식이다.
이는 과학적 표기법(Scientific Notation)을 2진수에 적용한 것으로, 큰 수와 작은 수를 효과적으로 표현할 수 있다. 과학적 표기법에서는 숫자를 가수(Mantissa)와 지수(Exponent)로 나눈다.
예를 들어:
0.0012
를 과학적 표기법으로 표현하면 → 1.2 × 10⁻³
120000
을 과학적 표기법으로 표현하면 → 1.2 × 10⁵
2진법에서도 마찬가지로, 밑을 2
로 하여 표현한다.
예를 들어, 6.0
을 2진 부동소수점으로 표현하면 → 1.1 × 2²
부동소수점 수는 가수(Mantissa)와 지수(Exponent)로 구성된다.
가수(Mantissa): 실수 부분을 나타내며, 소수점 왼쪽에 한 자리만 있는 2진수로 정규화됨.
지수(Exponent): 2를 몇 번 거듭제곱해야 하는지를 나타냄.
예제 (4비트 부동소수점, 2비트 가수 + 2비트 지수)
가수 1.1
, 지수 10(₂) = 2(₁₀)
이면
실제 값 = 1.1 × 2² = 6.0(₁₀)
더 넓은 범위의 수를 표현 가능
플랑크 상수(6.63 × 10⁻³⁴)부터 아보가드로 수(6.02 × 10²³) 같은 극단적인 값을 표현할 수 있음.
고정소수점 방식과 달리, 매우 큰 수와 작은 수를 효율적으로 표현할 수 있음.
소수점의 위치를 유동적으로 조절 가능
소수점이 움직이므로 다양한 크기의 수를 표현할 수 있음.
예: 1.1 × 2³ = 8.0
, 1.1 × 2⁻² = 0.375
메모리 절약
필요한 만큼의 가수와 지수만 저장하면 되므로 고정소수점 방식보다 더 효율적임.
비효율적인 비트 사용
같은 값을 여러 개의 방법으로 표현할 수 있어 중복되는 비트 패턴이 발생.
예를 들어 1.0
과 2.0
, 4.0
같은 값은 여러 방법으로 표현 가능.
정확도가 떨어질 수 있음
부동소수점 표현 방식은 근사값을 저장하는 방식이라 정확도가 제한됨.
2진수에서 표현할 수 없는 10진 소수(예: 0.1₁₀ → 0.0001100110011…₂ 무한 반복)가 존재함.
연산 오류 발생 가능
지수가 커질수록 가수의 한 패턴과 다른 패턴 사이의 값 차이가 커진다.
예를 들어 0.5 + 6.0
같은 연산에서 6.5
를 정확히 표현할 수 없는 문제가 발생할 수 있음.
이러한 오류를 해결하기 위해 수치 해석(Numerical Analysis) 분야에서 연구가 이루어짐.
현대 컴퓨터에서는 IEEE 754 부동소수점 표준을 사용한다.
IEEE 754는 단정도(32비트)와 배정도(64비트) 부동소수점 표현 방식을 정의함.
32비트 단정도(Single Precision)
1비트: 부호(Sign)
8비트: 지수(Exponent)
23비트: 가수(Mantissa)
64비트 배정도(Double Precision)
1비트: 부호(Sign)
11비트: 지수(Exponent)
52비트: 가수(Mantissa)
IEEE 754 표준을 따르면 부동소수점 연산의 정확성과 일관성을 유지할 수 있음.
반면 12.00, 01.20, 00.12 같은 고정소수점 수에서 소수점 바로 왼 쪽의 수는 항상 일의 자리 숫자로 고정돼서 고정 소수점이다.
소수점 왼쪽이 항상 일의 자리 숫자는 게 뭔소리일까? 12는 십의 자리인데
"소수점 왼쪽이 항상 일의 자리 숫자"라는 표현이 헷갈릴 수 있는데, 이는 고정소수점 방식과 부동소수점 방식의 차이를 설명하는 맥락에서 사용된 것이다.
고정소수점에서의 소수점 위치
고정소수점(Fixed-Point) 방식에서는 소수점의 위치가 항상 정해져 있어서 변하지 않는다.
예를 들어, 만약 소수점이 항상 일의 자리 숫자(1자리) 왼쪽에 고정되어 있다면, 다음과 같이 표현될 수 있다.
12.00
01.20
00.12
이 경우, 소수점의 위치가 미리 정해져 있어서, 숫자가 변해도 소수점이 움직이지 않는다.
즉, 12
라는 숫자 자체가 아니라 소수점 왼쪽 자릿수가 항상 같은 위치에 유지된다는 의미이다.
예를 들어, 10진수 기준으로 소수점이 일의 자리 숫자 바로 오른쪽에 고정된다면, 항상 다음과 같이 표현된다.
3.45
1.23
0.12
45.67
(여기서는 십의 자리도 포함하지만, 소수점 바로 왼쪽은 5라는 일의 자리)
즉, 소수점의 위치가 항상 같은 곳에 있고, 소수점 왼쪽이 일의 자리 숫자로 유지된다는 의미이다.
반면 부동소수점(Floating-Point) 방식에서는 소수점이 유동적으로 움직일 수 있다. 이는 **과학적 표기법(Scientific Notation)**과 같은 방식으로 숫자를 표현하기 때문이다.
예를 들어, 1.2라는 가수를 사용하여 다른 숫자들을 표현하면
1.2 × 10⁰ = 1.2
1.2 × 10¹ = 12
1.2 × 10² = 120
1.2 × 10⁻¹ = 0.12
같은 1.2
라는 숫자라도, 소수점의 위치가 변하면서 숫자의 크기가 달라질 수 있다.
이와 마찬가지로, 2진수 부동소수점에서도 소수점이 가수(Mantissa)와 지수(Exponent)에 의해 달라지는 것이다.
1.10 × 2³ = 11.0₂ (10진수 6)
1.10 × 2⁻² = 0.0110₂ (10진수 0.375)
1.10 × 2⁵ = 110000.0₂ (10진수 48)
즉, 고정소수점에서는 숫자가 커져도 소수점의 위치가 일정하지만, 부동소수점에서는 숫자의 크기에 따라 소수점의 위치가 바뀐다는 차이가 있다.
고정소수점에서는 소수점의 위치가 고정되어 있어서 소수점 왼쪽 자릿수가 항상 같은 위치에 존재한다.
즉, 특정한 자리수(예: 일의 자리)에서 소수점이 고정되어 변하지 않는다.
부동소수점에서는 소수점이 숫자의 크기에 따라 이동할 수 있기 때문에, 소수점 왼쪽 숫자가 항상 같은 자리에 있지 않는다.
즉, 같은 숫자라도 소수점이 움직이므로 다양한 크기의 값을 표현할 수 있다.
따라서 소수점 왼쪽이 항상 일의 자리 숫자다라는 말은, 고정소수점에서는 소수점이 항상 같은 위치에 있어서, 숫자의 자릿수가 변해도 소수점 왼쪽의 숫자 위치는 일정하다는 의미로 이해하면 된다.
부동소수점 표현법은 소수점의 위치를 고정하지 않고 유동적으로 조절하는 방식이다.
고정소수점보다 훨씬 넓은 범위의 숫자를 표현할 수 있어, 현대 컴퓨터에서 널리 사용된다. 하지만 정확도의 한계와 연산 오류 가능성이 있으며, 이를 해결하기 위해 IEEE 754 표준이 도입되었다.
부동소수점 연산을 다룰 때는 반올림 오차, 정밀도 손실, 수치 해석 기법 등을 고려해야 한다.
이제 부동소수점 개념이 이해되었으면,
IEEE 754 부동소수점 표준의 내부 구조와 동작 방식
부동소수점 연산에서 발생하는 오차와 그 해결 방법
컴퓨터에서 실수 연산을 다룰 때 주의할 점
등을 배우면 더욱 깊이 있는 이해가 가능하다. 🚀
IEEE 754는 컴퓨터에서 실수를 부동소수점 방식으로 표현하고 연산하는 표준이다.
이 표준은 단정도(32비트)와 배정도(64비트) 부동소수점을 정의하며, 부동소수점 연산의 정확성을 높이기 위한 여러 기법이 포함되어 있다.
부동소수점은 표 1-8보다 더 많은 비트를 사용하며, 가수와 지수에 대해 각각 부호 비트를 사용한다 지수에 대한 부호 비트는 지수의 비트 패턴에 감춰져 있다.
낭비되는 비트 조합을 최소화하고 반올림을 쉽게 하기 위한 여러 가지 트릭이 사용된다.
IEEE 754라는 표준은 이 모든 기능을 정의한다.
1비트
단정도: 8비트 / 배정도: 11비트
단정도: 23비트 / 배정도: 52비트
1비트 (부호, Sign) → 0
이면 양수, 1
이면 음수
8비트 (지수, Exponent) → 2의 거듭제곱을 나타내며, Bias를 적용하여 부호 비트 없이 표현
23비트 (가수, Mantissa) → 유효숫자로, 정규화(normalization) 기법을 적용하여 저장 공간을 절약
실제 값=(−1)부호×(1+가수)×2(지수−Bias)\text{실제 값} = (-1)^{\text{부호}} \times (1 + \text{가수}) \times 2^{(\text{지수} - \text{Bias})}
단정도(32비트) → Bias: 127
배정도(64비트) → Bias: 1023
예제: 0 10000001 10100000000000000000000
(단정도 32비트)
부호: 0
(양수)
지수: 10000001₂ = 129
, 실제 지수 = 129 - 127 = 2
가수: 1.101₂ = 1 + 0.5 + 0.125 = 1.625
값: 1.625 × 2² = 6.5
IEEE 754는 똑같은 비트를 사용하면서도 최대한 정밀도를 높이는 다양한 기법을 적용한다.
(1) 정규화(Normalization)
가수의 왼쪽(맨 앞) 비트가 항상 1이 되도록 조정하여 불필요한 0을 제거하고 비트 공간을 절약.
예제: 0.01101 × 2⁵
→ 1.101 × 2²
원래는 01101.0000₂
이지만, 왼쪽 첫 번째 1이 가수의 시작이 되도록 소수점을 이동하고 지수를 조정.
(2) 암시적 1비트 (Hidden Bit)
가수의 맨 앞 비트는 항상 1이므로 저장하지 않고 생략, 대신 필요한 추가 정보를 저장할 수 있도록 비트를 절약
단정도에서는 23비트 가수지만 실제로는 24비트(1비트가 암시적 1비트로 존재).
디지털 이큅먼트 사DEC, Digital Equipment Corporation에서 고안한 것
가수의 맨 왼쪽 비트가 1이라는 사실을 알고 있으므로 이를 생략하는 것
이로 인해 가수에 1비트를 더 사용할 수 있다
IEEE 754의 세부 사항을 모두 알 필요는 (아직은) 없다. 하지만 두 가지 부동소수점 수가 자주 쓰인다는 사실을 알아둬야 한다.
부호 비트
1비트
1비트
지수 비트
8비트 (Bias = 127)
11비트 (Bias = 1023)
가수 비트
23비트 (24비트 효과)
52비트 (53비트 효과)
정밀도
약 7자리 (10진수)
약 15자리 (10진수)
표현 가능한 범위
±10³⁸ 정도
±10³⁰⁸ 정도
메모리 사용량
적음 (일반적인 연산에 적합)
큼 (과학 계산, 금융 연산에 적합)
그림에서 2배 정밀도 수가 기본 정밀도 수보다 지수가 3비트 더 크다는 점을 볼 수 있다.
따라서 지수의 범위 는 8배 더 크다.
2배 정밀도 수
는 기본 정밀도 수보다 가수가 29비트 더 크다. 따라서 정밀도도 훨씬 더 크다. 하지만 이런 모든 장점은 비트를 2배나 더 많이 사용한다는 비용을 지불하고 얻은 것이다.
지수에 대해 부호 비트가 따로 존재하지 않는다.
IEEE 754 를 설계한 사람들은 지수 비트가 모두 0이거나 1인 경우에 특별한 의미를 갖게 하고, 실제 지숫 값은 나머지 비트 패턴에 집어넣고 싶었다. 그래서IEEE 754는 특별한 비트 패턴을 사용하여 특정한 연산 결과를 처리할 수 있도록 설계되었다.
(1) 편향된(Biased) 지수
지수 값에 Bias(편향값)를 더해 부호 비트를 없애고, 정렬을 쉽게 함.
단정도에서는 Bias = 127, 배정도에서는 Bias = 1023 사용.
127(01111111₂)
→ 실제 지수 0
1(00000001₂)
→ 실제 지수 -126
254(11111110₂)
→ 실제 지수 +127
(2) 0으로 나누는 경우의 처리
IEEE 754는 0으로 나누는 연산을 수행할 때 양/음의 무한대(∞)를 표현하는 특별한 비트 패턴을 제공.
+∞
, -∞
을 명확히 정의하여 에러 처리를 쉽게 만듦.
(3) NaN (Not a Number)
0/0
, √(-1)
같은 정의되지 않은 연산이 발생하면 NaN(Not a Number)을 반환.
NaN 값이 포함된 계산은 전파되어, 후속 연산에서도 NaN을 유지함.
부동소수점 수로 계산을 하던 도중에 NaN 값이 생기면 뭔가 잘못된 산술 연산을 수행했다는 뜻
이런 특별한 비트 패턴들은 앞에서 이야기한 특별한 지숫값(모든 비트가 0이거나 모든 비트가 1인 지수)을 사용
부동소수점 연산은 비트 수가 제한된 환경에서 실수를 표현해야 하므로, 오차가 발생할 수 있다.
(1) 표현할 수 없는 값
10진수 0.1
을 2진수로 변환하면 무한 반복(0.0001100110011...)되므로, 근사값으로 저장됨.
이로 인해 0.1 + 0.2 ≠ 0.3
같은 연산 오차가 발생할 수 있음.
(2) 반올림 오차 (Rounding Error)
저장할 수 있는 비트 수가 제한되므로 반올림이 발생하고, 작은 숫자가 더해질 때 정밀도가 떨어질 수 있음.
(3) 연산 순서에 따른 오차
(A + B) + C ≠ A + (B + C) 가 될 수 있음.
큰 숫자와 작은 숫자를 더할 때, 작은 숫자가 반올림으로 인해 손실될 수도 있음.
부동소수점 연산의 오차를 줄이기 위해 여러 기법을 사용할 수 있다.
(1) Kahan Summation Algorithm
작은 값이 반올림으로 손실되는 문제를 해결하는 알고리즘.
(2) decimal
모듈 사용 (Python)
(3) 정수 연산 활용
금융 연산에서는 소수를 사용하지 않고 정수 단위로 변환 후 연산하는 것이 일반적임.
IEEE 754 부동소수점 표준은 실수를 표현하는 방식으로, 부호(1비트), 지수(8비트), 가수(23비트)로 구성됨.
Bias를 적용한 지수 표현과 정규화된 가수를 사용하여 저장 공간을 효율적으로 활용함.
단정도(32비트)는 일반적인 연산에 적합하고, 배정도(64비트)는 높은 정밀도가 필요한 과학 및 금융 연산에 적합.
부동소수점 연산에서는 표현할 수 없는 값, 반올림 오차, 연산 순서에 따른 오차가 발생할 수 있음.
Kahan Summation, decimal
모듈 사용, 정수 연산 활용 등의 방법으로 오차를 줄일 수 있음.
(1) 비교 연산에서 ==
사용 금지
if (x == 0.1)
같은 비교는 오차 때문에 잘못된 결과를 낼 수 있음.
대신 허용 오차(ε)를 활용한 비교를 해야 함.
(2) 누적 오차 고려
반복 연산이 많아질수록 오차가 누적될 수 있으므로, 정밀도를 고려해야 함.
(3) 정확한 계산이 필요한 경우 정수 연산 사용
금융 계산에서는 소수를 직접 사용하지 않고, 정수 단위(예: 센트 단위)로 변환하는 것이 일반적임.
(4) 알고리즘 설계 시 오차를 감안한 전략 필요
수치 해석(Numerical Analysis) 기법을 활용하여 부동소수점 오차를 최소화하는 알고리즘을 선택해야 함.
1. BCD란?
BCD(Binary-Coded Decimal)는 4비트를 사용하여 10진 숫자(0~9)를 개별적으로 표현하는 방식이다.
즉, 각 10진 자리(일의 자리, 십의 자리 등)를 4비트 이진수로 변환하여 저장한다.
예제:
10진수 12
일반적인 2진수 표현: 1100₂
BCD 표현: 0001 0010₂
(1
은 십의 자리, 2
는 일의 자리)
BCD 방식은 사람이 읽고 해석하기 쉬운 장점이 있어, 디지털 디스플레이나 센서 데이터 처리 등에 사용된다.
2. BCD의 장점
10진수와의 직관적인 호환성
사람에게 익숙한 10진수와 직접적으로 매핑되므로, 디지털 디스플레이 장치에서 사용하기 편리함.
예를 들어, 127
을 BCD로 표현하면 0001 0010 0111
로 변환되며, 각 4비트 단위로 10진수를 쉽게 읽을 수 있음.
디지털 기기에서 유용
디지털 시계, 계산기, 계측기, 센서 등에서 BCD를 사용하면 숫자를 그대로 출력하기 쉬움.
예를 들어, LCD 디스플레이에서 숫자를 표시할 때, BCD를 사용하면 변환 과정이 간단해짐.
3. BCD의 단점
비트 낭비
4비트는 0000₂
(0)부터 1111₂
(15)까지 16가지 값을 표현할 수 있지만, BCD에서는 10진수 0~9까지만 사용.
즉, 6가지 조합(1010₂
~1111₂
)은 사용되지 않으며, 전체 비트의 37.5%가 낭비됨.
연산 비효율성
일반적인 2진수 연산과 다르게, BCD 연산(덧셈, 뺄셈 등)은 별도의 보정이 필요함.
예를 들어, BCD 덧셈에서 9 + 1 = 10
이 되면, 10을 BCD로 변환(0001 0000₂
)하는 추가 과정이 필요.
따라서 CPU가 직접 BCD 연산을 지원하지 않으면, 소프트웨어적으로 처리해야 하는 부담이 생김.
4. BCD의 사용 감소
과거 일부 컴퓨터들은 BCD를 직접 지원하는 명령어를 제공했지만, 오늘날에는 거의 사용되지 않음. 그 이유는 일반적인 2진수 표현보다 비효율적이기 때문이다.
과거:
컴퓨터 성능이 낮고, 비트 비용이 높았을 때 디지털 디스플레이 장치와의 호환성 때문에 BCD가 사용됨.
예를 들어, 초창기 IBM 메인프레임 일부 모델에서는 BCD를 하드웨어적으로 지원.
현재:
비트 비용이 낮아졌으며, BCD의 비효율성이 크기 때문에 대부분 2진수 연산으로 대체됨.
일부 센서나 디지털 디스플레이 장치에서 BCD가 사용되지만, 연산 처리는 대부분 일반적인 2진수 방식으로 변환하여 수행.
사람들은 2진수를 더 읽기 쉽게 표현할 수 있는 방법을 고안해냈다.