2010-06-24 13 views
4

DBL_EPSILON/std :: numeric_limits :: 엡실론은 하나를 추가 할 때 차이를 만드는 가장 작은 값을 줄 것입니다.DBL_EPSILON/엡실론을 사용하는 경우

유용한 정보에이 지식을 적용하는 방법을 이해하는 데 문제가 있습니다.

엡실론은 컴퓨터가 처리 할 수있는 가장 작은 값보다 훨씬 크기 때문에 엡실론보다 작은 값을 사용하는 것이 안전하다는 가정이 올바른 것처럼 보일 수 있습니다.

내가 작업하는 값의 비율이 1/ε보다 작 으면 안됩니까?

답변

4

DBL_EPSILON의 정의가 아닙니다. 다음에 표현할 수있는 1과 1 사이의 차이입니다 (사용자 정의에서는 반올림 모드가 "향해 0"또는 "- 반대로 무한대"로 설정되어 있다고 가정합니다. 항상 그렇지는 않습니다).

숫자 분석에 대해 충분히 알고 있다면 유용합니다. 그러나 나는이 장소가 그것에 관해 배울 가장 좋은 사람이 아닌 것을 두려워한다. 예를 들어, 두 개의 부동 소수점 숫자이

bool approximatively_equal(double x, double y, int ulp) 
{ 
    return fabs(x-y) <= ulp*DBL_EPSILON*max(fabs(x), fabs(y)); 
} 

은 (그러나 ULP을 결정하는 방법을 모르고, 당신이 손실 될 것 같은 approximatively 동일한 경우는 말할 것 비교 기능이있는 건물에서 사용할 수,이 함수는 중간 결과가 비정상 일 경우 문제가있을 수 있으며 fp 계산은 복잡해지기 때문에 복잡합니다.

+0

'approximately_equal'을 지수 값이 변하기 때문에 현재 값과 다음으로 가장 가까운 표현 가능한 값 사이의 간격 크기가 크기와 함께 변하기 때문에 매우 큰 값에 대해서는 올바르게 작동하지 않습니다. 이를 적절하게 수행하려면 비교되는 값을 기반으로 상황에 맞는 정확한 엡실론을 다시 계산해야합니다. – numist

+0

@numist,'max (fabs) '에 의해 ε을 곱하면 정확한 크기가 주어져야하며, ulp 인수는 이미 누적 된 상대적 오류에 대한 컨텍스트 정보를 제공합니다. 여전히 문제가 있다고 생각되면 소스를 더 명확하게 할 수 있습니까? – AProgrammer

+0

엡실론은 연속적인 방식으로 비례하지 않습니다. IEEE 인코딩의 경우, 엡실론은베이스 2의 값에 비례합니다. http://stackoverflow.com/questions/5064377/c-comparing-two-floating-point-values/35536839#35536839 –

1

X과 다음 값인 X의 차이는 X에 따라 다릅니다.
DBL_EPSILON1과 다음 값 1 사이의 차이입니다.

당신은 엡실론 차이가 두 double을 테스트 std::nextafter을 사용할 수 있습니다 : 당신이 요인 * 엡실론의 차이가 두 double을 테스트하려는 경우

bool nearly_equal(double a, double b) 
{ 
    return std::nextafter(a, std::numeric_limits<double>::lowest()) <= b 
&& std::nextafter(a, std::numeric_limits<double>::max()) >= b; 
} 

, 당신은 사용할 수 있습니다

bool nearly_equal(double a, double b, int factor /* a factor of epsilon */) 
{ 
    double min_a = a - (a - std::nextafter(a, std::numeric_limits<double>::lowest())) * factor; 
    double max_a = a + (std::nextafter(a, std::numeric_limits<double>::max()) - a) * factor; 

    return min_a <= b && max_a >= b; 
}