C++ 실수 연산, 정수연산 속도 차이

C++ 에서 같은 알고리즘을 사용할 경우 연산이 실수형 연산이냐 정수형 연산이냐에 따라 유의미한 차이를 보이나요?

예를 들어 1억번 loop안에서 원의 넓이를 구할 때 반지름이 실수가 가능하냐 아니면 정수만으로 제한 하냐 정도의 수준에서요

2답변

  • stackoverflow에 같은 질문이 있네요. 전처리기에 따라 조금씩 다르다고 합니다.

    제 경우엔 4294967295번 실행했을 때, int연산이 2초정도 더 빨랐습니다.

    #include<iostream>
    #include<cmath>
    #include<ctime>
    #include<limits>
    
    using namespace std;
    const unsigned long max_count = numeric_limits<unsigned int>::max();
    
    int calc_int(int radius){
        return (0.5*radius*radius*M_PI);
    }
    
    float calc_float(float radius){
        return (0.5*radius*radius*M_PI);
    }
    
    
    double calc_double(double radius){
        return (0.5*radius*radius*M_PI);
    }
    
    int main(void){
        cout << "반복 횟수는 " << max_count << " 입니다." << endl;;
        clock_t start, end;
    
        // double형
        start = clock();
        double double_num = 0.0;
        for(long i=0; i<max_count; i++, double_num++)
            calc_int(double_num);
        end = clock();
        cout<<"double형 수행시간 : "<<((end-start)/CLOCKS_PER_SEC)<<endl;
    
    
        // float형
        start = clock();
        float float_num = 0.0;
        for(long i=0; i<max_count; i++, float_num++)
            calc_int(float_num);
        end = clock();
        cout<<"float형 수행시간 : "<<((end-start)/CLOCKS_PER_SEC)<<endl;
    
    
        // int형
        start = clock();
        int int_num = 0;
        for(long i=0; i<max_count; i++, int_num++){
            calc_int(int_num);
        }
        end = clock();
        cout<<"int형 수행시간 : "<<((end-start)/CLOCKS_PER_SEC)<<endl;
    
    }
    
    반복 횟수는 4294967295 입니다.
    double형 수행시간 : 17
    float형 수행시간 : 17
    int형 수행시간 : 14
    
    • (•́ ✖ •̀)
      알 수 없는 사용자
    • (•́ ✖ •̀)
      알 수 없는 사용자
  • -1. 정확한 계산을 생각하신다면 정수형으로 해야합니다.

    -2. 실수형은 컴퓨터의 특성상 이진으로 처리하기 때문에 연산을 거듭할 수록 오차가 누적됩니다.

    #include <stdio.h>
    int main(){
        float a = 0.0001,b=0;
        int i;
        for(i=0;i<1000;i++) {
            b = b + a;
        }
        printf("b = %e",b);
        printf("b = %f",b);
        return 0;
    }
    

    위 예를 보면, float의 경우 유효자리를 표현하기 위한 bit수가 매우 적어 더 극명하게 잘 보여줍니다. 0.0001을 1000번 더하면 0.1이 되어야 하지만, 위를 돌려보면 0.1이 되지 않는 걸 알 수 있습니다.

    -3. 의미적으로 실수를 사용해야만 하고, 정확도를 요구한다면 double 형을 써야합니다. 이 경우에도 어떤 계산의 결과를 기대할 때, 유효자리를 산정하여 맞는지 검사해야 합니다. 예를 들어 어떤 실수 연산 결과가 소수점 이하 5자리까지만 맞는지 검사한다는 식의 코드를 작성해야 합니다.

    -4. 위 2,3과 같은 이유로, 실수는 정확한 카운트를 해야하는 (ex. for loop의 count 변수) 경우에는 사용하지 말아야합니다.

    -5. 속도는 기본적으로 우리가 사용하는 컴퓨터의 하드웨어에서 같은 장치 안에 포함된 기능을 사용한다면, 정수형 계산이 실수형 계산보다 빠릅니다. 실제로는 부동소수(실수) 계산을 위한 하드웨어(예: GPU)들은 때때로 더 빠른 성능을 내기도 함으로, 어떤 하드웨어를 사용하느냐 달려있다고 볼 수 있습니다. 비단 이 뿐만 아니라 데이터 사이즈(16bit, 32bit, 64bit ...) 에 따라서, 메모리에 접근횟수가 달라짐으로, 우리가 사용하는 알고리즘(혹은 프로그램)에서는 생각보다 큰 차이를 보이지 않을 수도 있기 때문에, 상황에 따라 달라질 것 같습니다.

ᕕ( ᐛ )ᕗ
로그인이 필요합니다

작성한 답변에 다른 개발자들이 댓글을 작성하거나 댓글에 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.