Domanda

Qual è la pratica più efficace da prevenire overflow aritmetico E sottoflusso?

Alcuni esempi che mi vengono in mente sono:

  • test basati su intervalli di input validi
  • validazione mediante metodi formali
  • uso degli invarianti
  • rilevamento in fase di esecuzione utilizzando funzionalità o librerie del linguaggio (questo non lo impedisce)
È stato utile?

Soluzione

Una possibilità è quella di utilizzare un linguaggio che abbia numeri interi di dimensioni arbitrarie che non trabocchino o non trabocchino mai.

Altrimenti, se questo è qualcosa che ti preoccupa veramente, e se il tuo linguaggio lo consente, scrivi una classe wrapper che si comporti come un numero intero, ma controlla l'overflow di ogni operazione.Potresti anche fare in modo che esegua il controllo sulle build di debug e lasci le cose ottimizzate per le build di rilascio.In un linguaggio come C++, potresti farlo e si comporterebbe quasi esattamente come un numero intero per le build di rilascio, ma per le build di debug otterresti un controllo completo in fase di esecuzione.

class CheckedInt
{
private: 
    int Value;

public:
    // Constructor
    CheckedInt(int src) : Value(src) {}

    // Conversions back to int
    operator int&() { return Value; }
    operator const int &() const { return Value; }

    // Operators
    CheckedInt operator+(CheckedInt rhs) const
    {
        if (rhs.Value < 0 && rhs.Value + Value > Value)
            throw OverflowException();
        if (rhs.Value > 0 && rhs.Value + Value < Value)
            throw OverflowException();
        return CheckedInt(rhs.Value + Value);
    }

    // Lots more operators...
};

Modificare:

Si scopre che qualcuno lo è lo sto già facendo per C++ - l'attuale implementazione è focalizzata su Visual Studio, ma sembra che stiano ricevendo supporto anche per gcc.

Altri suggerimenti

Scrivo molto codice di prova per eseguire controlli di intervallo/validità sul mio codice.Questo tende a cogliere la maggior parte di questi tipi di situazioni e sicuramente mi aiuta a scrivere un codice più a prova di proiettile.

Utilizza numeri in virgola mobile ad alta precisione come a doppio lungo.

Penso che ti manchi un'opzione molto importante nella tua lista:scegliere il linguaggio di programmazione giusto per il lavoro.Esistono molti linguaggi di programmazione che non presentano questi problemi, poiché non hanno numeri interi a dimensione fissa.

Quando si sceglie la lingua da utilizzare, ci sono considerazioni più importanti rispetto alla dimensione del numero intero.Controlla semplicemente il tuo input se non sai se il valore rientra nei limiti o utilizza la gestione delle eccezioni se il caso è estremamente raro.

Un wrapper che controlli le incoerenze avrà senso in molti casi.Se un'operazione additiva (addizione o moltiplicazione) su due o più numeri interi restituisce un valore inferiore a quello degli operandi, allora sai che qualcosa è andato storto.Ogni operazione additiva dovrebbe essere seguita da,

if (sum < operand1 || sum < operand2)
    omg_error();

Allo stesso modo qualsiasi operazione che dovrebbe logicamente risultare in un valore più piccolo dovrebbe essere controllata per vedere se è stata accidentalmente aumentata.

Hai studiato l'uso di metodi formali per controllare il tuo codice per dimostrare che è privo di overflow?Una tecnica di metodo formale nota come interpretazione astratta può verificare la robustezza del software per dimostrare che il software non soffrirà di overflow, underflow, divisione per zero, overflow o altri errori simili di runtime.È una tecnica matematica che analizza in modo esaustivo il tuo software.La tecnica è stata sperimentata da Patrick Cousot negli anni '70.È stato utilizzato con successo per diagnosticare una condizione di trabocco nel razzo Arian 5 in cui un trabocco ha causato la distruzione del veicolo di lancio.L'overflow è stato causato durante la conversione di un numero in virgola mobile in un numero intero.Puoi trovare maggiori informazioni su questa tecnica Qui e anche su Wikipedia.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top