2012-11-19 7 views
5

Sto scrivendo un metodo che crea una copia di un array di matrici di float. Stavo ottenendo alcuni valori estremamente strani dopo aver eseguito il debug di questo, quindi ho pensato di chiederlo perché non ero in grado di capirlo leggendo le FAQ sugli array di C++.Zero meno lo zero equivalente all'infinito?

Ecco le parti rilevanti del codice (è parte di un programma di grande, con la maggior parte delle cose irrilevanti per questo post):

// height and width are integer global variables 
void method() { 
    float testArray[height][width]; 
    for(int j = 0; j < height; ++j) { 
     for(int i = 0; i < width; ++i) { 
      testArray[j][i] -= 0.0; 
      std::cout << testArray[j][i] << std::endl; 
     } 
    } 
} 

(Nel mio test, altezza = 32 e width = 256, ma ciò non dovrebbe essere rilevante.) Quando inizializzo testArray, i suoi valori dovrebbero essere tutti 0.0, corretto? Quindi, nel ciclo, sottraggo 0.0 da un determinato elemento in testArray, che non dovrebbe logicamente modificare il valore. Ma la stampa dei valori di TestArray a seguito passo debug in alcuni valori strani, come ad esempio il seguente frammento:

[...] 
0 
[...] 
-3.23805e-24 
[...] 
8.40779e-45 
[...] 
1.79513e+37 
[...] 
0 
[...] 
3.19586e+36 
[...] 

I valori più preoccupanti sono quelli infiniti, come ad esempio il quarto numero di cui sopra. Onestamente non so perché questo si sta verificando. Non dovrebbero tutti questi valori essere ancora circa 0.0? Ho pensato che avesse a che fare con l'imprecisione dell'aritmetica in virgola mobile, ma questo non dovrebbe portare ad un valore infinito ...

+7

Quando si inizializza l'array, i valori non sono. inizializzato a 0, ti viene appena assegnata una sezione casuale di memoria con le dimensioni corrette – Sinkingpoint

+2

Dovresti assicurarti di essere compilato al massimo livello di avviso, la maggior parte dei compilatori dovrebbe avvisarti che il tuo array non è inizializzato. –

+0

Wow, quello era un soluzione rapida, grazie. Il mio compilatore ha fatto n o avvertimi del tutto. Non ho idea del motivo per cui ho pensato di inizializzare i valori su 0 ... – TakeS

risposta

7

No, quando dichiarate il vostro array in quel modo sarà non inizializzato poiché è un tipo predefinito. Avrai bisogno di inizializzarlo per azzerare te stesso prima di fare la sottrazione.

Ma si noti che dichiarare un array come si ha (con dimensioni presumibilmente non const) è un'estensione del compilatore e non parte della lingua.

Vorrei solo utilizzare vector che risolve entrambi i problemi contemporaneamente.

std::vector<std::vector<float> > testArray(height, std::vector<float>(width)); 
+0

Grazie per la risposta. C'è un modo semplice per me di modificare l'altezza e la larghezza per essere costanti, quindi penso che rimarrò con una serie di array qui. – TakeS

3

Prova inizializzazione dei valori nella matrice:

float testArray[height][width] = {}; 
2

Questa linea crea un inizializzato matrice , i valori degli elementi possono essere qualsiasi immondizia:

float testArray[height][width]; 

Per inizializzare con galleggiante valori predefiniti (zero) utilizzano la seguente sintassi:

float testArray[height][width] = {}; 
2

QUESTA RISPOSTA È SBAGLIATA, MA LA STIA LASCIANDO COSÌ NO A PROVARE!

utilizzare questa definizione molto esplicito:

float testArray[height][width] = {{0.0f}}; 

per garantire che ogni valore nella vostra matrice viene inizializzato a zero. Altrimenti, i valori nella matrice saranno indefiniti. Sento che questa è la soluzione più "leggibile".

PERCHÉ È SBAGLIATO?

Come @Dave menziona di seguito, sebbene questa soluzione funzioni per questo caso, è fuorviante. Assegna in modo esplicito solo il primo elemento di testArray a 0,0, mentre è value-initializes tutti gli altri elementi dell'array.

La soluzione corretta è infatti:

float testArray[height][width] = {}; 

cui valore inizializza tutti gli elementi della matrice (il valore predefinito 0.0f per tipo float

+1

Questo non verrà compilato, sarà '{{0.0}}' – Rost

+0

@Rost Hai completamente ragione. – dinkelk

+3

-1 Questo è ingannevole, anche se un errore incredibilmente comune. Quello che hai scritto assegna in modo esplicito 1 elemento a '0.0' (dovrebbe essere' 0.0f' o '.0f' a proposito) e value-inizializza il resto degli elementi (che nel caso di float, li inizializza a' 0.0f '). Il modo migliore per farlo è scrivere '= {};' con * no * valore; o scrivere esplicitamente un valore per ogni elemento (non sempre pratico). – David