2010-05-25 9 views
2

double의 역 제곱근을 찾을 때 유효하지 않은 양수가 아닌 입력을 0.0 또는 MIN_DBL로 클램프하는 것이 더 좋습니까?0.0으로DBL_MIN 대 0.0 C++ 이중 나눗셈

두 부문 (double b 아래 내 예. 인해 약간 약간 게임은 과장되어 물리 법칙 부동 소수점 반올림 오류 때문 제외 끝나게 월) 및 MIN_DBL는 동일한 결과를 생성 1/0.01/DBL_MIN이 사실상 무한대이기 때문에 게임. 나의 직감은 MIN_DBL이 더 나은 선택이라고 말하지만, 0.0을 사용하는 모든 경우가 있을까요? 아마도 sqrt(0.0)과 마찬가지로 1/0.01.#INF000000000000의 곱셈은 특별한 경우이기 때문에 더 빠르게 실행됩니다. MSVC에서

double b = 1 - v.length_squared()/(c*c); 

#ifdef CLAMP_BY_0 
if (b < 0.0) b = 0.0; 
#endif 

#ifdef CLAMP_BY_DBL_MIN 
if (b <= 0.0) b = DBL_MIN; 
#endif 

double lorentz_factor = 1/sqrt(b); 

두 부문 :

 
1/0.0  = 1.#INF000000000000 
1/DBL_MIN = 4.4942328371557898e+307 

답변

2

부동 소수점 연산을 다룰 때는 "무한"과 "유효 무한"이 상당히 다릅니다. 숫자가 유한 한 것을 멈 추면, 그것은 그 길을 유지하는 경향이 있습니다. 따라서 lorentz_factor의 값이 두 값의 사용 방법에 따라 "효과적으로"같지만 나중에 계산은 근본적으로 다를 수 있습니다. 예를 들어 sqrt(lorentz_factor)은 0으로 클램핑하면 무한 상태로 유지되지만 매우 작은 숫자로 고정하면 실제로 계산됩니다.

그래서 답은 주로 클램핑 한 후에 그 값으로 무엇을 할 계획인지에 달려 있습니다.

0

왜 그냥 sqrt 전화 및 부문 모두를 피하고, 직접 lorentz_factorINF를 할당?

double lorentz_factor; 
if (b <= 0.0) 
    lorentz_factor = std::numeric_limits<double>::infinity(); 
else 
    lorentz_factor = 1/sqrt(b); 
  • 이에 대한 #include <limits>해야합니다.
  • ::infinity() 대신 ::max()을 사용할 수도 있습니다.