2012-05-25 5 views
39

Nel nostro codice abbiamo un doppio che dobbiamo convertire in un int.Conversione di un doppio in un interno in C#

double score = 8.6; 
int i1 = Convert.ToInt32(score); 
int i2 = (int)score; 

Qualcuno può spiegarmi perché i1 != i2?

Il risultato che ottengo è quello: i1 = 9 e i2 = 8.

+3

'Math.Truncate (score)' è un'intenzione espressa più esplicitamente di '(int) score' – Lu55

risposta

66

perché Convert.ToInt32 turni:

Valore di ritorno: arrotondati al numero intero con segno a 32 bit più vicino. Se il valore è a metà strada tra due numeri interi, viene restituito il numero pari; che è, 4,5 viene convertito in 4, e 5.5 viene convertito in 6.

... mentre il cast truncates:

Quando si converte da un valore doppio o float a un tipo integrale , il valore viene troncato.

Aggiornamento: commento See Jeppe Stig Nielsen sotto per ulteriori differenze (che però non entrano in gioco se score è un numero reale come è il caso qui).

+3

Il tuo link in realtà lo spiega meglio, e non è così semplice come round contro truncate: Tipo: System.Int32 , arrotondato al numero intero con segno a 32 bit più vicino. Se il valore è a metà strada tra due numeri interi, viene restituito il numero pari; cioè 4.5 viene convertito in 4 e 5.5 viene convertito in 6. – ericosg

+0

@ericosg: Sì, questo maschera la differenza se 'score' fosse' 8.5' invece di '8.6'. Ho aggiornato la risposta per includere le virgolette. Grazie per l'input. – Jon

+2

E se 'score' è' NaN' o un infinito o finito ma fuori dal range di 'Int32', quindi' Convert.ToInt32' genererà un'eccezione. Cast restituirà un 'int', ma non saprai quale (nella mia implementazione è' Int32.MinValue') perché sei nel contesto 'deschecked'. (Se sei nel contesto di 'checked', anche il cast lancia un'eccezione in questi casi.) –

2

RoundInt32. Il lancio su int getta via il componente non intero.

4

è possibile arrotondare il tuo doppio e cast ist:

(int)Math.Round(myDouble); 
+0

la domanda ora era ** come ** per rendere 'i1 == i2'. La domanda riguardava ** perché ** non sono uguali. Downvoted. – Adam

7

Casting ignorerà qualsiasi cosa dopo il punto decimale, quindi 8.6 diventa 8.

Convert.ToInt32(8.6) è il modo sicuro per garantire la vostra doppia viene arrotondato al il numero intero più vicino, in questo caso 9.

+1

Domanda bonus: che succede se il valore del * double * è troppo grande per essere inserito in * int *? Cioè se è superiore a * int.MAX_VAL *? –

+1

@KonradViltersten Genera un'eccezione _Value era troppo grande o troppo piccolo per un Int32._ – Vamsi