2010-03-02 1 views
17

Ho trascorso parte di ieri e oggi rintracciando un bug in qualche codice Matlab. Avevo pensato che il mio problema fosse l'indicizzazione (con molte strutture che non ho definito e mi sto ancora abituando), ma si è rivelato un bug di overflow. Ho perso questo per un motivo ben preciso:Come riconoscere i bug di overflow in Matlab?

>> uint8(2) - uint8(1) 

ans = 

    1 

>> uint8(2) - uint8(2) 

ans = 

    0 

>> uint8(2) - uint8(3) 

ans = 

    0 

mi sarei aspettato l'ultimo ad essere qualcosa di simile a -1 (o 255). Nel mezzo di un grande vettore, gli errati 0 s erano difficili da rilevare, ma uno 255 si sarebbe distinto facilmente.

Eventuali suggerimenti su come rilevare facilmente questi problemi in futuro? (Idealmente, mi piacerebbe disattivare il controllo di overflow per farlo funzionare come C.) Cambiare in double funziona, ovviamente, ma se non mi rendo conto che è un uint8 per cominciare, che non aiuta.

+1

Dove prendi questi numeri da? Se li carichi dal file, puoi semplicemente aggiungere una riga al caricatore per restituire tutto come uint8 o doppio. Oltre a leggere i file, non dovresti aspettarti gli uint8 in Matlab. – Jonas

+0

In realtà non so esattamente da dove vengano. Sto integrando il codice di qualcun altro, quindi non conosco i dettagli. –

risposta

13

Si può iniziare accendendo avvertimenti interi:

intwarning('on') 

Questo vi darà un avviso quando integer overflow aritmetici.

Attenzione però, come indicato in here, questo rallenta l'aritmetica dei numeri interi, quindi usalo solo durante il debug.

+3

Nota: [INTWARNING è stato rimosso] (http://www.mathworks.com/help/techdoc/rn/bsdgysw-1.html#bseu09o-1) e il link sopra non è più valido. – gnovice

+0

Ragazzi, sapete perché è stato rimosso e cosa invece usare? – Lupocci

6

A partire dalla versione R2010b e più tardi, la funzione INTWARNING has been removed, insieme a these warning messages for integer math and conversion:

  • MATLAB:intConvertNaN
  • MATLAB:intConvertNonIntVal
  • MATLAB:intConvertOverflow
  • MATLAB:intMathOverflow

Quindi utilizzare INTWARNING non è più un'opzione valida per determinare quando si verificano overflow integer. Un'alternativa è utilizzare la funzione CLASS per verificare la classe dei dati e riformularli di conseguenza prima di eseguire l'operazione. Ecco un esempio:

if strcmp(class(data),'uint8') %# Check if data is a uint8 
    data = double(data);   %# Convert data to a double 
end 

È anche possibile utilizzare la funzione ISA così:

if ~isa(data,'single') %# Check if data is not a single 
    data = single(data); %# Convert data to a single 
end 
+2

Se non sai da dove provengono i tuoi dati, dovresti fare dei test di input molto accurati come questo. – Jonas

+0

@gnovice Ho appena avuto lo stesso problema, ma il tuo approccio al casting a doppio o singolo sembra molto strano per me. Cosa succede se ho bisogno di questi suggerimenti? Non voglio essere costretto a fare tutto sui doppi. Naturalmente non è una domanda, ma perché MATLAB non può utilizzare le operazioni con interi senza segno standard? – angainor