ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • float형과 int형, 뭐가 다를까?
    궁금증/C++ 2019. 9. 4. 11:04

    코딩을 하다 보면 int형을 많이 사용하다가 소수점 연산에 있어서 float이나 double형을 사용하는 경우가 있다.

    int형의 경우 소수점 연산을 하면 값에 오차가 커지기 때문에 float형을 사용한다......(?)

     

    float형의 경우 int 형과 수의 표현 방식이 다르다.

     

     

    int형의 경우 000011110101.... 과 같은 2진수의 표현방법으로 이루어져 있는데

    (물론 부호표현이 들어가기 때문에 일반적인 2진수는 아니다.)

     

    float형의 경우는 수의 표현영역이 3 부분으로 나뉜다.

    부호를 표현하는 sign bit

    자릿수를 표현하는 exponent bit

    값을 표현하는 mantissa bit

     

    간단히 말해, 부호가 +냐 - 냐, 그래서 크기가 어느 정도냐, 그럼 값은 어느정도냐

    를 나눠서 표현을 하도록 되어 있다는 것이다.

     

     

    여기까지는 일반적으로 배우고 이해하고 납득하기 어렵지 않다.

     

    한 가지 궁금한 것이 있다면, 소수점은 정수보다 훨씬 많은데...(물론 맞는 100% 표현이 아니다. 하지만 0과 2 사이에는 정수가 1개 있고 소수의 경우 무한개가 있다고 생각해서,라고 심플하게 생각하자) 표현 방법이 다르든 어쨌든, 둘 다 bit를 사용해서 표현하고 심지어 사이즈마저 같다.(두 형 모두 4byte, *32bit 기준)

     

    사용할 수 있는 bit의 수가 같다는 것은 표현할 수 있는 경우의 수가 같다는 것이고, 그렇다면 위의 생각과는 약간의 충돌이 생길 수가 있다.

     

    내 카드가 100장이고 친구 카드도 100장인데, 50번째 카드를 낼 때만 해도, 나랑 같은 카드인 줄 알았더니

    나한테는 없는데 친구만 거의 정신 나간 것 마냥 계속 내는 마법의 카드를 가지고 있는, 마치 10000장이라도 가지고 있는 것 같은 느낌이다.

     

    예림이 그패봐봐

     

    실제로 당장 구글링만 해 보아도 int 형의 범위는 

    -2,147,483,648 ~ 2,147,438,647

     

    float형의 범위는

    3.4E-38(-3.4*10^38) ~ 3.4E+38(3.4*10^38) (7digits)

     

    float형만 어마어마한 큰 수와 어마어마하게 작은 수를 모두 표현할 수 있는 마법 같은 모습이다.

    하지만 계속 언급한 것처럼 둘 다 4byte인지라, 표현할 수 있는 경우의 수는 같다는 것이다.

     

    즉, 분포가 다르다.

     

     

    아래 코드를 한 번 보도록 하자.

    #include <iostream>
    using namespace std;
    
    int main() {
    	double a = 3.4E+20;
    	double b = 0;
    
    	double c = 3.4E+3;
    	double d = 0;
    
    	
    	b = a + 1;
    	d = c + 1;
    	
    	if (a == b)
    		cout << a << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" << b << endl;
    	else
    		cout << a << " " << b << endl;
    
    
    	if (c == d)
    		cout << c << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" << d << endl;
    	else
    		cout << c << " " << d << endl;
    
    
    	return 0;
    }
    

     

    심플하게, 엄청 큰 수와 보통의 크기의 수에 1을 더해봤더니,

    띠용

    엄청 큰 놈은 같다고 보고, 보통의 크기를 가진 수는 다르다는 걸 인식했다는 것이다.

     

     

    위와 같은 결과를 통해 유추할 수 있는 float 형의 분포는 다음과 같다.(물론~ 틀릴 수도 있다)

     

    부제 : 대략 어두운 복도의 끝에 보스가 기다리는 듯한 그림

    중심점에 가까울수록, 즉 0에서 일정 영역에 있는 수를 표현하는 것은 매우 정밀하게 되어 있지만, 그곳에 능력을 다 쏟아부었기 때문에 그 외의 영역에 대해서는 그만큼 정밀할 수가 없다는 것이다.

     

    위의 결과는 매우 큰 수가 되었을 경우 표현할 수 있는 수의 간격이 너무나도 크기 때문에, 1을 추가해도 그것을 bit로 표현할 방법이 없었고, 결국 그나마 가장 작은 오차를 가지는 bit를 대신해서 사용했고, 1을 추가했을 경우 가장 비슷한 bit는 방금 사용한 'a'의 bit였다는 이유로, 구분을 할 수 없었던 것이다.

     

     

    일반적으로 float형은 int형보다 정밀한가? 에 대한 질문에 쉽게 다수의 사람들이 '그렇다'라고 답변을 하게 되는데,

    이러한 큰 수를 다루는 경우까지 본다면 꼭 그렇다고 말할 수만은 없다.

     

    심지어 float형을 계산하기 위해서는 별도의 하드웨어(FPU [floating point unit])가 필요할 정도로 많은 연산을 요구하게 되는데, 그 결과가 이 꼴이라니...

     

     

    float형이 int형보다 정밀한 것은 아니고, 그렇다고 해서 int형이 float형보다 정밀한 것 또한 아니다.

    경우에 따라서 다르지만, 고연산의 float을 사용하고 case by case라는 것은... 

     

    가능하면 int 형을 사용하는 것이 성능에 큰 도움이 되지 않을까?

     

     

     

     

     

     

    틀린 점은 언제나 지적해주신다면 감사하겠습니다.

    의심이야 말로 발전의 원동력

    '궁금증 > C++' 카테고리의 다른 글

    randomized quick sort - 정말로 더 나은가?  (0) 2019.03.28
    C++ 배열의 선언에 관하여  (0) 2019.03.27

    댓글

Designed by Tistory.