본문 바로가기
개발

소프트웨어에서 정수가 아닌 실수를 다루는 법

by owel.dev 2025. 3. 16.

컴퓨터는 데이터를 이진수 체계를 이용해 0과 1로 저장합니다. 정수를 저장할 경우 해당 정수를 이진수로 변환한 후 이를 메모리에 저장합니다. 10진수 정수를 우측부터 2^0, 2^1, 2^2... 에 해당하는 수로 변환하는 정수-이진수 변환은 비교적 간단합니다.

125를 이진수로 변환

 

그런데 소수부가 포함된 125.275 같은 정수가 아닌 실수를 이진수로 변환하려면 어떻게 해야 할까요? 아무래도 정수의 이진수 변환과는 다른 규칙이 필요해 보입니다. 그리고 25.23423112342343243232444... 같은 긴 실수를 변환해야 할 경우를 생각해 보면, 두 실수 사이에는 무수히 많은 실수가 존재한다는 특성상 이를 유한한 비트로 나타내기는 쉽지 않아 보입니다. 그럼에도 불구하고 많은 소프트웨어에서 정수가 아닌 실수를 다뤄야 할 필요성이 있었기에, 정수가 아닌 실수를 이진수로 표현하기 위한 방법들이 개발되었습니다.

 

현재 널리 사용되는 실수 표현 방식에는 고정소수점(Fixed-point)과 부동소수점(Floating-point) 두 가지가 있습니다. 오늘은 각 방식의 원리와 장단점, 적합한 사용 사례에 대해 살펴보도록 하겠습니다.

 

고정 소수점 방식 (Fixed-point)

고정 소수점 방식은 실수를 이진수로 변환할 때 정수부분과 소수 부분을 각각 별도의 정수를 저장하듯 저장하는 방식입니다.

컴퓨터에서 실수를 다루기 위해 부동소수점 방식보다 먼저 사용되던 방식으로, 원래 고정소수점이라는 이름으로 부르지는 않았지만, 부동소수점 방식이 등장한 이후 두 가지 방식을 구분하기 위해 그러한 이름으로 부르게 되었습니다.

고정 소수점 표현 방식 중 가장 널리 사용되는 방법은 Q표기법이 있습니다. 아래의 설명들은 Q표기법의 Q8.8 형식(정수 부분에 8비트, 소수 부분에 8비트, 총 16비트사용)을 기준으로 설명하였습니다.

 

고정소수점 수 변환 과정

1) 정수 부분과 소수 부분을 각각 정수 변환 규칙을 사용하여 이진수로 변환.

 

2) 두 이진수를 결합하여 16비트 저장공간에 저장

 

고정 소수점 방식의 장점

  • 정확한 표현: 소수 부분을 정수를 저장하듯 저장하기에 지정된 크기 내에서는 정확한 값을 유지할 수 있습니다.
  • 구현 간단: 정수의 저장 방식과 연산방식을 그대로 사용하기에 직관적이고 구현하기 쉽습니다.

고정소수점 방식의 단점

  • 유연성 부족: 정수부와 소수부의 저장 공간의 크기를 미리 결정해야 하므로, 정해진 크기보다 작은 수가 들어온다면 저장공간이 낭비되고, 정해진 크기보다 큰 수가 들어온다면 값이 넘쳐 손실이 일어나므로 초기에 저장 공간의 크기를 잘 설정해야 하며, 앞서 말한 작거나 큰 예외적이 값들에 대해서는 효율적인 대응이 어렵습니다.
  • 하드웨어 미지원: 과거에는 연산 시 정수의 연산 체계를 그대로 사용하기에 빠른 연산 속도가 장점이었지만, 현대 CPU에는 부동 소수점 연산을 빠르게 처리하는 FPU(Floating Point Unit)가 내장되어 있어 상대적으로 고정 소수점 방식이 느려졌습니다.

 

부동 소수점 (Floating Point) 방식

부동소수점 방식은 실수를 부호(sign), 지수(exponent), 가수(fraction)의 세 가지 구성 요소로 나누어 저장하는 방법입니다. 가장 널리 사용되는 IEEE 754 표준의 단정밀도 부동소수점 표현 방식(32비트 사용)을 기준으로 설명하겠습니다.

 

단정밀도 부동소수점 수 표현에 쓰이는 비트

  • 부호(sign): 1비트를 사용하여 양수인지 음수인지를 표현.
    • 양수면 0, 음수면 1 저장.
  • 지수부(exponent): 8비트를 사용하여 가수부의 수에서 소수점이 어느 위치에 존재하는지를 표현.
    • 0부터 255까지의 값 저장이 가능하며, 0과 255는 특수값을 위해 예약되어 있음.
    • 1부터 254까지의 값으로 -126 ~ 127까지의 지수 값을 표현. 그를 위해  실제 값에 127을 더하여 저장하는 방법을 사용 ( -126은 1로 저장, 127은 254로 저장).
    • 이 127을 bias라고 부름.
  • 가수부(fraction): 23비트를 사용하여 실수를 이진수로 변환 후 정규화한 값을 저장 (자세한 내용은 아래에서 설명)

부동소수점 수 변환 과정

-125.625를 부동소수점 수로 변환하여 메모리에 저장하는 과정에 대해 알아보겠습니다.

 

1) 부호 비트 저장

-125.625는 음수이므로 맨 앞 부호비트에 1을 저장합니다.

부호 비트 저장

2) 이진수 변환

부호를 제외한 125.625를 이진수로 변환합니다. 다만, 정수부와 소수부를 별도의 규칙으로 변환합니다. (소수부는 왼쪽부터 2의 -1승, 그 다음 2의 -2승... 과 같은 규칙으로 변환)

 

2) 정규화 및 가수부 세팅

변환한 이진수 1111101.101의 소수점을 맨 앞 1 다음 자리로 옮겨  1.111101101을 만듭니다. 

 

이후, 맨 앞 1을 제외한 나머지 111101101를 가수부에 저장합니다. 이 맨 앞의 1은 정규화 과정에서 항상 존재하는 것이 보장되는 값으로(맨 앞 1 다음으로 소수점을 옮기기에) 암묵적으로 간주되므로 저장할 필요가 없습니다(이를 "hidden bit"라고 함). 가수부의 제일 왼쪽부터 111101101을 채우고, 나머지 빈 공간은 0으로 채웁니다.

 

3) 지수부 세팅

정규화 과정에서 소수점이 이동한 자릿수 6에 127(bias)을 더한 값 133을 이진수로 변환한 10000101을 지수부에 저장합니다.

부동 소수점 방식의 장점

  • 넓은 표현 범위: 같은 비트 수로 고정 소수점 방식보다 훨씬 넓은 범위의 숫자를 표현할 수 있습니다.
    실수 전체를 이진수로 변환하여 가수부에 저장한 후, 소수점의 위치를 지수부에 저장하기 때문에 소수점의 위치를 유연하게 지정할 수 있습니다.(부동 = 소수점이 둥둥 떠다님) 그렇기에 정수와 소수 각각의 저장에 사용되는 비트를 고정할 필요가 없으므로, 가수부의 공간에 정수가 작을 경우 소수 저장에 더 많은 비트를 사용할 수 있고, 소수가 작을 경우 정수 저장에 더 많은 비트를 사용할 수 있습니다.
  • 하드웨어 지원: 현대 CPU에는 부동소수점 연산을 빠르게 처리하는 전용 회로(FPU, Floating Point Unit)가 내장되어 있어 빠른 연산이 가능합니다.

부동 소수점 방식의 단점

  • 정밀도 손실: 특정 실수(예: 0.2, 0.3)는 이진 부동소수점으로 정확히 표현할 수 없어(0.2는 이진수로 0.00110011001100... ... 와 같이 무한히 반복되는 형태가 됨) 근삿값으로 저장됩니다.
  • 오차 누적: 반복적인 연산 과정에서 작은 오차가 누적되면 예상과 다른 결과를 초래할 수 있습니다.
  • 특별한 값 처리: NaN(Not a Number), 무한대 등 특별한 값을 처리하기 위한 추가적인 로직이 필요합니다.

 

각 방식의 적합한 사용 사례

고정 소수점 방식이 적합한 사례

고정 소수점 방식은 금융이나 회계 분야처럼 미세한 오차조차 허용되지 않는 분야에 적합합니다. 예를 들어 은행의 입출금 시스템, 주식 거래 시스템, 암호화폐 거래소 등에서는 정확한 금액 기록과 계산이 중요하기 때문에 오차가 없는 고정 소수점 방식을 사용하여 데이터를 관리합니다.

부동 소수점 방식이 적합한 사례

부동 소수점 방식은 정밀도를 조금 희생하더라도 넓은 숫자 범위를 빠르게 계산해야 하는 분야에 적합합니다. 물리 시뮬레이션, 날씨 예측, 우주 항공 기술, 그래픽 처리(3D 렌더링), 머신러닝과 인공지능 알고리즘 등에서 빠르고 효율적인 데이터 처리를 위해 부동 소수점 연산을 활용합니다. 이러한 분야에서는 작은 오차는 허용할 수 있으며, 오히려 넓은 범위의 숫자 표현과 빠른 연산 속도가 중요하기 때문입니다.