How to handle a float overflow?

孤街醉人 提交于 2019-12-10 15:54:33

问题


If a float overflow occurs on a value, I want to set it to zero, like this...

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
}

but once val has been added to m_speed, the overflow has already occurred (and I'm assuming that the same problem would occur if i did if (( m_speed + val ) > ..).

How can I check to make sure an overflow is going to occur, without causing an overflow?


回答1:


You could do:

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

Another method might be:

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

But do keep in mind when an overflow actually occurs, the result is undefined behavior. So while this probably works on most machines, it isn't guaranteed. You're better of catching it before it happens.


Because this isn't trivial to read at first, I'd wrap it into a function:

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;



回答2:


If you exceed FLT_MAX then your float value will become INF and you can test for this explicitly, e.g.

#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;
}


来源:https://stackoverflow.com/questions/3260022/how-to-handle-a-float-overflow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!