Qual è il significato di 0.0f durante l’inizializzazione (in C)?

Ho visto codice in cui le persone inizializzano variabili float come questa:

float num = 0.0f; 

C’è una differenza significativa tra questo e solo facendo quanto segue?

 float num = 0; 

Grazie.. 🙂

float x = 0 ha un typecast implicito da int a float.
float x = 0.0f non ha un typecast.
float x = 0.0 ha un typecast implicito da double a float.

A seconda del compilatore, typecast implicito può richiedere al compilatore di generare codice aggiuntivo.

È solo considerato una buona pratica inizializzare una variabile con una costante letterale dello stesso tipo. In questo caso hai una variabile float e dovresti inizializzarla con una costante letterale float, cioè 0.0f , piuttosto che un int ( 0 ) che viene quindi implicitamente trasmesso a un float.

Probabilmente il motivo è che una volta hanno scritto qualcosa del tipo:

 float f = 1 / i; // i an integer 

Avendo eseguito il debug di questo, hanno giurato sempre di decorare letteralmente abbastanza per ottenere il tipo giusto:

 float f = 1.0f / i; 

In questo caso, il .0 serve a garantire che la divisione sia a virgola mobile, non a divisione intera. La f è perché non c’è bisogno che l’operazione venga eseguita in double – mi aspetto che ci siano più possibilità di un’implementazione in cui 1.0/i sarebbe significativamente più lento senza alcun beneficio (emulazione mobile del software, ottimizzazione indifferente), rispetto a quella in cui 1.0f è significativamente più lento senza alcun beneficio (se il doppio è più veloce del float perché l’hardware è fp, quindi la conversione tra i due sarà molto veloce, quindi non introdurre un rallentamento significativo ).

Uno che hai preso l’abitudine di decorare letterali, potresti scrivere bene:

 float f = 0.0f; 

anche se ha esattamente lo stesso effetto di float f = 0.0; o float f = 0; .

Ovviamente l’autore non avrebbe potuto passare attraverso questa rivelazione personalmente, potrebbero aver ereditato lo stile di qualcun altro che lo ha fatto.

Vorrei solo scrivere 0 .

R .. indica in un commento un’altra risposta che scrivere 0 ha anche il vantaggio che quando cambi il tipo di f in futuro, non devi aggiornare il letterale per farlo corrispondere. E se il compito è separato dalla definizione, allora cambia:

 float f = something // some time later f = 0.1f; 

a:

 double f = something; // some time later f = 0.1f; 

è probabilmente un bug. Meglio usare 0.1 e lasciare che il compilatore tronca per fluttuare se necessario. Probabilmente si potrebbe sostenere che l’utilizzo di float è un’ottimizzazione, per lo spazio se non per il tempo, e l’onere di gestire qualsiasi differenza tra float e double dovrebbe essere considerato come costo dello sviluppatore per l’esecuzione di tale ottimizzazione.

Beh, in senso stretto, 0 è un numero intero, quindi float num = 0 richiede un cast dal numero intero al float. Ma suppongo che il compilatore lo faccia comunque per te. Immagino che la gente usi 0.0f per sottolineare che questo è un float, quindi nessuno lo scambia per un intero.

Paul R ha scritto la risposta. Il secondo esempio ha un valore di inizializzazione intero.

Dovresti sempre utilizzare un inizializzatore dello stesso tipo della variabile che viene inizializzata. Questo evita qualsiasi conversione in tempo di compilazione (idealmente) o tempo di esecuzione (compilatori pigri: sono comunque così pigri?). E forse ancora più importante, la conversione può portare a cose strane nel caso generale.

Qui la conversione dovrebbe fare esattamente quello che ci si aspetta, ma è comunque buono ed evita un avvertimento del compilatore.

‘f’ indica che vuoi un float:

0 è un int

0f è un galleggiante

0.0 è un doppio

0.0f è un galleggiante

Non vedo alcun motivo per utilizzarlo per il processo di inizializzazione. Ma, per le operazioni che coinvolgono letterali in virgola mobile, questo sarebbe utile. Per esempio;

 float a=0.43, b; b = 0.5*a + 2.56*a*a; 

I letterali in virgola mobile senza suffisso sono considerati doppi. Quindi, per questo calcolo, “a” sarà castato in modo da raddoppiare e la risposta finale della valutazione RHS sarà doppia. Durante l’assegnazione, il doppio valore di RHS viene castato in virgola mobile e assegnato a “b”. Questo peggiorerebbe le prestazioni se la macchina non ha FPU a doppia precisione. Per evitare ciò e utilizzare float per l’intero calcolo. vengono utilizzati i suffissi. Per esempio,

 float a=0.43, b; b = 0.5f*a + 2.56f*a*a;