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


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

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


조회수 452


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
  • 2016년 05월 30일에 수정됨
    시원한 날만 일하자
  • 2016년 05월 30일에 작성됨
    시원한 날만 일하자


-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 ...) 에 따라서, 메모리에 접근횟수가 달라짐으로, 우리가 사용하는 알고리즘(혹은 프로그램)에서는 생각보다 큰 차이를 보이지 않을 수도 있기 때문에, 상황에 따라 달라질 것 같습니다.

  • 2016년 05월 30일에 작성됨
    리눅스(유닉스) 기반의 시스템에서 웹 서비스를 개발하고 있습니다.

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close