IEEE-754 Floating-Point Conversion


N = ±1.Mantissa × 2±Exponent
       x  2^

■ 단정밀도 부동소수점 표현(32 bit) - Single Precision

S b31
Exponent(8)
b30 ... b23    
Mantissa(23)
b22 . . .                       . . . b0

 
   

Status
 

 ━► [H]
± +127=   [D]   [D]    
 

■ 배정밀도 부동소수점 표현(64 bit) - Double Precision

S
b63

Exponent(11)
b62 ...... b52    
 
Mantissa(52)
b51 . . .                                                                        . . . b0
 

=

[H]
Status
 

 
0/1: ± -1023 = [D]    [D]  

부동소수점(Floating-Point, 浮動小數點)[1] 방식은 실수를 표현할 때 소수점의 위치를 고정하지 않고 그 위치를 나타내는 수를 따로 적는 것으로, 유효숫자를 나타내는 가수(Mantissa , 假數)와 소수점의 위치를 풀이하는 지수(Exponent, 指數)로 나누어 표현한다.

컴퓨터에서는 고정 소수점 방식보다 넓은 범위의 수를 나타낼 수 있어 과학기술 계산에 많이 이용되지만, 근사값으로 표현되며[2] 고정 소수점 방식보다 연산 속도가 느리기 때문에 별도의 전용 연산 장치를 두는 경우가 많다. 고정 소수점과 달리 정수 부분과 소수 부분의 자릿수가 일정하지 않으나, 유효 숫자의 자릿수는 정해져 있다.


■ 원리

부동 소수점 표현 방식은 수를 (가수)×(밑수)(지수)와 같이 유효숫자를 사용한 곱셈 형태로 표현한다. 예를 들어, -0.4를  밑수가 10인 부동 소수점으로 나타내면 -0.04×101이 되며, 밑수가 2이면 -0.8×2-1가 되는데, 가수 부분을 한자리 자연수를 갖도록 바꾸면 -4×10-1과 같이 된다. 이처럼 가수의 첫째 자리가 밑수보다 작은 한자리 자연수가 되도록 바꾸는 것을 정규화라고 한다. 예를 들어, 앞의 값은 밑수가 2이면 -0.8×2-1이 되는데 이것을 정규화하면 1.6×2-2이 된다. (여기서 볼 수 있듯이 밑수가 2일 때 정규화하면 가수부분의 첫째 숫자는 항상 1이 된다.)

컴퓨터 프로그래밍-2를 이 방식으로 표현하면 '부호 +, 가수 60000, 지수 -002'가 된다. (가수 1.6에서 1이 생략되고, 유효숫자는 6자리까지 가능하게 된다.)

실제 컴퓨터에서는 보통 이진법을 사용하여 밑수를 2로 하고, 다음과 같이 세 부분의 값으로 실수를 나타낸다.

이때, 값을 먼저 이진수로 변환한 후에 정규화하고, 그것을 다시 정형화된 형식으로 표현한다. 먼저 부호는 1비트로 실수가 양수일 때는 0, 음수일 때는 1로 표현한다. 지수부에는 따로 부호 비트가 없기 때문에 음수 지수를 처리하기 위해 보통 바이어스 표현법을 사용한다. 즉, 할당된 자릿수로 표현 가능한 전체 영역을 반으로 나누어, 작은 영역에는 음수값 및 0, 큰 영역에는 양수값이 차례대로 1:1 대응되도록 한다. 예를 들어, 지수부를 8비트로 표현한다면 모두 256가지 수를 나타낼 수 있는데 이것을 반으로 나누어 음수 127개와 0, 양수 128개를 차례대로 대응시킨다. 따라서, 비트열 00000000은 지수 -127을 나타내고, 01111111은 지수 0, 11111111은 지수 128을 나타낸다. 일반적으로는 지수부가 n비트일 때 (2n / 2 - 1 = 2n-1 - 1)을 지수 값에 더하며 이것을 바이어스 상수라고 한다. (다만, 지수부의 모든 자리가 모두 0 또는 1인 경우는 각각 0 또는 무한대를 나타내는 등 종종 특수한 목적으로 예약되어 있다.) 가수부에서는 정규화 결과 유효숫자의 첫째 자리는 언제나 1이므로 표시하지 않고, 소수 부분만 표현한다.

예를 들어, 앞의 보기와 같이 실수값 -0.4을 16비트 부동소수점으로 처리하되, 가수부는 10비트, 지수부는 5비트라면, 먼저 값을 이진수로 변환하면 0.0110011001100110(2)이고, 정규화 결과는1.10011001100110(2)×2-2이므로, 가수는1.10011001100110(2), 지수는 -10(2)이 된다. 양수값이므로 부호부는 '0'이 되고, 지수는 5비트이므로 바이어스 상수는 25-1 - 1 = 15이다. 따라서, 지수부는 '01101'이 된다. 가수부는 소수 부분만 10비트로 나열하여 '1001100110'이 된다. 부호-지수-가수의 순서로 조합하여 16비트 0011011001100110를 얻는다.

■ 정확도 문제

부동 소수점으로 표현한 수가 실수를 정확히 표현하지 못하고 부동 소수점 연산 역시 실제 수학적 연산을 정확히 표현하지 못하는 것은 여러가지 문제를 낳는다.

예를 들어, 0.1과 0.01을 표현하지 못하므로 0.1의 제곱이 0.01이 되지도 않고 0.01과 가장 가까운 수가 되지도 않는다. 24비트 단정밀도 표현에서, 십진수 0.1은 지수 = -4; 가수 = 110011001100110011001101 이고 그 값은,

정확히 0.100000001490116119384765625 이다.

이 수를 다시 제곱하면,

정확히 0.010000000298023226097399174250313080847263336181640625 이다.

단정밀도 부동 소수점 (반올림 있는) 하드웨어에서 제곱을 한다면,

정확히 0.010000000707805156707763671875 이다.

하지만 0.01과 가장 가까운 표현 가능한 수는

정확히 0.009999999776482582092285156250 이다.

또한, π (및 π/2)를 표현하지 못하므로 tan(π/2)가 무한대의 값이 나오지 않으며 오버플로우(overflow)가 생기지도 않는다. 따라서 π/2를 정확히 표현하지 못하기 때문에 일반적인 부동소수점 하드웨어에서는 tan(π/2)를 계산하는 일이 불가능하다. C 언어에서 아래의 계산 결과는 16331239353195370.0 가 된다.

  double pi = 3.1415926535897932384626433832795;   double z = tan(pi/2.0);

단정밀도에서는 (tanf 함수를 이용하여), −22877332.0 라는 결과를 얻는다.

같은 이유로 sin(π)는 0이 되지 않고 배정밀도에서 약 0.1225×10^-15 또는 단정밀도에서 −0.8742×10^-7가 된다. [3]

부동소수점 덧셈과 곱셈은 모두 교환법칙 (a + b = b + a 이고 a × b = b × a)이 성립하지만, 꼭 결합법칙이 성립하지는 않는다. 즉, (a + b) + c 이 항상 a + (b + c) 과 같지는 않게 된다. 예를 들면 7자리 부동소수점(Float 7) 10진수 계산을 할 때:

1234.567 + 45.67846 = 1280.245                        1280.245 + 0.0004 = 1280.245 그러나  45.67846 + 0.0004 = 45.67886                      45.67886 + 1234.567 = 1280.246

또한 항상 분배법칙이 성립하지도 않는다. 즉, (a + b) × ca × c + b × c과 다를 수 있다:

1234.567 × 3.333333 = 4115.223 1.234567 × 3.333333 = 4.115223                        4115.223 + 4.115223 = 4119.338 그러나  1234.567 + 1.234567 = 1235.802                        1235.802 × 3.333333 = 4119.340

유효 숫자를 잃어버리는 문제 뿐만 아니라, π와 0.1를 정확하게 표현하지 못하는 문제와 다른 약간의 부정확성이 다음과 같은 현상을 일으킨다:

■ 규격

실제 사용되고 있는 부동 소수점 방식은 대부분 IEEE 754 표준을 따른다. 이 규격에서는 실수를 32비트로 처리하는 단정밀도(single precision)에서는 부호 1비트, 지수부 8비트, 가수부 23비트를 사용하며, 64비트로 처리하는 배정밀도(double precision)에서는 부호 1비트, 지수부 11비트, 가수부 52비트를 사용한다. 4배정도(quadruple precision)에서는 128비트로 부호 1비트, 지수부 15비트, 가수부 112비트를 사용한다.[4]

과거의 마이크로소프트 제품은 자체 규격인 MBF(Microsoft Binary Format)를 사용했다. 이 형식에서는 배정밀도에서 부호 1비트, 지수 8비트, 가수 55비트를 사용하여 상대적으로 표현 범위가 좁은 대신에 유효숫자가 많으므로 보다 정밀한 값을 표현할 수 있다. 다만 실제 연산 과정에서는 IEEE 754 규격은 80비트 연산을 수행하므로, 연산 자체는 IEEE 754가 정밀하다.

■ 주석

  1. 정보통신표준용어에 따른 표기. 순화용어는 "떠돌이 소수점"이다.
  2. 본래 이진법에서는 십진수 소수가 정확히 표현되지 않는다.
  3. 하지만 cos(π)는 정확히 −1이 된다. 도함수가 π 근처에서 0에 가까우므로, 인자의 부정확함이 −1 근처의 부동소수점 수들의 간격보다 훨씬 작아지고 따라서 반올림한 결과는 정확하게 나온다.
  4. 이 16바이트 규격은 IEEE 754 규격서에 직접 명시되어 있지는 않다.

■ 참고자료