리메이크 중/C,C++ 이론 중심

C(&C++) 이론 10. 부동 소수점 표현 방식에 대한 국제 표준 IEEE-754

라이피 (Lypi) 2021. 5. 27. 19:00
반응형

목록용 썸네일 이미지


내용 참고

Microsoft Docs (구 MSDN)

영문 wikipedia


C언어 이론 10 / IEEE-754

■ C와 C++ 및 많은 언어에서 따르고 있는 국제 표준인 IEEE-754에서 실수를 표현하는 방법을 설명한 글이다.


Ⅰ. IEEE-754와 C 및 C++의 관계

ⅰ. IEEE-754에 정의된 형식

■ 국제 표준인 IEEE-754에는 2진법에 관한 표준 3가지와 10진법에 관한 표준 2가지가 기본으로 정의되어 있다.

■ 아래의 표는 2진법과 관련된 3가지 기본 형식과 2가지 파생 형식을 나타낸 표이다. (10진법에 관한 기본 형식 2가지는 생략했다.)

 

ⅱ. 실제 구현

■ IEEE-754를 따르는 구현이라면 5가지 기본 형식 중 하나 이상을 완전하게 구현해야한다.

■ 이에 따라 C 및 C++에서는 float를 binary32 형식으로, double과 long double을 binary64형식으로 구현해 두었다.

Ⅱ. IEEE-754에서 수를 표현하는 방법

ⅰ. 정규화될 수 있는 수

■ IEEE-754에서 정의한 2진법 기반 형식은 수를 정규화하여 (-1)^s * 2^E * M로 표현하며, 부호비트, 지수, 가수의 순서로 저장한다.

■ 위 식에서 s는 sign(부호)를, E는 Exponent(지수)를, M은 Mantissa(가수)를 의미한다.

■ 가수는 유효하게 표현된 수라는 의미에서 유효숫자(significant)나 분수(Fraction)이라고도 한다.

■ 지수부에 실제로 비트로 저장되는 값은 E(실제지수)+bias값이다.

■ 예를들어 binary32의 bias값은 127(011111112)이므로 E(실제 지수)가 0이라면 지수부에는 127(011111112)가 저장된다.

■ 지수부에 저장될 수 있는 최소값인 0...02과 최대값인 1...12은 정규화되지 않는 수를 표현하기 위해서 예약되어 있다.

■ 그러므로 정규화된 값에서 지수부에 저장될 수 있는 최소값은 0...012(-126)이고, 최대값은 1...102(127)이다. 

■ 정규화된 값에서 유효숫자인 M의 제일 좌측값은 항상 1이므로 가수부에 저장할 때는 이 1을 생략한다.

■ 예를 들어 유효숫자가 1.00010011 이라면 가수부에는 오른쪽 비트부터 00010011이 저장되고 남은 비트는 0으로 채워진다.

ⅱ. 정규화될 수 있는 수의 범위

■ 정규화할 수 있는 수를 시각화해보기 위해서 임의의 6비트 메모리 형식를 가정해보자.

■ 이 형식은 MSB(최상위비트)를 부호비트로 하고, 3비트를 지수부(bias는 3), 2비트를 가수부로 쓴다고 가정한다.

■ 그러면 이 형식으로 나타낼 수 있는 최대값은 부호비트 0(+), 지수부 110 (111을 특수값을 나타내므로), 가수부 11이다.

■ 이를 계산하면 23*1.112 = 11102 = 14이다. 즉 이 형식으로 정규화하여 표현할 수 있는 값의 최대치는 14가 된다.

■ 같은 방식으로 정규화하여 표현할 수 있는 양의 최소값을 구해보면 000100 = 2-2*1.02 = 0.012 = ¼이 된다.

■ 이 형식으로 나타낼 수 있는 모든 실수값을 이미지로 표현하면 다음과 같다. 

■ 정규식 -1s × 2E × M은 E에 대한 지수함수의 꼴이므로 E의 값이 작을 때는 값이 촘촘하다. 

■ 그림상으로는 듬성듬성 공백이 많아 보이지만 이는 6비트라는 최소의 값으로 표현했기 때문이다.

■ 메모리를 적게 쓰는 float형도 32비트이므로 그림으로 표현하면 훨씬 더 촘촘하게 수직선을 매꿀 것이다.

■ 하지만 그럼에도 실수의 개수는 무한하기 때문에 유한한 메모리로는 모든 실수를 표현할 수 없으며 오차가 생길 수 밖에 없다.

■ 또한 정규식의 M은 1.XXX의 값을 갖기 때문에 0을 나타낼 수 없으며, 0 주변의 매우 작은 실수도 표현할 수 없다.

■ 정규화된 식으로 표현할 수 없는 범위는 float형은 ±1/(2126), double형은 ±1/(21022)이다.

 

ⅲ. 정규화되지 않은 수

■ 정규화 식으로는 0과 0 주변의 매우 작은 실수들도 표현할 수 없다.

■ 그래서 IEEE-754 표준에서는 '정규화되지 않은 수'라는 것을 도입해서 0과 그 주변의 값을 표현한다.

■ 정규화되지 않은 수는 지수부의 비트가 모두 0인 수로 가수부의 값을 0.X...X의 형식으로 해석하며, 지수는 -(bias-1)의 값을 갖는다.

■ 위에서 정의한 6비트 형식으로 정규화되지 않은 수를 시각화하면 다음과 같다.

■ 이 방식으로는 0을 표현할 수 있지만 부호에 따라 +0과 -0의 2가지가 0이 생긴다는 문제가 있다.

■ 즉, 같은 0값을 비교하는데 같지 않다는 결과가 나올 수도 있는 것이다. 그래서 IEEE-754 표준에서는 -0=+0으로 정의하고 있다.

■ IEEE-754 표준에서 부호있는 0을 내버려둔 이유는 계산상의 오차로 인해 0에 매우 가까운 값이 0으로 표현될 수도 있기 때문이다.

 

ⅳ. 그외 특수값 (NaN과 무한(∞))

■ IEEE-754표준은 위의 두가지 경우외에도 특수한 값을 2가지 더 정의하고 있는데 그것이 NaN(Not a Number)과 무한이다.

■ NaN은 또한 Quiet NaN(qNaN)과 Signaling NaN(sNaN)으로 나뉜다.

1. Quiet NaN

■ qNaN은 잘못된 연산으로 인해 계산하지 못했음을 나타내며, 예외를 발생시키지 않고 qNaN을 반환하여 연산을 지속시킨다.

■ qNaN은 부호에 상관없이, 지수부와 가수부 모두 1로 채워서 표시한다.

■ qNaN이 발생하는 대표적인 상황은 다음과 같다.

2. Signaling NaN

■ sNaN은 피연산자로 사용될 시 예외를 발생시키는 값이다. 

■ sNaN은 부호에 상관없이, 지수부는 모두 1로 채우고, 가수부의 대부분의 비트를 0으로, 최소1개의 비트를 1로 채워서 나타낸다.

■ sNaN은 일반 연산의 결과로는 발생하지 않는다.

3. Infinit (무한대 : ∞)

■ ∞는 계산 결과가 표현 가능한 수의 범위를 벗어나 오버플로우가 발생했음을 의미한다.

■ ∞는 지수부의 모든 비트를 1로 채우고, 가수부의 모든 비트를 0으로 채워서 나타내며, 부호비트에 따라 +∞와 -∞로 나뉜다.

■ 0이 아닌 x값을 실수 0으로 나눌 경우 x값의 부호에 따라 +∞나 -∞가 반환된다.


 

반응형