Skip to Content
독학사독학사 2단계컴퓨터구조08. 자료의 표현: 부동소수점·문자코드·오류검출

이번 문서의 목표: 이 파일을 다 읽으면 임의의 실수를 IEEE 754 단정도(single precision) 32비트로 직접 변환하고, 문자 인코딩 체계의 차이를 설명하며, 패리티 비트와 해밍 코드로 오류를 검출·위치 계산할 수 있다.

왜 정수 표현만으로는 부족한가

07편에서 정수를 2의 보수로 표현하는 법을 다뤘다. 하지만 정수만으로는 3.143.14, 0.001-0.001처럼 소수점이 있는 실수(real number)나, 매우 크거나 매우 작은 수를 표현할 수 없다. 04편 “부동소수점과 오버플로 사전지식”에서 가수(mantissa)·지수(exponent)와 과학적 표기법의 개념을 맛봤는데, 이번 편에서는 국제 표준인 IEEE 754가 이 개념을 실제 비트열로 어떻게 구현하는지 끝까지 손으로 계산한다.

IEEE 754 단정도: 32비트를 세 부분으로 나눈다

쉽게 말하면: 부호 1비트, 지수 8비트, 가수 23비트, 총 32비트로 실수를 표현하는 국제 표준이다.

IEEE 754는 미국 전기전자학회(IEEE, Institute of Electrical and Electronics Engineers)가 제정한 부동소수점(floating point) 표현의 국제 표준이다. 단정도(single precision)는 32비트를 사용하며 다음과 같이 나뉜다.

부분비트 수위치역할
부호(sign)1비트31번(최상위)0이면 양수, 1이면 음수
지수(exponent)8비트30–23번편향된(bias) 지수값 저장
가수(mantissa, fraction)23비트22–0번정규화된 가수의 소수부

지수부는 바이어스(bias, 편향값) 127을 더한 값을 저장한다. 즉 저장되는 지수값은 E저장=E실제+127E_{저장} = E_{실제} + 127이다. 바이어스를 쓰는 이유는 지수가 음수일 수도 있는데, 부호 없는 정수로만 저장된 지수부의 대소 비교를 정수 비교 회로로 그대로 처리하고 싶기 때문이다(바이어스를 더하면 지수부가 항상 0 이상의 정수로 저장되어, 크기 비교가 단순한 정수 비교와 같아진다).

실제 십진수를 IEEE 754 단정도로 변환하기: 12.375-12.375

쉽게 말하면: 정수부와 소수부를 각각 2진수로 바꾸고, 정규화해서 지수를 뽑아낸 뒤, 부호·지수·가수 세 칸에 순서대로 채워 넣으면 된다.

1단계: 부호 비트 결정

12.375-12.375는 음수이므로 **부호 비트 =1= 1**이다.

2단계: 절댓값 12.37512.375를 2진수로 변환

정수부 1212를 2진수로 변환한다. 12=8+4=1100212 = 8 + 4 = 1100_2다.

소수부 0.3750.375를 2진수로 변환한다. 소수부는 2를 곱해가며 정수부를 뽑아내는 방식을 쓴다.

0.375×2=0.75  (정수부0)0.375 \times 2 = 0.75 \;(\text{정수부} 0) 0.75×2=1.5  (정수부 1)0.75 \times 2 = 1.5 \;(\text{정수부 } 1) 0.5×2=1.0  (정수부 1)0.5 \times 2 = 1.0 \;(\text{정수부 } 1)

나온 정수부를 순서대로 나열하면 0.37510=0.01120.375_{10} = 0.011_2이다(마지막 소수부가 0이 되었으므로 여기서 끝난다).

따라서 12.37510=1100.011212.375_{10} = 1100.011_2다.

3단계: 정규화(normalization)

정규화란 이진수를 1.xxxxx×2e1.xxxxx \times 2^e 형태로 바꾸는 것을 말한다. 소수점을 왼쪽으로 옮겨서 정수부가 1 하나만 남게 만들고, 옮긴 자릿수만큼 지수를 매긴다.

1100.01121100.011_2에서 소수점을 왼쪽으로 3칸 옮기면 1.1000112×231.100011_2 \times 2^3이 된다.

1100.0112=1.1000112×231100.011_2 = 1.100011_2 \times 2^3
  • 정규화된 가수(유효숫자) 부분: 1.1000111.100011
  • 실제 지수 E실제=3E_{실제} = 3

4단계: 지수부에 바이어스 127을 더해 저장값 계산

E저장=E실제+127=3+127=130E_{저장} = E_{실제} + 127 = 3 + 127 = 130

130130을 8비트 2진수로 바꾸면 128+2=130128 + 2 = 130이므로 10000010210000010_2다.

5단계: 가수부(fraction) 23비트 채우기

정규화 결과 1.100011×231.100011 \times 2^3에서 소수점 앞의 1은 항상 1이라는 것이 자명하므로 저장하지 않는다. 이것을 암묵의 1(implicit/hidden bit)이라 부른다. 저장하는 것은 소수점 뒤의 100011100011뿐이다. 가수부는 23비트이므로 뒤에 0을 채워 자리를 맞춘다.

10001100000000000000000나머지는 0으로 채움100011\underbrace{00000000000000000}_{\text{나머지는 0으로 채움}}

23자리를 정확히 세면: 10001100000000000000000 (총 23비트).

6단계: 세 부분을 순서대로 이어 붙이기

부호(1비트)지수(8비트)가수(23비트)
11000001010001100000000000000000

전체를 이어 붙이면 다음과 같은 32비트가 된다.

1 10000010 10001100000000000000000

검산: 이 비트열을 거꾸로 십진수로 바꿔 원래 값이 나오는지 확인한다. 부호 비트 1은 음수, 지수는 100000102=13010000010_2 = 130이므로 E실제=130127=3E_{실제} = 130 - 127 = 3, 가수는 암묵의 1을 앞에 붙이면 1.1000110000000000000000021.10001100000000000000000_2이다. 이 값을 계산하면 1+0.5+0.0625+0.03125=1.593751 + 0.5 + 0.0625 + 0.03125 = 1.59375이고, 1.59375×23=1.59375×8=12.751.59375 \times 2^3 = 1.59375 \times 8 = 12.75… 이 부분을 다시 짚어보면, 1.10001121.100011_2을 십진수로 바꿀 때는 1+21+25+26=1+0.5+0.03125+0.015625=1.5468751 + 2^{-1} + 2^{-5} + 2^{-6} = 1 + 0.5 + 0.03125 + 0.015625 = 1.546875이고, 여기에 23=82^3 = 8을 곱하면 1.546875×8=12.3751.546875 \times 8 = 12.375가 된다. 부호까지 반영하면 12.375-12.375로, 원래 값과 정확히 일치한다.

검산할 때는 가수의 각 비트 위치가 21,22,23,2^{-1}, 2^{-2}, 2^{-3}, \dots 순서로 값을 갖는다는 점을 놓치지 말아야 한다. 1.10001121.100011_2에서 소수점 뒤 비트는 순서대로 21(=0.5)2^{-1}(=0.5), 22(=0.25,비트값 0)2^{-2}(=0.25, \text{비트값 }0), 23(=0.125,0)2^{-3}(=0.125, 0), 24(=0.0625,0)2^{-4}(=0.0625, 0), 25(=0.03125,1)2^{-5}(=0.03125, 1), 26(=0.015625,1)2^{-6}(=0.015625, 1)이다. 자리를 하나만 밀려 읽어도 전혀 다른 값이 나오므로, 시험에서는 자리별로 표를 그려 확인하는 습관이 안전하다.

정규화와 비정규화 수

쉽게 말하면: 정규화 수는 맨 앞자리가 항상 1인 표준 형태이고, 비정규화 수는 0에 아주 가까운 극소값을 표현하기 위한 예외 형태다.

지수부가 전부 0인 특수한 경우(E저장=000000002E_{저장} = 00000000_2)를 비정규화 수(denormalized number, subnormal number)라 부른다. 이 경우에는 암묵의 1을 가정하지 않고 0.xxxxx×21260.xxxxx \times 2^{-126} 형태로 해석해, 정규화 수로는 표현할 수 없는 0에 매우 가까운 극소값을 표현한다. 지수부가 전부 1이면(11111111211111111_2) 가수부가 0일 때는 무한대(Infinity), 가수부가 0이 아니면 NaN(Not a Number, 정의되지 않은 값)을 나타내는 특수값으로 예약되어 있다.

문자 인코딩: 문자를 숫자로 약속하는 방법

쉽게 말하면: 컴퓨터는 숫자만 다룰 수 있으므로, 어떤 숫자가 어떤 문자를 뜻하는지 미리 약속해 둔 표가 문자 인코딩이다.

ASCII(American Standard Code for Information Interchange, 미국 정보교환 표준부호)는 7비트로 영문 알파벳·숫자·특수문자·제어문자를 표현하는 가장 오래된 표준 문자 인코딩이다. 7비트이므로 27=1282^7 = 128가지 문자를 표현할 수 있다. 예를 들어 대문자 A는 65(100000121000001_2), 소문자 a는 97이다.

ASCII의 한계는 명확하다. 128가지로는 한글, 한자, 각국 문자를 전혀 표현할 수 없다. 이를 해결하기 위해 등장한 것이 유니코드(Unicode)다. 유니코드는 전 세계 모든 문자에 고유한 코드 포인트(code point)를 부여하려는 국제 표준으로, 문자 하나하나에 U+0041(대문자 A)처럼 번호를 매긴다. 유니코드를 실제 바이트열로 저장하는 방식(인코딩 방식)에는 UTF-8(가변 길이, 영문은 1바이트로 ASCII와 호환), UTF-16(2바이트 또는 4바이트 단위) 등이 있다.

구분ASCII유니코드(UTF-8)
비트 수7비트(128가지)가변 길이(1–4바이트)
표현 범위영문·숫자·기본 특수문자만전 세계 모든 문자
ASCII와 호환성기준 자체UTF-8은 영문 구간에서 ASCII와 동일

오류 검출: 전송 중 비트가 뒤집혔는지 확인하기

쉽게 말하면: 데이터에 별도의 검사용 비트를 추가해 두면, 받는 쪽에서 그 비트로 계산해봐서 데이터가 중간에 손상됐는지 확인할 수 있다.

03편에서 패리티 비트와 해밍 개념을 맛봤다. 여기서는 시험에 실제로 나오는 계산 포인트까지 파고든다.

패리티 비트: 1의 개수를 짝수 또는 홀수로 맞춘다

패리티 비트(parity bit)는 데이터 비트에 1비트를 추가해, 전체 1의 개수를 짝수(짝수 패리티, even parity) 또는 홀수(홀수 패리티, odd parity)로 맞추는 오류 검출 방식이다.

예를 들어 데이터 1011000에서 1의 개수는 3개(홀수)다. 짝수 패리티를 쓴다면 1의 총 개수를 짝수로 맞춰야 하므로 패리티 비트를 1로 추가해 10110001(1의 개수 4개, 짝수)을 만든다.

패리티 비트의 한계는 짝수 개의 비트가 동시에 뒤집히면 검출하지 못한다는 점이다. 예를 들어 2개의 비트가 동시에 뒤집히면 1의 개수의 홀짝이 원래대로 돌아와 오류를 놓친다. 그리고 패리티 비트는 오류가 있다는 것만 알려줄 뿐, 어느 비트가 틀렸는지는 알려주지 못한다.

해밍 코드: 오류의 위치까지 찾아낸다

해밍 코드(Hamming code)는 여러 개의 패리티 비트를 정해진 위치에 배치해, 오류 검출뿐 아니라 오류가 발생한 비트의 위치까지 계산해내는 방식이다. 리처드 해밍(Richard Hamming)이 1950년에 고안했다.

해밍 코드의 핵심 아이디어는 패리티 비트를 20,21,22,24,2^0, 2^1, 2^2, 2^4, \dots번째 자리(1, 2, 4, 8, …)에 배치하고, 각 패리티 비트가 자신의 이진 위치에 해당 비트가 1로 켜져 있는 데이터 비트들만 검사하도록 그룹을 나누는 것이다.

예제: 7비트 코드워드에서 오류 위치 계산하기

데이터 4비트 1011을 해밍 코드로 부호화한 뒤, 수신 측에서 오류를 검출하는 과정을 살펴보자. 7비트 해밍 코드(데이터 4비트 + 패리티 3비트, 흔히 (7,4) 해밍 코드라 부른다)에서 위치 1, 2, 4는 패리티 비트(P1,P2,P4P_1, P_2, P_4)이고 위치 3, 5, 6, 7은 데이터 비트(D3,D5,D6,D7D_3, D_5, D_6, D_7)다.

위치1234567
종류P1P_1P2P_2D3D_3P4P_4D5D_5D6D_6D7D_7
??1?011

패리티 그룹은 위치의 이진수 표현으로 정해진다.

  • P1P_1(위치 1, 이진수 001)은 이진수 표현의 1번째 비트(최하위 비트)가 1인 모든 위치, 즉 1, 3, 5, 7번 위치를 검사한다.
  • P2P_2(위치 2, 이진수 010)는 2번째 비트가 1인 위치, 즉 2, 3, 6, 7번 위치를 검사한다.
  • P4P_4(위치 4, 이진수 100)는 3번째 비트가 1인 위치, 즉 4, 5, 6, 7번 위치를 검사한다.

짝수 패리티로 맞춘다고 하면, 각 그룹에 속한 비트(패리티 비트 자신 포함)의 1의 개수 합이 짝수가 되도록 패리티 비트 값을 정한다.

  • P1P_1 그룹(1,3,5,7번 위치의 데이터 비트 3,5,7 = D3=1,D5=0,D7=1D_3=1, D_5=0, D_7=1): 1의 개수가 2개(짝수)이므로 P1=0P_1 = 0.
  • P2P_2 그룹(2,3,6,7번 위치의 데이터 비트 3,6,7 = D3=1,D6=1,D7=1D_3=1, D_6=1, D_7=1): 1의 개수가 3개(홀수)이므로 짝수로 맞추려면 P2=1P_2 = 1.
  • P4P_4 그룹(4,5,6,7번 위치의 데이터 비트 5,6,7 = D5=0,D6=1,D7=1D_5=0, D_6=1, D_7=1): 1의 개수가 2개(짝수)이므로 P4=0P_4 = 0.

완성된 7비트 코드워드는 다음과 같다.

위치1234567
0110011

수신 측 오류 위치 계산: 3번째 비트가 뒤집혔다고 가정

전송 중 3번째 비트가 뒤집혀 수신된 코드워드가 0110011이 아니라 0100011이 되었다고 하자(3번 위치 값이 1에서 0으로 바뀜).

위치1234567
수신값0100011

수신 측은 송신 측과 똑같은 규칙으로 각 패리티 그룹의 1의 개수 짝홀을 다시 검사한다. 이때 나오는 결과를 체크비트(check bit) C1,C2,C4C_1, C_2, C_4라 하며, 그룹의 짝수 패리티가 깨졌으면 1, 유지되면 0으로 기록한다.

  • C1C_1: 1,3,5,7번 위치(0,0,0,10,0,0,1)의 1의 개수는 1개(홀수) → 짝수 패리티가 깨졌으므로 C1=1C_1 = 1.
  • C2C_2: 2,3,6,7번 위치(1,0,1,11,0,1,1)의 1의 개수는 3개(홀수) → 깨졌으므로 C2=1C_2 = 1.
  • C4C_4: 4,5,6,7번 위치(0,0,1,10,0,1,1)의 1의 개수는 2개(짝수) → 유지되므로 C4=0C_4 = 0.

체크비트를 C4C2C1C_4 C_2 C_1 순서로 이진수로 읽으면 0112=3011_2 = 3이다.

오류 위치=C4C2C1(이진수)=0112=3\text{오류 위치} = C_4 C_2 C_1 \text{(이진수)} = 011_2 = 3

결과 해석: 계산된 값 33이 바로 오류가 발생한 비트의 위치다. 실제로 우리가 일부러 뒤집었던 자리가 3번 위치였으므로, 해밍 코드가 오류 위치를 정확히 짚어냈다. 오류 위치를 알면 수신 측은 그 비트를 다시 반전시켜 즉시 정정(correction)할 수 있다. 이것이 패리티 비트 하나만 쓸 때와 결정적으로 다른 점이다. 패리티 비트는 오류가 있는지 없는지만 알려주지만, 해밍 코드는 어디가 틀렸는지까지 알려준다.

자주 틀리는 점

  • 체크비트를 읽는 순서를 C1C2C4C_1 C_2 C_4로 잘못 배열하는 실수가 흔하다. 반드시 자리값이 큰 것부터(C4C_4가 최상위) 나열해야 올바른 위치가 나온다.
  • 체크비트가 모두 0이면 오류가 없다는 뜻이다. 0002=0000_2 = 0번 위치는 존재하지 않으므로 “오류 없음”으로 해석한다.
  • 패리티 그룹에 패리티 비트 자기 자신도 포함해서 1의 개수를 세야 한다는 것을 빠뜨리기 쉽다.

핵심 정리

  • IEEE 754 단정도는 부호 1비트, 지수 8비트(바이어스 127), 가수 23비트(암묵의 1 생략)로 구성되며, 십진수를 변환할 때는 “정수부·소수부 2진 변환 → 정규화 → 지수에 바이어스 더하기 → 가수 23비트 채우기” 순서를 따른다.
  • 지수부가 전부 0이면 비정규화 수, 전부 1이면 무한대 또는 NaN을 나타내는 특수값이다.
  • ASCII는 7비트 128가지 문자, 유니코드는 전 세계 문자를 다루며 UTF-8·UTF-16 같은 인코딩 방식으로 저장된다.
  • 패리티 비트는 오류 유무만 검출하고 짝수 개의 오류는 놓치지만, 해밍 코드는 패리티 비트를 여러 개 배치해 오류의 정확한 위치까지 계산해낸다.
  • 해밍 코드에서 오류 위치는 각 패리티 그룹의 체크비트를 자리값이 큰 순서로(C4C2C1C_4 C_2 C_1) 이진수로 읽어서 구한다.

마무리 복습

문제 14지선다
IEEE 754 단정도(32비트) 부동소수점 표현의 구성으로 옳은 것은?
문제 24지선다
십진수 12.375를 정규화된 이진수 형태로 바르게 나타낸 것은?
문제 34지선다
IEEE 754 단정도에서 지수부에 바이어스(bias) 127을 더해서 저장하는 이유로 가장 적절한 것은?
문제 44지선다
패리티 비트(parity bit) 방식의 한계로 옳은 것은?
문제 54지선다
(7,4) 해밍 코드에서 체크비트 계산 결과 C4=1, C2=0, C1=1이 나왔다면 오류가 발생한 비트 위치는?
문제 64지선다
IEEE 754 단정도에서 지수부가 전부 0(00000000)인 경우가 나타내는 것은?

참고 자료

Last updated on