내용 재검토 필요

실수형에 대한 오해: ‘정밀하다’는 말의 함정 (C언어 코드 예시)

프로그래밍을 하다 보면 int (정수형)float/double (실수형) 자료형을 자주 사용하게 됩니다.

많은 분들이 실수형, 특히 double 자료형을 “정밀한(Precise) 수를 표현하는 데 특화된 자료형”이라고 알고 계십니다. 그게 바로 접니다. 😊

사실 이는 반은 맞고 반은 틀린 이야기인데요, 이번 포스팅에서는 실수형이 어떻게 숫자를 저장하는지, 그리고 우리가 흔히 알고 있는 정수형(int) 역시 특정 상황에서는 정밀도를 포기할 수밖에 없다는 점을 C언어 예시 코드를 통해 알아보겠습니다.


정수형과 실수형의 정밀도 문제

정수형(int)의 정밀도 문제

우리가 흔히 ‘정밀하다’고 생각하는 int 자료형은 사실 표현할 수 있는 수의 범위가 제한적입니다. 32비트 시스템 기준으로 int는 약 -21억에서 +21억까지의 정수만을 표현할 수 있습니다. 이 범위를 넘어서는 큰 수를 표현하려고 하면 오버플로우(Overflow)가 발생하여 정밀도를 잃게 됩니다.

실수형(float / double)의 정밀도 문제

반면, 실수형(double)은 훨씬 넓은 범위의 수를 표현할 수 있지만, 그 대가로 ‘유효 숫자(Significant Figures)’라는 개념 하에서 정밀도를 관리합니다. double은 유효 숫자(소수점 이하가 아닌 전체) 약 15~17자리를 정밀하게 표현하지만, 그 이상은 오차가 발생할 수 있습니다.


유효 숫자

정의

유효 숫자는 컴퓨터가 오차 없이 ‘정확하게’ 표현할 수 있다고 보장하는 최대 십진수 자릿수를 의미합니다.

C 자료형 크기 (비트) 가수부 비트 (이진수 정밀도) 보장되는 유효 숫자 (십진수)
float 32 비트 23 비트 (약 $2^{24}$) 6~7 자리
double 64 비트 52 비트 (약 $2^{53}$) 15~17 자리

예시

float 변수에 1.23456789를 저장하면, 7자리인 1.234568 (마지막에서 반올림)까지만 의미 있는 값으로 저장되고, 그 이상의 숫자는 손실되거나 오차로 처리됩니다.

실수 자료형에서의 유효 숫자

실수 자료형의 구조

C 언어의 실수형은 수를 부동 소수점(Floating-Point) 방식으로 저장하며, 이는 국제 표준인 IEEE 754를 따릅니다. 이 방식은 하나의 숫자를 세 부분으로 나누어 저장함으로써 넓은 범위의 수와 정밀도를 동시에 관리합니다.

특징 float (단정밀도) double (배정밀도)
총 비트 수 32 비트 64 비트
지수부 비트 8 비트 11 비트
가수부 비트 23 비트 52 비트
유효 숫자 (십진수) 약 6~7 자리 약 15~17 자리
주요 차이점 지수부와 가수부의 비트 수가 적어 표현 범위가 좁고 정밀도가 낮습니다. 지수부와 가수부의 비트 수가 많아 표현 범위가 넓고 정밀도가 높습니다.

유효 숫자의 저장

  • 유효 숫자에 해당하는 실제 값은 가수부 비트에 저장됩니다. 이 가수부가 길수록(비트가 많을수록) 숫자를 이진수로 표현할 때 더 많은 자릿수를 담을 수 있으므로 유효 숫자가 늘어나고 정밀도가 높아집니다.
  • double이 float보다 가수부 비트가 훨씬 많기 때문에 더 높은 정밀도(더 많은 유효 숫자)를 가집니다.

정규화와 손실

컴퓨터는 숫자를 저장할 때 항상 정규화(Normalization) 과정을 거칩니다.

모든 이진 부동 소수점 숫자는 1.xxxx... 형태로 표현되며, 이 때 맨 앞의 ‘1’은 생략하고 소수점 아래의 xxxx... 부분만 가수부에 저장합니다.

문제는 일부 십진수 (예: 0.1, 0.2)가 이진수로 변환될 때 무한 소수가 된다는 점입니다. 메모리는 유한하므로, 컴퓨터는 이 무한 소수를 가수부 비트의 끝에서 강제로 잘라내고 반올림하여 저장합니다.

이 ‘잘라냄(Truncation)’ 또는 ‘반올림(Rounding)’ 과정에서 바로 오차(Error)가 발생하며, 이 오차가 유효 숫자를 벗어난 부분에서 나타나는 비정밀성의 주된 원인이 됩니다. 유효 숫자 개수 이내의 자리는 정확하게 보장되지만, 그 이후의 자리는 오차로 인해 신뢰할 수 없습니다.

Comments