본문 바로가기

프로그래밍/기타

IEEE745

int형과 float형은 둘 다 4바이트로 자료형의 크기가 같은데 실제로 표현될 수 있는 값은 왜 그렇게 큰 차이가 나는 것일까?

int, float 자료형의 bit구조를 알기전까지는 위와 같은 의문을 가진바가 있었다.

그 의문은 컴퓨터구조라는 과목을 배우면서 해결되었다.

더불어, 부동소수점 형이 의외로 신뢰할 수 없는 결과를 나을 수 있다는 것도..


int 형     -2,147,483,648  ~  2,147,483,647     ( 2-31 ~ 231-1 )

float형   3.4E-38 ~ 3.4E+38                   ( 3.4*10-38 ~ 3.4*1038 )


int형이 42억 남짓한 수를 표현할 수 있는 반면,

float형은 무려 0 이 38개나 붙는 어마어마한 수를 표현할 수 있다.

     ( 조 단위까지 가더라도 0 은 고작 12개일 뿐이다. )


위에서도 언급했다시피 똑같은 4바이트(32비트)로 표현가능한 수의 범위가 차이나는 이유는 무엇일까?

그 이유는 두 자료형을 구성하는 비트 구조가 다른데서 기인한다.


int형은 구조가 단순하다.

4바이트를 비트형태로 보면 아래와 같다.


 31  30 29 28 27 .......                                                     .........2  1  0 bit

1

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1


int형의 범위는 아래와 같이 구해진다.


    (1*231) + (1*230) + (1*229) + ...... + (1*21) + (1*20)


이와 같이 이진수 <-> 십진수 변환법과 똑기에 2-31 ~ 231-1 까지 표현가능하다.


하지만 float형은 다르다.


 31 30 29 28 .. 25 24 23  22 21 20 ......                                   .........2  1  0 bit

1

1 1 1 1 1 1 1 1 

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

부호   지수비트(8bit)                           유효자리비트(23bit)

비트


float 형의 범위는 아래와 같이 구해진다.


    (-1)부호비트 * (1 + 유효자리) * 2(지수-127)


부호비트 - 부호를 결정하는 비트

유효자리 - 소수점 이하의 수를 표현

지 수     - 2n 에서 n을 표현


부호비트(1bit) + 지수(8bit) + 유효자리(23bit)로 구성되어 있고, 이와같이 숫자를 표현하는 비트구조 자체가 서로 차이를 보임으로 인해 int형과 float형은 4byte 의 크기를 지니더라도 실제 표현가능한 값에는 상당한 차이가 있음을 알았다.

부동소수점에 대해 조금 더 알아보자.

더 큰 수를 표현할 수 있다고 해서 float형이 더 좋은 것일까?   그것은 아니다.

분명히 단점도 존재한다. 그것은 이전 글에서 언급한 정밀도의 한계를 가진다는 것이다.

int형은 있는 그대로의 비트를 보여주면 되기 때문에 100%의 정확도를 가지며, 그에 비해 float형은 아주 큰 수를 표현할 수 있지만 그 수가 유효자리비트로 표현할 수 있는 한계를 넘어가버리게 되면 근사치를 취하게 된다. 실제로 값을 짤라먹는다는 말이다.

컴퓨터의 계산은 100% 믿을 수 있어야 하는데 이처럼 그 값을 제대로 표현하지 못하게 되면 어찌 될까.

아주 큰 수에서 이러한 경우가 발생하기 때문에 보통은 신경 쓰지 않아도 되지만 그것조차 고려를 해야한다면

해결 방법으로는 double 형을 쓰는 것이 있다.


double         1.7E-308 ~ 1.7E+308         ( 1.7*10-308 ~ 1.7*10308 )

long double    3.4E-4932 ~ 3.4E+4932         ( 3.4*10-4932 ~ 1.7*104932 )


 31  30 29 28 .......       22 21 20   19 18 17 ....                        ......   2  1  0 bit

1

1 1 1 1 1 1 1 1 1 1 1

 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

부호   지수비트(11bit)                           유효자리비트(20bit)

비트


1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

                           유효자리비트(30bit)


double형은 8바이트(64비트)로 표현하기 때문에 float보다 훨씬 크며, 유효자리비트 또한 커서 정밀도 역시 높아지게 된다. 그렇다면 많은 비트를 할당해서 더 큰 수와 더 정확한 정밀도를 제공한다고 해서 float형에서 발생했던 오류가 사라지는 것인가?


아니다.  여전히 존재한다.  단지, 그러한 경우가 발생할 확률이 줄어들도록 더욱 더 많은 비트를 할당 할 뿐...


다만, 이러한 경우가 발생할 것을 예측하여, 프로그래머가 예방하는 길만이 최선의 방법일 것이다.

알아두자. 아주 크거나 아주 작은 부동소수점 수는 무조건 믿으면 안된다는 것을...

지금까지 언급한 내용은 IEEE745 표준에서 나온 것으로 부동소수점 연산을 하는 기계에서 다루어지는 부분이다.

 float, double, long double 의 값들은 특정한 기계에 대한 것이며 기계에 따라 다를 수 있다. < C++을 이용한 프로그래밍, 사이텍미디어 >