2011-12-19 8 views
19

È considerato "cattivo stile" utilizzare l'operatore di incremento (++) sui float? Compila bene ma trovo maleodorante e contro-intuitivo.Sta usando increment (operator ++) su float con stile scorretto?

La domanda: in quali casi si utilizza ++ su variabile float giustificata e migliore di += 1.0f? Se non ci sono casi d'uso, c'è una rispettabile guida in stile C++ che dice esplicitamente che ++ su float è malvagio?

Per float ++ non incrementa del valore più piccolo possibile, ma di 1,0. 1.0f non ha significato speciale (diversamente dal numero intero 1). Potrebbe confondere il lettore facendogli pensare che la variabile sia int.

Per float non è garantito che l'operatore ++ modifichi l'argomento. Ad esempio il seguente ciclo non è infinito:

float i, j; 
for (i=0.0, j=1.0; i!=j;i=j++); 

Di conseguenza, facendo immediatamente ++ dopo, non garantisce che il valore sia invariato.

+2

C'è una grande differenza tra j ++ e ++ j – luke

+0

Perché non dividi la coppia domanda-risposta in una domanda appropriata e una risposta adeguata? Potresti ottenere più voti se le persone sono d'accordo con te. – vitaut

+3

+1 - Sono d'accordo che '++' ha una connotazione di "anticipo al valore successivo", non "aumenta del numero magico 1".E in questo senso non ha molto senso usare con i float. Tuttavia, dubito che ci sarà una risposta soddisfacente a questa domanda. – tenfour

risposta

12

In generale ++/-- non è definito per float, poiché non è chiaro con quale valore il float deve essere incrementato. Quindi, potresti avere fortuna su un sistema in cui ++ porta a f += 1.0f ma potrebbero esserci situazioni in cui questo non è valido. Pertanto, per i float, dovrai fornire un valore specifico.

++/-- è definito come "incremento/decremento di 1". Pertanto questo è applicabile ai valori in virgola mobile. Tuttavia, personalmente penso, che questo possa essere fonte di confusione per qualcuno che non è a conoscenza di questa definizione (o lo applica solo ai numeri interi), quindi consiglierei di usare f += 1.0f.

+4

È definito per tutti i tipi di aritmetica e puntatore: "Il valore dell'oggetto operando viene modificato aggiungendo 1 ad esso, a meno che l'oggetto sia di tipo bool, nel qual caso è impostato su true ' – fefe

+0

Anche gcc non si lamenta float ++ durante la compilazione con -Wall. – Muxecoid

+0

@fefe: Grazie per il chiarimento –

15

Quando si aggiunge un sacco di 1.0 ad un galleggiante, a causa di aritmetica in virgola mobile si potrebbe essere un po 'fuori alla fine

Il modo migliore è quello di fare

for (int i = 0; i < 100; i++) 
{ 
    float f = 2.433f + i * 1.0f; 

invece di

for (float f = 2.433f; f < 102.433f; f += 1.0f) 

Nel secondo caso l'errore aritmetico in virgola mobile si somma e nel primo caso non lo è. Come alcuni utenti hanno sottolineato nei commenti qui sotto, l'aggiunta di galleggianti integrali potrebbe non accumulare errori, ma in generale è una buona idea evitarlo.

+4

Sì. (Ma perché moltiplicare per 1.0f? 'Float f = 2.433f + i;' è sufficiente.) – TonyK

+2

@TonyK Stavo pensando ad un incremento generale ... e lasciare che l'incremento sia 1.0f ... :) –

+2

Mentre è vero che certi valori frazionari non hanno una rappresentazione esatta come float, i valori integrali fanno sempre e il risultato dell'aggiunta di due float con valori interi (che sembra essere quello che sta facendo l'OP) non avrà mai un errore di arrotondamento. – Ferruccio

4

È brutto stile. ++ e -- intendono impostare un lvalue al suo valore successivo o precedente, come il numero intero successivo o precedente, l'elemento successivo o precedente in un array (per i puntatori), l'elemento successivo o precedente in un contenitore (iteratori), ecc.

I valori precedenti e precedenti non sono ben definiti per i galleggianti. Do f += 1. esplicitamente.

+2

Non sono sicuro di seguire quello che stai dicendo. Per quanto gli operatori di incremento e decremento siano "intenzionati" a fare qualsiasi cosa, sono pensati per incrementare e decrementare qualsiasi tipo per cui sono definiti, compresi i tipi a virgola mobile. L'unica differenza tra 'f + = 1.' e' ++ f' è che il primo promuove 'f' a un doppio per il calcolo. –

+1

@Mike: Penso che i larsman e l'intervistatore affermino effettivamente che si è trattato di un errore (di cattivo stile) nello standard C per definire '++' per i tipi a virgola mobile. Lo affermano sulla base della loro percezione dell'obiettivo di tale operatore per altri tipi, e solo perché la definizione può essere applicata a qualsiasi tipo con un operatore di assegnazione '+ =' che prende '1' sul rhs, non significa che lo scopo si applica. –

+0

@SteveJessop: esattamente. Ho avuto una discussione sull'argomento con il mio collega, quindi ora sto cercando una guida di stile che supporti il ​​mio punto.:) – Muxecoid

9

Non c'è niente di sbagliato nell'uso di ++ e -- su float o doppi operandi. Semplicemente aggiunge o sottrae 1. Ecco a cosa serve!

+0

Per quanto mi riguarda, in realtà non è vero, secondo lo "standard" che in realtà non specifica il comportamento qui, non mi affiderei a questo. – ScarletAmaranth

+3

@ScarletAmaranth Lo standard specifica il comportamento, in modo molto preciso. (Ciò non significa necessariamente che sia una buona idea.) –

+0

@TonyK Mi scuso, signore, trascuro il mio commento precedente, anche se il suo comportamento non è definito quando si ha a che fare con i float (considerando molti problemi di interpretazione in virgola mobile). Quindi sì, aumenta semplicemente di uno :) – ScarletAmaranth