2014-11-06 3 views
0

double 값을 취할 수있는 특정 변수가 실제로 정수 값을 가져 왔는지 확인해야하는 코드를 작성하고 있습니다. 이중 변수가 정수의 허용 오차 내에 있으면 정수 값을 취한다고 생각합니다. 이 공차는 1e-5입니다. 전달 된 double 인수가 "close enough"인지 확인하여 정수로 간주합니다.

다음

내 코드입니다 :

#define SMALL 1e-5 
//Double that attains this is considered non zero. Strictly Less than this is 0 

int check_if_integer(double arg){ 
//returns 1 if arg is close enough to an integer 
//returns 0 otherwise 
    if(arg - (int)arg >= SMALL){ 
     if(arg + SMALL > (int)(arg+1.0)){ 
      return(1); 
//Code should have reached this point since 
//arg + SMALL is 16.00001 
//while (int)(arg+1.0) should be 16 
//But the code seems to evaluate (int)(arg+1.0) to be 17 
     } 
    } 
    else{ 
     return(1); 
    } 
    return(0); 
} 

int main(void){ 

    int a = check_if_integer(15.999999999999998); 

} 

불행하게도, 인수 15.999999999999998 전달에, 함수 인 0을 반환, 그것이 나타내는 1을 반환해야하지만, 소수로 인수하다고 판단 그 인수는 "16에 충분히 가깝습니다."

저는 VS2010 전문가를 사용하고 있습니다.

모든 포인터가 크게 감사하겠습니다!

답변

2

예, 부동 소수점은 어렵습니다. 단지 15.999999999999998 < 16.0이므로 15.999999999999998 + 1.0 < 17.0이 아닙니다. 정밀도가 3 자리 인 10 진 부동 소수점 유형이 있다고 가정합니다. 그 유형의 정밀도에서 9.99 + 1.0에 대한 결과는 무엇입니까? 수학적 결과는 10.99이고, 해당 유형의 정밀도로 반올림하면 11.0이됩니다. 이진 부동 소수점에도 동일한 문제가 있습니다.

이 특별한 경우에는 (int)(arg+1.0)에서 (int)arg+1으로 변경할 수 있습니다. (int)arg은 정확하고 정수 또한 추가됩니다.

+0

귀하의 제안을 내 경우에 작동하고 내가 가지고있는 현재의 코드에 맞는. – Tryer

2

유형에 관한 hvd의 대답에 더 가깝습니다. 그들도 내부적으로 표현되는 방식 때문에 큰 복식에 작은 복식을 더하거나 빼는 것은 권하지 않습니다.

간단한 작업은 주위에 모두 문제가 될 것 방지 :

if (abs(arg - round(arg)) <= SMALL) { 
    return (1); 
} else { 
    return (0); 
} 
+0

VS2010에서는 라운드를 사용할 수없는 것으로 보입니다. https://www.daniweb.com/software-development/cpp/threads/270269/boss_loken-cpp147-error-c3861-round-identifier-not-found 그러나 해당 링크에 지정된대로 해결 방법이 있습니다. 코드가 제대로 작동합니다. 감사. – Tryer