如何处理浮点溢出?

per*_*son 4 c++ floating-point error-handling overflow

如果某个值发生浮点溢出,我想将其设置为零,就像这样...

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
}
Run Code Online (Sandbox Code Playgroud)

但一旦val添加m_speed,就已经发生了溢出(并且我假设如果这样做,也会发生相同的问题if (( m_speed + val ) > ..)。)

如何检查以确保不会发生溢出而发生溢出?

GMa*_*ckG 5

您可以这样做:

if (numeric_limits<float>::max() - val < m_speed)
{
    m_speed = 0;
}
else
{
    m_speed += val;
}
Run Code Online (Sandbox Code Playgroud)

另一种方法可能是:

m_speed += val;
if (m_speed == numeric_limits<float>::infinity())
    m_speed = 0;
Run Code Online (Sandbox Code Playgroud)

但是请记住,当实际发生溢出时,结果是未定义的行为。因此,尽管这可能适用于大多数计算机,但不能保证。您最好在发生之前将其捕获。


因为一开始阅读起来并不容易,所以我将其包装到一个函数中:

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;
Run Code Online (Sandbox Code Playgroud)