2010-07-15 2 views
3

부동 소수점 오버플로가 값에 발생하는 경우, 나는 ...과 같이 0으로 설정플로트 오버 플로우를 처리하는 방법은 무엇입니까?

m_speed += val; 
if (m_speed > numeric_limits<float>::max()) { // This might not even work, since some impls will wraparound after previous line 
    m_speed = 0.f 
} 

원하지만 valm_speed에 추가되면, 오버 플로우가 이미 발생한 (그리고 난 내가 if ((m_speed + val) > ..)를 한 경우 같은 문제가 발생할 것이라고 가정

가 내가 오버 플로우를 발생시키지 않고 확실히 오버 플로우가 발생하는 것입니다 확인하십시오 어떻게

답변

4

당신이 할 수있는 :.?

if (numeric_limits<float>::max() - val < m_speed) 
{ 
    m_speed = 0; 
} 
else 
{ 
    m_speed += val; 
} 

또 다른 방법이 될 수 있습니다

m_speed += val; 
if (m_speed == numeric_limits<float>::infinity()) 
    m_speed = 0; 

을하지만 오버 플로우가 실제로 발생했을 때 염두에 두어야 할, 결과는 정의되지 않은 동작입니다. 따라서 대부분의 시스템에서 작동하지만 보장 할 수는 없습니다. 당신은 그것이 일어나기 전에 그것을 잡는 것이 낫습니다.


이 처음 읽는 사소한 아니기 때문에, 나는 함수로 묶지 것 : 당신이 FLT_MAX을 초과하는 경우

template <typename T> 
bool will_overflow(const T& pX, const T& pValue, 
        const T& pMax = std::numeric_limits<T>::max()) 
{ 
    return pMax - pValue < pX; 
} 

template <typename T> 
bool will_underflow(const T& pX, const T& pValue, 
        const T& pMin = std::numeric_limits<T>::min()) 
{ 
    return pMin + pValue > pX; 
} 

m_speed = will_overflow(m_speed, val) ? 0 : m_speed + val; 
1

은 다음 부동 소수점 값이 INF이 될 것입니다 그리고 당신은 테스트 할 수 있습니다 이것은 명시 적으로, 예를 들어

#include <iostream> 
#include <cfloat> 
#include <cmath> 

using namespace std; 

int main(void) 
{ 
    float f1 = FLT_MAX; 
    float f2 = f1 * 1.001f; 
    cout << "f1 = " << f1 << ", f2 = " << f2 << endl; 
    cout << "isinf(f1) = " << isinf(f1) << ", isinf(f2) = " << isinf(f2) << endl; 
    return 0; 
} 
+1

는 +/- Inf를가 NaN의 –

+0

@Axel과 동일하지 않습니다 : 좋은 지적 - 난으로 융합하지 말았어야 두 - I가 NaN하지만, IEEE-754로 처리 한 종류로 INF 생각하는 경향이 다른 엔티티. –

관련 문제