2014-11-02 12 views
6

Per dichiarare i numeri float dobbiamo mettere 'f' per i float e 'd' per i doppi.C# letterali a virgola mobile: Perché il compilatore non DEFAULTS sul tipo di variabile sul lato sinistro

Esempio:

float num1 = 1.23f; // float stored as float 

float num2 = 1.23; // double stored as float. The code won't compile in C#. 

Si dice che C# default raddoppiare se un punto flottante letterale viene omesso.

La mia domanda è cosa impedisce un linguaggio moderno come "C#" a "DEFAULTS" sul tipo di variabile sul lato sinistro? Dopo tutto, il compilatore può vedere l'intera riga di codice.

È questo per motivi storici nella progettazione del compilatore? o c'è qualcosa che non sto ricevendo.

+0

L'assegnazione num2 non verrà compilata: 1.23 viene considerato come un doppio valore letterale e non può essere assegnato a una variabile float. – furkle

+0

furkle: modificato. – 911

+2

Niente lo impedisce tranne che gli autori del compilatore non l'hanno implementato. –

risposta

1

Qualcun altro qui può probabilmente spiegare perché gli sviluppatori .NET hanno deciso di non utilizzare una sorta di predizione per determinare come un numero letterale dovrebbe essere calzato nel tipo che si sta fornendo ad esso. Ma in assenza di qualsiasi tipo di filosofia, la risposta è semplice: non volevano farlo, quindi non lo fecero. Non ho intenzione di dirti che a titolo definitivo non dovresti preoccupartene, perché ovviamente non è assolutamente irragionevole voler un compilatore per capire esattamente quello che vuoi. Almeno sarebbe carino, vero?

(Se io avessi indovinare, però, direi che ha molto a che fare con che permette una sorta di logica tipizzazione implicita - float f = 1.0 è float, ma var d = 1.0 è double Questo diventa ancora meno logico quando si? considerare che f.Equals (d) sarebbe false, nonostante il fatto che è 1.0 == 1.0true.)

Ma, ammesso che avevano buoni motivi per non introdurre alcuna previsione specifico tipo definizione (e alcuni più perfettamente buoni motivi può essere trovato nel post di Rotem), il miglior motivo per cui posso immaginare hanno deciso che double num1 = 1.23 è accettabile, e float num1 = 1.23 no, è che double è francamente più utile nella maggior parte dei casi. Le penalità di CPU e IO dell'utilizzo di un valore a virgola mobile a 64 bit rispetto a 32 bit sono trascurabili nella maggior parte dei casi d'uso, ma l'utilità di non doversi preoccupare di superare i limiti di quel tipo di dati è significativa.

Si noti che è possibile fare esattamente lo stesso argomento sul motivo per cui 1.23 non può essere assegnato a un decimal senza un suffisso. Le persone che hanno progettato C# hanno deciso che era più facile fare supposizioni sul tipo di un numero letterale di qualsiasi formato, e double è un'ipotesi del tutto ragionevole dato che la maggior parte delle persone che scrivono 1.23 desidera un double o almeno dovrebbe usare uno.

modifica: titolo utente fisso.

+0

modificherà il titolo. – 911

6

Direi che la ragione principale è quella di prevedibilità e coerenza.

Immaginiamo siete il compilatore e si deve determinare il tipo del letterale 3.14 nelle seguenti affermazioni:


float p = 3.14; 

Il primo è stato facile. Ovviamente, dovrebbe essere un galleggiante.


Che dire di questo?

var x = 3.14 * 10.0f; 

l'utente aggiunto in modo esplicito un f dopo 10.0. Quindi dovrebbe essere un float, che cosa su 3.14? Dovrebbe x essere un double o un float?


E questo:

bool b = 3.14/3.14f == 1; 

è il primo 3.14 un double o un float? Il valore di b dipende da questo!


Come utente, preferirei esplicitamente aggiungere un f e sapere esattamente quello che sto ottenendo.

1

Poiché la funzione che si propone fondamentalmente renderebbe il compilatore incoerente. La regola è semplice e facilmente comprensibile: 3.14 è un double, 3.14f è un float.

Il vostro esempio è banale, ma il vostro guardando l'immagine piccola:

float x = 3.14; 

Ok diciamo che il compilatore è "intelligente" abbastanza per risolvere la letterale di galleggiare.

double x = 3.14; 

Hmmm, ora lo stesso letterale è un double e non v'è alcuna conversione implicita da float a double ... strano. Quindi quale dovrebbe essere il tipo di folledi?

var x = 3.14; 

Altre varianti simili della stessa questione:

int i = 2 * 3.14; 

Quale dovrebbe essere l'errore di tempo di compilazione essere? Non è possibile convertire implicitamente double in int o float in int. Perché uno dovrebbe essere migliore dell'altro?

var x = 2 * 3.14; 

Oh, oh, e adesso?

I progettisti C# hanno deciso di risolvere un numero decimale letterale come double ... sempre. Se si desidera un altro tipo (float o decimal), è necessario specificarlo esplicitamente. Vantaggio: coerenza. Avrebbero potuto benissimo decidere di rendere il tipo implicito float ma non si può avere in entrambi i modi senza creare confusione.

Inoltre, è importante notare che le regole di risoluzione C# (tipi, metodi, ecc.) Ignorano costantemente il tipo del lato sinistro di un'espressione. La tua caratteristica farebbe sì che il compilatore modificasse la sua risoluzione del tipo in base al tipo di lato sinistro che sarebbe anche incoerente con il modo in cui si comporta la lingua.

+0

commenti e risposte abbastanza illuminanti da parte di tutti, posso solo accettare una risposta. – 911

Problemi correlati