Nel nostro codice abbiamo un double che dobbiamo convertire in un int.
double score = 8.6;
int i1 = Convert.ToInt32(score);
int i2 = (int)score;
Qualcuno può spiegarmi perché i1 != i2
?
Il risultato che ottengo è che: i1 = 9
e i2 = 8
.
Nel nostro codice abbiamo un double che dobbiamo convertire in un int.
double score = 8.6;
int i1 = Convert.ToInt32(score);
int i2 = (int)score;
Qualcuno può spiegarmi perché i1 != i2
?
Il risultato che ottengo è che: i1 = 9
e i2 = 8
.
Risposte:
Perché i Convert.ToInt32
turni:
Valore restituito: arrotondato all'intero con segno a 32 bit più vicino. Se il valore è a metà tra due numeri interi, viene restituito il numero pari; ovvero 4,5 viene convertito in 4 e 5,5 in 6.
... mentre il cast viene troncato :
Quando si converte da un valore double o float a un tipo integrale, il valore viene troncato.
Aggiornamento: vedere il commento di Jeppe Stig Nielsen di seguito per ulteriori differenze (che tuttavia non entrano in gioco se score
è un numero reale come nel caso qui).
score
fosse 8.5
invece di 8.6
. Ho aggiornato la risposta per includere le virgolette. Grazie per l'input.
score
è NaN
o è infinito o finito ma è al di fuori dell'intervallo di Int32
, Convert.ToInt32
verrà generata un'eccezione. Cast restituirà un int
, ma non saprai quale (nella mia implementazione è Int32.MinValue
) perché sei nel unchecked
contesto. (Se sei nel checked
contesto, anche il cast farà un'eccezione in questi casi.)
Double
numero del tipo 10000000000.6
(dieci miliardi di virgola sei) sia un numero "reale". Usare un cast int
su che darà un risultato strano (a meno che tu non sia nel checked
contesto, ma probabilmente non lo sei).
Il cast ignorerà qualsiasi cosa dopo il punto decimale, quindi 8.6 diventa 8.
Convert.ToInt32(8.6)
è il modo sicuro per assicurarti che il tuo doppio venga arrotondato al numero intero più vicino, in questo caso 9.
Nell'esempio fornito il tuo decimale è 8.6 . Se fosse stato 8.5 o 9.5, l'affermazione i1 == i2 avrebbe potuto essere vera. Infatti sarebbe stato vero per 8.5 e falso per 9.5.
Spiegazione:
Indipendentemente dalla parte decimale, la seconda istruzione int i2 = (int)score
scarterà la parte decimale e restituirà semplicemente la parte intera. Cosa abbastanza pericolosa da fare, poiché potrebbe verificarsi una perdita di dati.
Ora, per la prima affermazione, possono accadere due cose. Se la parte decimale è 5, cioè è a metà, è necessario prendere una decisione. Arrotondiamo per eccesso o per difetto? In C #, la classe Convert implementa l'arrotondamento del banchiere. Vedi questa risposta per una spiegazione più approfondita. In poche parole, se il numero è pari, arrotondare per difetto, se il numero è dispari, arrotondare per eccesso.
Ad esempio, considera:
double score = 8.5;
int i1 = Convert.ToInt32(score); // 8
int i2 = (int)score; // 8
score += 1;
i1 = Convert.ToInt32(score); // 10
i2 = (int)score; // 9
ToInt32 giri. Il cast su int elimina semplicemente il componente non intero.
Math.Truncate(score)
è un'intenzione più esplicitamente espressa di(int)score