문제

내 컴퓨터의 부동 소수점 숫자의 내부 표현의 결과 인 것처럼 보이는 정확도 문제를 극복하는 방법이 있는지 궁금합니다.

명확성을 위해 문제는 다음과 같이 요약됩니다.

// str is "4.600";   atof( str ) is 4.5999999999999996  
double mw = atof( str )  

// The variables used in the columns calculation below are:   
//  
//                    mw = 4.5999999999999996  
//                    p = 0.2  
//                    g = 0.2  
//                    h = 1 (integer)  

int columns = (int) ( ( mw - ( h * 11 * p ) ) / ( ( h * 11 * p ) + g ) ) + 1;

정수 유형으로 캐스팅하기 전에 열 계산 결과는 1.9999999999999996입니다. 따라서 지금까지 2.0의 원하는 결과와는 거리가 멀다.

모든 제안이 가장 환영합니다.

도움이 되었습니까?

해결책

부동 소수점 번호를 정수로 반올림하는 매우 간단하고 효과적인 방법 :

int rounded = (int)(f + 0.5);

참고 : 이것은 경우에만 작동합니다 f 항상 긍정적입니다. (감사합니다 J Random Hacker)

다른 팁

플로팅 포인트 산술 엄격한 평등을 사용하면 거의 의미가 없습니다. 일반적으로 허용 가능한 다양한 값과 비교하고 싶습니다.

일부 값은 할 수 있습니다 ~ 아니다 플로팅 포인트 블루스로 정확하게 표현됩니다.

보다 모든 컴퓨터 과학자가 부동 소수점 산술에 대해 알아야 할 것 그리고 부동 소수점 수치 비교.

몰수 문제가 없습니다.

결과 (1.999999999999996)는 수학적 결과 (2)의 1E-16 마진과 다릅니다. 입력 "4.600"을 고려하여 매우 정확합니다.

물론 반올림 문제가 있습니다. C ++의 기본 반올림은 잘림입니다. KIP의 솔루션과 비슷한 것을 원합니다. 세부 사항은 정확한 도메인에 따라 round(-x)== - round(x) ?

당신이 그것을 읽지 않았다면, 제목입니다 이 종이 정말 정확합니다. 현대 컴퓨터의 부동 소수점 산술의 기본 사항, 일부 함정 및 그들이하는 방식에 대한 설명에 대한 설명에 대해 자세히 알아 보려면 읽어보십시오.

정확도가 정말로 중요하다면 플로팅 포인트가 아닌 이중 정밀 부동 소수점 번호를 사용하는 것을 고려해야합니다. 당신의 질문에서 당신이 이미있는 것 같습니다. 그러나 특정 값을 확인하는 데 여전히 문제가 있습니다. (0에 대해 값을 확인한다고 가정 할 때)의 줄을 따라 코드가 필요합니다.

if (abs(value) < epsilon)
{
   // Do Stuff
}

여기서 "Epsilon"은 작지만 0이 아닌 값입니다.

컴퓨터에서는 부동 소수점 번호가 정확하지 않습니다. 그들은 항상 가까운 근사입니다. (1E-16은 가깝습니다.)

때로는 보지 못하는 숨겨진 비트가 있습니다. 때로는 대수의 기본 규칙이 더 이상 적용되지 않습니다 : a*b! = b*a. 때로는 메모리에 레지스터를 비교하면 이러한 미묘한 차이가 나타납니다. 또는 수학 공동 프로세서 대 런타임 플로팅 포인트 라이브러리 사용. (나는이 waayyy 너무 오래 해왔다.)

C99는 다음과 같이 정의합니다 수학)

double round(double x);
float roundf(float x);
long double roundl(long double x);

.

또는 직접 굴릴 수 있습니다.

template<class TYPE> inline int ROUND(const TYPE & x)
{ return int( (x > 0) ? (x + 0.5) : (x - 0.5) ); }

플로팅 포인트 동등성의 경우 다음을 시도하십시오.

template<class TYPE> inline TYPE ABS(const TYPE & t)
{ return t>=0 ? t : - t; }

template<class TYPE> inline bool FLOAT_EQUIVALENT(
    const TYPE & x, const TYPE & y, const TYPE & epsilon )
{ return ABS(x-y) < epsilon; }

소수 사용 : 타협장 ++

당신은 이것을 읽을 수 있습니다 종이 당신이 찾고있는 것을 찾기 위해.

나타난대로 결과의 절대 값을 얻을 수 있습니다. 여기:

x = 0.2;  
y = 0.3;  
equal = (Math.abs(x - y) < 0.000001)  
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top