2010-07-15 103 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