2012-05-11 24 views
11

Tengo el siguiente código:C# - Convierte decimal a int32

int a = Convert.ToInt32(4.5m); 
int b = Convert.ToInt32(5.5m); 

Console.WriteLine(a); 
Console.WriteLine(b); 

Y aquí está la salida:

4 
6 

¿Por qué los valores Convert.ToInt32 rondas decimales al número par más cercano?

+0

por lo que espera '' 4'y 5 '? – gideon

+1

sí, espero '4' y' 5' –

+0

pero, ¿por qué esperar algo diferente? – Tigran

Respuesta

12

Convertir está usando el redondeo al más cercano, o redondeo bancario:

El comportamiento de este método sigue el estándar IEEE 754, apartado 4. Esta tipo de redondeo es a veces llamado redondeo al más cercano, o de la banca de redondeo. Minimiza los errores de redondeo que resultan de forma consistente redondeando un valor de punto medio en una sola dirección.

Para controlar el tipo de redondeo utilizado por el método Round, llame a la sobrecarga Math.Round (Double, MidpointRounding).

+0

Parece otro John Skeet en ciernes ... –

+0

Excelente explicación. –

12
int a = (int)Math.Floor(4.5m); 
int b = (int)Math.Floor(5.5m); 

MSDN:

O:

int a = decimal.ToInt32(4.5m); 
int b = decimal.ToInt32(4.5m) 

también puede simplemente utilizar la explícita del operador int reparto:

int a = (int) 4.5m; 
int b = (int) 5.5m; 

Pero lea esta nota de MSDN:

Este operador admite la conversión explícita de un decimal a un Int32. La sintaxis para tales conversiones explícitas depende del idioma, y ​​los compiladores de lenguaje individual pueden proporcionar diferentes implementaciones y devolver resultados diferentes. El ejemplo ilustra los diferentes valores devueltos cuando convierte explícitamente un valor decimal en un valor Int32 utilizando C# y Visual Basic. Para realizar una conversión que sea independiente del idioma, puede llamar al método ToInt32 o Convert.ToInt32 (Decimal).


Math.Floor Method (Decimal) 

Devuelve el mayor entero menor o igual que el número decimal especificado.

Tenga en cuenta que decimal es más grande que int por lo que si el valor es más grande que int.MaxValue se obtiene una OverflowException

+1

+1 ¡Maldición! Muéstremelo :) mientras esperaba una confirmación de OP – gideon

+0

Math.Floor siempre redondea hacia abajo eso es lo que OP quiere. ¿Qué pasaría si (4.9m) obtuviera 4 –

+0

? Solo (int) también hará el trabajo. –

0

leí algo ayer que cuando se produce el redondeo que redondea al número par más cercano, sus llamados banqueros redondeo. Tiene que indicarle cómo desea redondear

EDITAR: solicitó una explicación de por qué se redondea al número par más cercano.

decir que tiene 10 números (este es un caso extremo

1.5, 2.5 , 3.5, 4.5 , 5.5, 6.5 , 7,5, 8.5, 9.5 , 10.5

la suma = 60

si todos ellos redondear primera

la suma = 65 porque todos ellos se redondear

si le banqueros redondas ellos

la suma = 60

+0

Esto simplemente repite una respuesta anterior y no explica el motivo por el que se utiliza este método de redondeo. –

+0

@Ramhound Verifique las veces que se agregaron las respuestas ... me repitieron no al revés, y estoy de acuerdo en que no expliqué por qué, excepto para decir que agrega precisión, razón por la cual en otros comentarios que he hecho se lo conté a la gente para leer sus respuestas –

+0

No me di cuenta. –

4

Lo hace porque that's how it's defined (ver más abajo por el motivo):

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

que tendría que utilizar algo como Math.Floor si quieres resultados diferentes.

La documentación para Math.Round, que hace lo mismo, establece la razón:

El comportamiento de este método sigue el estándar IEEE 754, apartado 4. Esta tipo de redondeo es a veces llamado redondeo al más cercano, o el redondeo del banco . Minimiza los errores de redondeo que resultan de forma consistente redondeando un valor de punto medio en una sola dirección.

para controlar el tipo de redondeo utilizado por el método de Ronda (decimal), llamada la Math.Round (decimal, MidpointRounding) de sobrecarga.

+0

Sí, pero quiero saber el motivo :) La explicación de MSDN no tiene ningún sentido. –

+0

vea mi respuesta a continuación Creo que lo explica de alguna manera. y Dirk muestra cómo elegir qué camino desea redondear –

+0

@ šljaker - El hecho de que pregunte y espere resultados completamente incorrectos muestra claramente que NO conoce el motivo. Además de preguntar "¿por qué está pasando esto?" –

0

De http://msdn.microsoft.com/en-us/library/93kx4xke

Valor devuelto

Tipo: System.Int32 valor, redondeado a los 32 bits más cercana firmó entero. Si el valor está a medio camino entre dos números enteros, se devuelve el número par ; es decir, 4.5 se convierte a 4 y 5.5 es convertido a 6.

+0

Todo lo que hizo fue repetir lo que decía 'Botz3000'. No entiendo el objetivo de esta respuesta. –

+0

Si nos fijamos en la marca de tiempo, puede ver que publicamos al mismo tiempo. – JonC

5

Matemáticas.Round() le permite elegir

Console.WriteLine(Math.Round(4.5m, 0, MidpointRounding.ToEven)); //4 
Console.WriteLine(Math.Round(5.5m, 0, MidpointRounding.ToEven)); //6 

Console.WriteLine(Math.Round(4.5m, 0, MidpointRounding.AwayFromZero)); //5 
Console.WriteLine(Math.Round(5.5m, 0, MidpointRounding.AwayFromZero)); //6 

(Y, como era de suponer, por defecto es ToEven)

+0

+1 para mostrar las opciones de sintaxis –