2010-07-15 5 views
3

Si un débordement de flotteur se produit sur une valeur, je veux le mettre à zéro, comme ça ...Comment gérer un débordement de flotteur?

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 
} 

mais une fois val a été ajouté à m_speed, le trop-plein a déjà eu lieu (et je suis en supposant que le même problème se produirait si je ne if ((m_speed + val) > ..)

Comment puis-je vérifier pour vous assurer un débordement va se produire, sans provoquer un débordement

Répondre

4

Vous pourriez faire:.?

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

Une autre méthode pourrait être:

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

Mais gardez à l'esprit quand un débordement se produit en fait, le résultat est un comportement non défini. Donc, même si cela fonctionne probablement sur la plupart des machines, ce n'est pas garanti. Tu es mieux de l'attraper avant que ça n'arrive.


Parce que ce n'est pas trivial de lire d'abord, je l'envelopper dans une fonction:

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

Si vous dépassez FLT_MAX alors votre valeur flottante deviendra INF et vous pouvez tester ceci explicitement, par exemple

#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 n'est pas le même que NaN –

+0

@Axel: bon point - je ne devrais pas avoir confondu les deux - je tends à penser INF comme une sorte de NaN mais IEEE-754 les traite comme différentes entités. –

Questions connexes