2010-07-15 100 views
3

如果一个值出现浮动溢出,我想将它设置为零,像这样...如何处理浮点溢出?

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 
} 

但一旦val已添加到m_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; 

但是千万记住,当溢出实际发生,其结果是不确定的行为。所以虽然这可能适用于大多数机器,但不能保证。在它发生之前,你最好抓住它。


因为这是不平凡的,在第一次读,我把它包装成一个函数:

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

如果超过FLT_MAX那么你的浮点值将成为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

+/-天道酬勤是不一样的NaN – 2010-07-15 21:04:48

+0

@Axel:好点 - 我不应该混为一谈两个 - 我倾向于认为INF中作为一种NaN的,但IEEE-754就会将它们当作不同的实体。 – 2010-07-15 21:12:28