2012-05-25 15 views
39

En nuestro código tenemos un doble que necesitamos convertir a un int.Convirtiendo un doble en int en C#

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

¿Alguien puede explicar por qué i1 != i2? El resultado que recibo es el siguiente: i1 = 9 y i2 = 8.

+3

'Math.Truncate (puntuación)' es más explícitamente la intención expresa que '(int) puntuación' – Lu55

Respuesta

66

Debido Convert.ToInt32 rondas:

Valor de retorno: redondean al número entero con signo de 32 bits más cercano. Si el valor está a medio camino entre dos números enteros, se devuelve el número par; es decir, 4,5 se convierte en 4, y 5.5 se convierte a 6.

... mientras que el elenco truncates:

Al convertir desde un valor doble o flotante a un tipo entero , el valor se trunca.

Actualización: Ver comentario Jeppe Stig Nielsen a continuación las diferencias adicionales (que sin embargo no entran en juego si score es un número real como es el caso aquí).

+3

Su enlace realmente lo explica mejor, y no es tan simple como redondo vs truncado: Tipo: System.Int32 valor, redondeado al entero con signo de 32 bits más cercano. Si el valor está a medio camino entre dos números enteros, se devuelve el número par; es decir, 4.5 se convierte en 4 y 5.5 se convierte en 6. – ericosg

+0

@ericosg: Sí, eso enmascararía la diferencia si 'puntaje' fuera' 8.5' en lugar de '8.6'. Actualicé la respuesta para incluir las citas. Gracias por el aporte. – Jon

+2

Y si 'score' es' NaN' o un infinito o finito pero fuera del rango de 'Int32', entonces' Convert.ToInt32' lanzará una excepción. Cast devolverá un 'int', pero no sabrás cuál (en mi implementación es' Int32.MinValue') porque estás en el contexto 'sin marcar'. (En caso de que esté en el contexto 'checked ', el elenco lanzará una excepción también en estos casos.) –

2

ToInt32 rondas. Casting to int solo descarta el componente no entero.

4

puede redondear su doble y elenco ist:

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

la pregunta ahora era ** cómo ** hacer 'i1 == i2'. La pregunta era acerca de ** por qué ** no son iguales. Downvoted. – Adam

7

Fundición ignorará cualquier cosa después del punto decimal, por lo que se convierte en 8.6 8.

Convert.ToInt32(8.6) es la manera segura de garantizar su doble consigue redondeado a el entero más cercano, en este caso 9.

+1

Pregunta de bonificación: ¿qué sucede si el valor del * doble * es demasiado grande para ingresar al * int *? Es decir. si es mayor que * int.MAX_VAL *? –

+1

@KonradViltersten Lanza una excepción _Valor era demasiado grande o demasiado pequeño para un Int32._ – Vamsi