ROONTAMS
ROONTAMS
ROONTAMS
전체 방문자
오늘
어제
  • 분류 전체보기 (13)
    • Unity : 개발 (0)
    • 강의 (12)
      • iOS개발 강의 (6)
      • React 강의 (1)
      • 컴퓨터 구조 (5)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

태그

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ROONTAMS

ROONTAMS

강의/컴퓨터 구조

데이터의 표현 - Part2

2025. 9. 19. 03:15
컴퓨터구조 Part 2: 데이터 표현 II

컴퓨터구조 Part 2

데이터 표현 II: 실수와 문자의 디지털 세계
소프트웨어공학 관점에서 이해하는 데이터 표현의 심층 분석

📚 목차

  • 2.1 실수의 표현 (40분)
  •     2.1.1 고정소수점 표현
  •     2.1.2 부동소수점 표현 (IEEE 754 표준)
  •     2.1.3 실수 표현의 한계
  • 2.2 문자의 표현 (30분)
  •     2.2.1 ASCII 코드
  •     2.2.2 한글 인코딩의 역사
  •     2.2.3 유니코드와 UTF
  • 2.3 부동소수점 연산의 오차와 주의사항 (20분)
  •     2.3.1 부동소수점 연산의 문제점
  •     2.3.2 프로그래밍 시 주의사항
  •     2.3.3 실제 사고 사례 분석

2.1 실수의 표현

학습목표: 컴퓨터에서 실수를 표현하는 방법을 이해하고, 각 방법의 장단점과 프로그래밍 시 고려사항을 파악한다.

2.1.1 고정소수점 표현

고정소수점(Fixed-point) 표현은 실수를 정수부와 소수부로 나누어 고정된 위치에 소수점을 둔다. 예를 들어, 16비트를 8.8 형식으로 사용하면 상위 8비트는 정수부, 하위 8비트는 소수부를 표현한다.

왜 고정소수점을 사용할까?
게임 프로그래밍이나 임베디드 시스템에서는 부동소수점 연산이 느리거나 불가능한 경우가 있다. 고정소수점은 정수 연산만으로 실수를 다룰 수 있어 매우 빠르다!

실습: 12.75를 8.8 고정소수점으로 표현하기

1 정수부 12 = 0000 1100₂
2 소수부 0.75 = 0.11₂ (0.5 + 0.25)
3 소수부 8비트로 확장: 1100 0000₂
4 최종 결과: 0000 1100 . 1100 0000
장점 단점 사용 예
빠른 연산 속도 제한된 표현 범위 게임 물리 엔진
예측 가능한 정밀도 고정된 정밀도 오디오 처리
정수 ALU만 필요 오버플로우 위험 임베디드 시스템

2.1.2 부동소수점 표현 (IEEE 754 표준) ⭐

부동소수점(Floating-point)은 과학적 표기법처럼 가수부와 지수부를 분리하여 표현한다. IEEE 754는 이를 표준화한 규격으로, 현재 거의 모든 컴퓨터가 사용한다.

IEEE 754 단정밀도(32비트) 구조

S EEEEEEEE MMMMMMMMMMMMMMMMMMMMMMM
  • S (1비트): 부호비트 (0=양수, 1=음수)
  • E (8비트): 지수부 (바이어스 127 적용)
  • M (23비트): 가수부 (정규화된 1.xxx의 xxx 부분)

실제 값 = (-1)^S × 2^(E-127) × (1 + M/2²³)

실습: -12.375를 IEEE 754 단정밀도로 변환

1 부호 결정
음수이므로 S = 1
2 이진수 변환
12.375₁₀ = 1100.011₂
(12 = 1100₂, 0.375 = 0.011₂)
3 정규화
1100.011₂ = 1.100011 × 2³
따라서 지수 = 3
4 지수부 계산
E = 3 + 127 = 130₁₀ = 10000010₂
5 가수부 결정
1.100011의 소수부분: 100011
23비트로 확장: 10001100000000000000000
6 최종 결과
1 10000010 10001100000000000000000
16진수: 0xC1460000

특수값 표현

값 지수 (E) 가수 (M) 의미
±0 00000000 모두 0 영(Zero)
비정규수 00000000 0이 아님 매우 작은 수
±∞ 11111111 모두 0 무한대
NaN 11111111 0이 아님 숫자 아님
주의! NaN은 자기 자신과도 같지 않다. 즉, NaN == NaN은 항상 false다. 이는 IEEE 754 표준의 특별한 규칙이다.

2.1.3 실수 표현의 한계

컴퓨터는 유한한 비트로 무한한 실수를 표현해야 한다. 이는 필연적으로 정밀도 손실과 표현 불가능한 수를 만들어낸다.

0.1은 왜 정확히 표현할 수 없을까?

0.1을 이진수로 변환하면:

0.1₁₀ = 0.0001100110011001100110011...₂ (무한 반복)
                            
32비트로 저장하면:
0.00011001100110011001101 (반올림됨)

실제 값: 0.100000001490116119384765625
오차: 0.000000001490116119384765625

이처럼 10진수로 간단한 수도 2진수로는 순환소수가 될 수 있다!

Machine Epsilon 이해하기

Machine Epsilon(ε)은 1.0과 그 다음 표현 가능한 수 사이의 간격이다.

  • 단정밀도: ε ≈ 1.19 × 10⁻⁷
  • 배정밀도: ε ≈ 2.22 × 10⁻¹⁶

이보다 작은 차이는 구별할 수 없다!

2.2 문자의 표현

학습목표: 문자 인코딩의 발전 과정을 이해하고, 다양한 인코딩 방식의 특징과 호환성 문제를 파악한다.

2.2.1 ASCII 코드

ASCII(American Standard Code for Information Interchange)는 1963년 개발된 7비트 문자 인코딩으로, 128개의 문자를 표현할 수 있다.

ASCII 코드의 구성

0~31 제어 문자 (줄바꿈, 탭 등)
32~47 특수 문자 (공백, !, " 등)
48~57 숫자 (0~9)
65~90 대문자 (A~Z)
97~122 소문자 (a~z)

실습: "Hello"를 16진수 ASCII로 표현

문자 ASCII (10진수) ASCII (16진수) 이진수
H 72 0x48 0100 1000
e 101 0x65 0110 0101
l 108 0x6C 0110 1100
l 108 0x6C 0110 1100
o 111 0x6F 0110 1111

결과: "Hello" = 0x48 65 6C 6C 6F

프로그래밍 팁
대문자를 소문자로 변환하려면 32를 더하면 된다! (A=65, a=97)
이는 비트 연산으로 OR 0x20과 같다.

2.2.2 한글 인코딩의 역사

한글은 초성, 중성, 종성의 조합으로 이루어져 있어 인코딩이 복잡하다. 이를 해결하기 위해 다양한 방식이 개발되었다.

조합형 vs 완성형

구분 조합형 완성형
원리 자모를 조합하여 표현 완성된 글자에 코드 부여
장점 모든 한글 표현 가능 간단한 구현
단점 복잡한 조합 로직 일부 글자만 표현
예시 한 = ㅎ(5비트) + ㅏ(5비트) + ㄴ(5비트) 한 = 0xD55C (고정)

실습: '가'의 다양한 인코딩 비교

인코딩 바이트 수 16진수 값 특징
EUC-KR 2 0xB0A1 한국 표준
CP949 2 0xB0A1 윈도우 확장
UTF-8 3 0xEAB080 국제 표준
UTF-16 2 0xAC00 유니코드 직접
인코딩 지옥
한글이 깨져 보이는 이유는 대부분 인코딩 불일치 때문이다. EUC-KR로 저장한 파일을 UTF-8로 읽으면 "한글"이 "�븳湲�"처럼 보인다!

2.2.3 유니코드와 UTF

유니코드는 전 세계 모든 문자를 하나의 체계로 표현하기 위한 국제 표준이다. 각 문자에 고유한 코드 포인트(Code Point)를 부여한다.

UTF-8 인코딩 규칙

코드 포인트 범위 UTF-8 바이트 패턴 바이트 수
U+0000 ~ U+007F 0xxxxxxx 1
U+0080 ~ U+07FF 110xxxxx 10xxxxxx 2
U+0800 ~ U+FFFF 1110xxxx 10xxxxxx 10xxxxxx 3
U+10000 ~ U+10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 4

실습: '한'(U+D55C)을 UTF-8로 인코딩

1 코드 포인트 확인
'한' = U+D55C = 0xD55C = 54620₁₀
2 범위 확인
U+0800 ~ U+FFFF 범위 → 3바이트 필요
3 이진수 변환
0xD55C = 1101 0101 0101 1100₂
4 UTF-8 패턴에 배치
1110xxxx 10xxxxxx 10xxxxxx
11101101 10010101 10011100
5 최종 결과
0xED 95 9C = 11101101 10010101 10011100₂
UTF-8의 장점
• ASCII와 100% 호환 (영문은 그대로 1바이트)
• 자체 동기화 가능 (중간부터 읽어도 문자 경계 찾기 가능)
• 엔디안 문제 없음 (바이트 순서가 고정)

"Hello 안녕" 인코딩별 크기 비교

인코딩 바이트 수 16진수 표현
ASCII 불가능 한글 표현 불가
EUC-KR 9 48 65 6C 6C 6F 20 BE C8 B3 E7
UTF-8 12 48 65 6C 6C 6F 20 EC 95 88 EB 85 95
UTF-16LE 16 48 00 65 00 6C 00 6C 00 6F 00 20 00 48 C5 55 B1

2.3 부동소수점 연산의 오차와 주의사항

학습목표: 부동소수점 연산의 본질적 한계를 이해하고, 실제 프로그래밍에서 발생할 수 있는 문제를 예방하는 방법을 익힌다.

2.3.1 부동소수점 연산의 문제점

부동소수점 연산은 빠르고 넓은 범위를 표현할 수 있지만, 정확도 문제로 인해 예상치 못한 결과를 낳을 수 있다.

세 가지 주요 오차
1. 반올림 오차(Rounding Error): 유한한 비트로 무한소수 표현
2. 취소 오차(Cancellation Error): 비슷한 수의 뺄셈
3. 흡수 오차(Absorption Error): 크기가 매우 다른 수의 덧셈

반올림 오차 실습

// C 코드 예시
float sum = 0.0f;
for(int i = 0; i < 10; i++) {
    sum += 0.1f;
}
printf("%.20f\n", sum);
// 예상: 1.0
// 실제: 0.99999994039535522461

0.1을 10번 더해도 정확히 1.0이 되지 않는다! 각 연산마다 미세한 오차가 누적된다.

취소 오차 실습

예제: 1.000001 - 1.000000
정확한 값: 0.000001 (유효숫자 1개)
부동소수점 결과: 0.000001 (정밀도 손실 발생)

원래 6자리 유효숫자가 1자리로 줄어든다! 이를 치명적 취소(Catastrophic Cancellation)라 한다.

흡수 오차 실습

// 단정밀도 부동소수점
float big = 1e10f;    // 10,000,000,000
float small = 1.0f;   // 1
float result = big + small - big;
printf("%f\n", result);
// 예상: 1.0
// 실제: 0.0 (작은 수가 "흡수"됨)

2.3.2 프로그래밍 시 주의사항

부동소수점의 한계를 알고 적절한 대응 방법을 적용해야 안전한 프로그램을 만들 수 있다.

실수 비교의 올바른 방법

// ❌ 잘못된 방법
if(a == b) { ... }

// ✅ 올바른 방법
#define EPSILON 1e-6
if(fabs(a - b) < EPSILON) { ... }

// ✅ 더 정확한 방법 (상대 오차 고려)
if(fabs(a - b) < EPSILON * fmax(fabs(a), fabs(b))) { ... }
분야별 해결책
금융: 센트 단위 정수로 계산 (예: $12.34 → 1234)
게임: 고정소수점 사용 (예: 16.16 형식)
과학계산: 임의 정밀도 라이브러리 사용 (예: GMP, MPFR)

0.1 + 0.2 ≠ 0.3인 이유 (비트 수준 분석)

0.1₁₀ = 0.00011001100110011...₂ (무한 반복)
0.2₁₀ = 0.00110011001100110...₂ (무한 반복)

IEEE 754 단정밀도로 저장:
0.1 → 0x3DCCCCCD (실제: 0.10000000149011612)
0.2 → 0x3E4CCCCD (실제: 0.20000000298023224)
합  → 0x3E99999A (실제: 0.30000000447034836)

0.3 → 0x3E999999 (실제: 0.29999999403953552)

차이: 0.00000001043081284 ≠ 0
루프 카운터로 실수를 사용하지 마라!
// ❌ 위험한 코드
for(float i = 0.0; i < 1.0; i += 0.1) {
    // 10번이 아닌 9번만 실행될 수 있음!
}

// ✅ 안전한 코드
for(int i = 0; i < 10; i++) {
    float value = i * 0.1f;
    // 정수 카운터 사용
}

2.3.3 실제 사고 사례 분석

부동소수점 오차는 단순한 이론적 문제가 아니다. 실제로 인명 피해와 막대한 손실을 초래한 사례들이 있다.

🚀 패트리어트 미사일 실패 (1991년 2월 25일)

상황: 걸프전 중 사우디아라비아 다란

원인: 시스템 시계의 0.1초를 이진수로 변환 시 오차

  • 0.1초 = 0.0001100110011...₂ (무한 반복)
  • 24비트 레지스터: 0.00011001100110011001100 (잘림)
  • 오차: 0.000000095초/틱
  • 100시간 작동 후: 0.34초 오차 누적
  • 미사일 속도 1,676m/s × 0.34초 = 약 570m 빗나감

결과: 스커드 미사일 요격 실패, 28명 사망, 100명 부상

💻 펜티엄 FDIV 버그 (1994년)

문제: 특정 나눗셈에서 잘못된 결과

4195835.0 / 3145727.0 = ?
정답: 1.33382044913624100
펜티엄: 1.33373906890203759
오차: 0.00008138023420341

원인: 나눗셈 조견표(lookup table) 5개 항목 누락

영향: Intel 4.75억 달러 손실 (칩 교체 비용)

📈 주식거래 시스템 오류 사례

Knight Capital Group (2012년 8월 1일)

  • 부동소수점 가격 계산 오류
  • 45분 동안 잘못된 거래 실행
  • 손실: 4억 6천만 달러
  • 회사 파산 위기 (후에 인수됨)

교훈: 금융 시스템은 반드시 정수 연산 사용!

실무 개발자를 위한 체크리스트
✅ 금전 계산은 항상 정수로
✅ 실수 비교 시 epsilon 사용
✅ 루프 카운터는 정수만
✅ 중요 계산은 double 사용 고려
✅ 테스트 시 경계값 확인
✅ 오차 누적 가능성 항상 염두

요약 및 핵심 정리

Part 2에서 배운 내용을 정리하고, 실무에서 꼭 기억해야 할 핵심 사항을 확인한다.

핵심 개념 정리

주제 핵심 내용 주의사항
고정소수점 정수부.소수부 고정
빠른 연산
제한된 범위
오버플로우 주의
IEEE 754 S(1) + E(8/11) + M(23/52)
넓은 범위
정밀도 손실
특수값 처리
ASCII 7비트, 128문자
영문 중심
다국어 불가
확장 필요
UTF-8 가변 길이
ASCII 호환
한글 3바이트
처리 복잡
부동소수점 오차 반올림/취소/흡수
누적 위험
직접 비교 금지
epsilon 사용

프로그래밍 베스트 프랙티스

꼭 기억해야 할 10가지

  1. 실수를 == 로 비교하지 마라
  2. 금융 계산은 정수로 하라
  3. 루프 카운터는 정수만 사용하라
  4. 문자 인코딩을 명시하라
  5. 0.1 + 0.2 ≠ 0.3임을 기억하라
  6. NaN은 자기 자신과도 같지 않다
  7. 큰 수 + 작은 수는 위험하다
  8. UTF-8이 만능은 아니다
  9. 고정소수점도 고려하라
  10. 테스트 시 경계값을 확인하라

더 깊이 공부하기

추천 학습 자료
📚 "What Every Computer Scientist Should Know About Floating-Point Arithmetic" - David Goldberg
📚 "The Unicode Standard" - Unicode Consortium
🔧 IEEE 754 변환기: float.exposed
🔧 문자 인코딩 테스터: r12a.github.io/app-conversion/

'강의 > 컴퓨터 구조' 카테고리의 다른 글

데이터의 표현 - Part1  (0) 2025.09.19
컴퓨터 구조 개론 - Part 3  (1) 2025.09.12
컴퓨터 구조 개론 - Part 2  (0) 2025.09.12
컴퓨터 구조 개론 - Part 1  (0) 2025.09.12
    '강의/컴퓨터 구조' 카테고리의 다른 글
    • 데이터의 표현 - Part1
    • 컴퓨터 구조 개론 - Part 3
    • 컴퓨터 구조 개론 - Part 2
    • 컴퓨터 구조 개론 - Part 1
    ROONTAMS
    ROONTAMS

    티스토리툴바