포스트

고정 소수점과 부동 소수점, 오차 발생 이유

컴퓨터가 정수를 표현하는 방법은 2진수로 표현하기 때문에, 처음에 낯설더라도 배우고나면 어떻게 컴퓨터가 수를 표현하는지 이해할 수 있습니다.

하지만, 컴퓨터의 실수. 즉, 소수를 표현하는 방법은 이해하기 어려운 부분이 존재합니다.

컴퓨터는 실수를 두 가지 방법으로 표현 가능합니다.

고정 소수점과 부동 소수점이 그 방법입니다.

고정 소수점은 단순하고 빠르지만 큰 실수를 표현하기 어렵고, 부동 소수점은 큰 수를 표현할 수 있지만 연산이 복잡하고 특수한 경우를 처리해야 하는 복잡함이 있습니다.

대부분의 경우 부동 소수점을 사용하는데, 이 부동 소수점은 부호, 지수, 가수로 구성되며, IEEE 754 표준을 따르는 등, 다소 복잡하기 때문에, 배워도 어려운 경우가 있습니다.

고정 소수점 (fixed point)

고정 소수점 방식은 정수부소수부를 나누어 비트 수를 미리 정하고(고정) 실수를 표현합니다.

예를 들어 32비트에서 1비트는 부호비트, 15비트는 정수부, 16비트는 소수부로 사용될 수 있습니다.

구현이 단순한만큼 표현할 수 있는 범위가 적습니다.

  • 처음 1비트는 부호를 나타냅니다. 양수는 0, 음수는 1입니다.
  • 다음 절반(15비트)는 정수부를 나타냅니다.
  • 나머지(16비트)는 소수부를 나타냅니다.

고정 소수점.png

예를 들어 3.375의 경우에는 다음과 같은 결과가 나옵니다.

\[\begin{split}3.375_{(10)}&=2^{1}⋅1+2^{0}⋅1+2^{−1}⋅0+2^{−2}⋅1+2^{−3}⋅1\\&=11.011_{(2)}\end{split}\]

고정 소수점 결과.png

고정 소수점의 장단점

장점:

  • 부동 소수점에 비해 단순하고 속도가 빠릅니다.

단점:

  • 정수부와 소수부의 비트 수가 고정되어 있기 때문에 큰 실수를 표현하기 어렵습니다.

부동 소수점 (floating point)

부동 소수점의 부동은 ‘움직이지 않는다’라는 부동(不動)이 아니라, 떠서 움직이는 ‘부유하다’의 의미인 부동(浮動)입니다.

부동 소수점은 부호, 지수, 가수 세 부분으로 구성됩니다.

여기에서 가수소수점 아래의 숫자를 표현하고, 지수소수점의 위치를 제어합니다. 따라서 부동 소수점이라는 이름이 붙었습니다.

예를 들어, 3.37이라는 숫자를 10진수의 부동 소수점으로 표현해보겠습니다.

\[3.375=0.3375⋅10^{1}=0.03375⋅10^{2}=33.75⋅10^{-1}\]

위 예시에서 볼 수 있듯이, 지수부에 따라 소수점의 위치가 다르게 표현될 수 있습니다.

이러한 표현 방식은 굉장히 큰 수매우 작은 수를 동일한 형식으로 표현할 수 있게 해줍니다.

다시 돌아와서, 따라서 컴퓨터에서의 부동 소수점에도 부호, 지수부, 가수부가 나뉘어져 있고, 일반적으로 널리 쓰이는 표준은 IEEE 754 입니다.

  • 처음 1비트는 부호를 나타냅니다. 양수는 0, 음수는 1입니다.
  • 다음 8비트는 지수부를 나타냅니다. 정규화 과정에서 얻은 지수에 bias를 더한 값으로 채웁니다.
  • 나머지 23비트는 가수부를 나타냅니다. 소수 부분의 값으로 채웁니다.

부동 소수점.png

정규화

2진수의 정규화는 특히 부동 소수점 수를 표현할 때 중요한 개념입니다.

2진수에서의 정규화는 2진수를 이동시켜 정수 부분이 1이 되도록 하며, 이동한 만큼 지수를 증가시키거나 감소시키는 것입니다.
예를 들어, $1.1011_{(2)}⋅2^1$ 과 같은 형태로 만드는 것입니다.

지수 표현과 Bias 사용

지수를 표현하는데 있어서는 IEEE 754 기준으로 지수부에 Bias인 127을 더해서 표현합니다.

이 Bias를 사용하는 방식은 음수 지수와 양수 지수를 모두 표현하면서 부호 없는 정수로 취급할 수 있기 때문에, 두 수의 비교가 쉬워지고 특수한 값을 표현할 수 있게 됩니다.

Bias의 역할

  1. 정렬 용이성: Bias를 사용하면 지수 부분을 부호 없는 정수로 취급할 수 있으므로, 두 수의 대소 비교가 쉽습니다.
  2. 음수 지수 표현: 음수 지수를 표현할 수 있습니다. (127보다 크면 양수, 127보다 작으면 음수로 취급할 수 있습니다.)
  3. 특수 값 표현: 지수 부분이 모두 0이거나 모두 1인 특수한 경우를 나타낼 수 있기 때문에 무한대, NaN 등을 표현하는 데 사용할 수 있습니다.
  • 양수 지수: 지수가 양수인 경우, Bias를 더하면 지수 부분의 값이 127보다 크게 됩니다. 따라서 지수 부분의 제일 앞 비트는 1이 됩니다.
  • 음수 지수: 지수가 음수인 경우, Bias를 더하면 지수 부분의 값이 127보다 작게 됩니다. 따라서 지수 부분의 제일 앞 비트는 0이 됩니다.

지수 부분이 $00000000_{(2)}$ 거나, $11111111_{(2)}$ 인 경우는 특수한 값으로 표현되므로 실제 표현되는 지수의 범위는 -126부터 127까지입니다.
double의 경우에는 지수 부분은 11비트이고 Bias 값은 1023이므로 지수의 범위는 -1022부터 1023까지입니다.

변환 예제

예를 들어 3.375를 부동 소수점으로 표현하면,

  1. 정수 부분과 소수 부분을 2진수로 변환합니다.
    • 정수 부분: $3_{(10)}=11_{(2)}$
    • 소수 부분: $0.375_{(10)}=2^{−1}⋅0+2^{−2}⋅1+2^{−3}⋅1=0.011$
  2. 정규화를 수행합니다.
    • $11.011$을 정규화 하면, $1.1011·2^1$
  3. Bias를 사용해 지수를 계산합니다.
    • 지수는 1이며, 127을 더한 후 8비트로 표현하면, $1+127=128=10000000$

따라서, 다음과 같은 결과가 나오게 됩니다.

부동 소수점 결과.png

부동 소수점의 장단점

장점:

  • 부동 소수점은 고정 소수점에 비해 큰 수를 표현할 수 있습니다.

단점:

  • 부동 소수점의 위에서 보듯 연산이 복잡합니다. 더해서 특수한 경우(무한대, NaN)을 처리해야 하는 경우도 생깁니다.

소수점의 오차 발생 이유

소수점의 오차 발생 이유는 간단히 말해 컴퓨터가 표현하는 수가 2진수이기 때문입니다.

컴퓨터는 2진수를 사용해 숫자를 표현하는데, 소수를 나타내는 데에도 위에서 보듯이 $2^{(-1)}$과 같이 계산됩니다.

컴퓨터는 이런 방식의 수들을 합산하여 최대한 근사한 소수를 만들어 내게 됩니다.

즉, $2^{(-1)}=0.25$, $2^{(-2)}=0.125$ 와 같은 수들을 더해서 계산합니다.

따라서 $0.1$과 같은 수는 이진수로 무한 소수가 됩니다. 이로 인해 10진수를 2진수로 변환하는데 있어서 무한 소수 같은 오차가 발생하게 됩니다.

\[\begin{split} 0.1_{(10)} &= 2^{−4}⋅1+2^{−5}⋅1+2^{−8}⋅1+...\\&=0.0625+0.03125+0.00390625+...\\&= 0.00011001_{(2)} \end{split}\]

$2^{-3}=0.125$ 기 때문에 그 아래부터 계산이 되는데, 근접하기만 할 뿐 정확히 0.1이 나오지 않습니다.

이 기사는 저작권자의 CC BY-NC-ND 4.0 라이센스를 따릅니다.