메모리의 한계
컴퓨터는 RAM(Random Access Memory)이라는 물리적 저장장치에 프로그램을 저장한다.
RAM은 유한한 크기의 비트만 저장할 수 있기 때문에 때때로 부정확한 결과를 낸다.
부동소수점의 부정확성
실수 x를 y로 나누는 프로그램을 작성해보자.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
float x = get_float("x: ");
float y = get_float("y: ");
printf("x / y = %.50f\n", x / y);
}
소수점 50자리까지 출력하도록 하고, x에 1, y에 10을 입력하면 다음과 같은 결과가 나온다.

정확한 결과는 0.1이어야 하지만, float에서 저장 가능한 비트 수가 유한하기 때문에 부정확한 결과가 나온다.
정수 오버플로우
1부터 시작하여 2를 계속 곱하는 프로그램을 작성해보자.
c#include <stdio.h>
#include <unistd.h>
int main(void)
{
for (int i = 1; ; i *= 2)
{
printf("%i\n", i);
sleep(1);
}
}

int 타입이 저장할 수 있는 수를 넘으면 0이 출력된다.int는 32비트만 사용하므로 그 이상의 숫자는 저장할 수 없다. 10억을 넘어서면 앞으로 넘어갈 자리가 없어지는 것이다.
사례 1: Y2K
1999년에 큰 이슈가 되었던 Y2K 문제는 연도를 마지막 두 자리수로 저장했던 관습 때문에 발생했다. 새해가 오면 '99'에서 '00'으로 정수 오버플로우가 발생하여 2000년이 아닌 1900년으로 인식되는 문제였다.
세계는 수백만 달러를 투자하여 더 많은 메모리를 활용해 이를 해결했다. 통찰력 부족으로 발생한 현실적이고 값비싼 문제였다.
사례 2: 보잉 787
보잉 787은 구동 후 248일이 지나면 강제로 안전 모드로 진입하여 모든 전력을 잃는 문제가 있었다. 248일을 1/100초로 계산하면 약 2^32가 나오는데, 설계 시 사용한 변수보다 커져서 오버플로우가 발생했다.
보잉은 주기적으로 재가동하여 변수를 0으로 리셋하는 방식으로 해결했다.
위와 같은 사례들로 보아 다루는 데이터 값의 범위를 유의하며 프로그램을 작성하는 것이 중요하다는 것을 알 수 있다.
연습 문제
Q. Y2K와 보잉 787 같은 문제를 방지하려면 프로그램을 어떻게 설계해야 할까?
시스템의 장기적인 안정성과 신뢰성을 보장할 수 있도록 다음의 조건들을 잘 생각해야 한다.
- 적절한 데이터 타입 선택: 충분히 큰 범위의 값을 저장할 수 있는 타입 사용
- 미래 지향적 설계: 확장성과 유연성을 고려한 설계
- 정기적인 테스트: 시스템을 주기적으로 검토하여 잠재적 문제 사전 발견
- 경계 조건 검사: 데이터의 최댓값과 최솟값에 대한 명확한 검사
- 문서화: 설계 결정과 알려진 제한 사항 기록 및 공유
- 유연한 아키텍처: 필요 시 쉽게 업데이트하거나 확장 가능한 구조
'TIL' 카테고리의 다른 글
| [CS50] 디버깅 (0) | 2025.11.05 |
|---|---|
| [CS50] 컴파일링 (0) | 2025.11.05 |
| [CS50] C 언어 - 사용자 정의 함수와 중첩루프 (0) | 2025.11.05 |
| [CS50] C 언어 - 자료형과 연산자 (0) | 2025.11.05 |
| [CS50] C 언어 - 조건문과 루프 (0) | 2025.11.05 |
