2009-02-01 21 views
183

¿Cómo convierto un decimal a un int?¿Cómo convierto un decimal a un int en C#?

+9

Sería útil saber si usted quiere redondear al int más cercano o simplemente dejar los números después del punto decimal (es decir: siempre redondeando hacia abajo) – Dinah

+112

Sinceramente, no veo el punto de downvoting preguntas genuinas. sí, la respuesta se puede encontrar en google PERO, ¿no mejoraría la calidad del sitio si las personas dejaran de cerrar cada segunda pregunta? No es que esta pregunta sea spam o algo así, y estoy seguro de que sería útil para muchos recién llegados C# –

Respuesta

228

Uso Convert.ToInt32 de mscorlib como en

decimal value = 3.14m; 
int n = Convert.ToInt32(value); 

Ver MSDN. También puede usar Decimal.ToInt32. Nuevamente, vea MSDN. Finalmente, puede realizar un reparto directo como en

decimal value = 3.14m; 
int n = (int) value; 

que utiliza el operador de conversión explícita. Ver MSDN.

+8

Cuidado: Convert tiene un comportamiento sorprendente para ciertas conversiones ('null' vs.' 0' vs. '" "'). Recomiendo nunca usar Convert a menos que necesite absolutamente su flexibilidad (es decir, en escenarios tipados dinámicamente) –

+1

-1, ya que esto no funcionará para valores como decimal.MaxValue y decimal.MinValue y da como resultado una 'OverflowException'. Creo que @Will ofrece una mejor respuesta aquí http://stackoverflow.com/a/501165/39532 – mezoid

+2

Tenga cuidado, porque 'Convert.ToInt32' y' Decimal.ToInt32' se comportan de manera diferente. Desde MSDN: 'Decimal.ToInt32' - El valor de retorno es la parte integral del valor decimal; los dígitos fraccionarios están ** truncados **. 'Convert.ToInt32' - El valor de retorno ** redondeado ** al entero de 32 bits con signo 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 a 4 y 5.5 se convierte a 6. – vezucci

8

System.Decimal implementa la interfaz IConvertable, que tiene un miembro ToInt32().

¿Funcionan las llamadas al System.Decimal.ToInt32()?

+1

De [la documentación] (https://msdn.microsoft.com/en-us/library/bb350799 (v = vs.110) .aspx) : "Esta API admite la infraestructura de .NET Framework y no está destinada a ser utilizada directamente desde su código". ¿Por qué no usar Convert.ToInt32? –

18
decimal d = 2; 
int i = (int) d; 

Esto debería funcionar bien.

+0

Cuidado, con una información de conversión explícita podría perderse. – Phaedrus

+18

Al convertir de decimal a int, la información casi siempre se perderá, pero creo que ese es el punto. – Dinah

38
int i = (int)d; 

le dará el número redondeado hacia abajo.

Si desea redondear al número par más cercano (es decir,> 0,5 se redondeará hacia arriba) se puede utilizar

int i = (int)Math.Round(d, MidpointRounding.ToEven); 

En general se puede lanzar entre todos los tipos numéricos en C#. Si no hay información que se pierde durante el elenco puede hacerlo de forma implícita:

int i = 10; 
decimal d = i; 

pesar de que todavía puede hacerlo de forma explícita si lo desea:

int i = 10; 
decimal d = (decimal)i; 

Sin embargo, si se va a ser la pérdida de información a través del yeso hay que hacerlo de forma explícita (para demostrar que es consciente de que puede estar perdiendo información):

decimal d = 10.5M; 
int i = (int)d; 

Aquí está perdiendo la" 0.5" . Esto puede estar bien, pero debe ser explícito al respecto y hacer un molde explícito para mostrar que sabe que puede estar perdiendo la información.

8

Un buen truco para el redondeo rápido es agregar .5 antes de convertir el decimal a un int.

decimal d = 10.1m; 
d += .5m; 
int i = (int)d; 

todavía deja i=10, pero

decimal d = 10.5m; 
d += .5m; 
int i = (int)d; 

redondearíamos de modo que i=11.

+5

¿Por qué molestarse en hacer esto cuando hay Math.Floor y Math.Ceiling? – Badaro

+0

En ese momento, era bastante nuevo para C# y por alguna razón no me di cuenta de que estas funciones existían. En realidad, es un truco que aprendí de C/C++, donde obviamente fue más útil. – DeadlyBrad42

+1

¿Qué pasa si el valor decimal fuera, por ejemplo,? -9.3? – supercat

64

No puede.

Bueno, por supuesto que podría, sin embargo, un int (System.Int32) no es lo suficientemente grande como para contener todos los valores decimales posibles.

Eso significa que si emite un decimal que es más grande que int.MaxValue se desbordará, y si el decimal es más pequeño que int.MinValue, se desbordará.

¿Qué sucede cuando sube/baja? Una de dos cosas. Si su construcción no está marcada (es decir, CLR no le importa si lo hace), su aplicación continuará después del valor por encima/por debajo del flujo, pero el valor en el int no será el que esperaba. Esto puede provocar errores intermitentes y puede ser difícil de solucionar. Usted terminará su aplicación en un estado desconocido que puede ocasionar que su aplicación corrompa los datos importantes en los que está trabajando. No está bien.

Si su conjunto está marcado (propiedades-> construir-> avanzado-> comprobar el desbordamiento/subdesbordamiento aritmético o la opción de compilador/comprobado), su código generará una excepción cuando ocurra un subdesbordamiento/desbordamiento. Esto es probablemente mejor que no; sin embargo, el valor predeterminado para los conjuntos no es verificar el exceso/defecto.

La verdadera pregunta es "¿qué estás tratando de hacer?" Sin conocer sus requisitos, nadie puede decirle lo que debe hacer en este caso, aparte de lo obvio: NO LO HAGA.

Si específicamente NO te importa, las respuestas aquí son válidas. Sin embargo, usted debe comunicarse su comprensión de que un desbordamiento puede ocurrir y que no importa envolviendo su código fundido en un bloque de sin control

unchecked 
{ 
    // do your conversions that may underflow/overflow here 
} 

Que la gente forma en que vienen detrás entienden no lo hace cuidado, y si en el futuro alguien cambia sus compilaciones a/verificadas, su código no se romperá inesperadamente.

Si todo lo que quiere hacer es soltar la parte fraccionaria del número, dejando la parte integral, puede usar Math.Truncate.

decimal actual = 10.5M; 
decimal expected = 10M; 
Assert.AreEqual(expected, Math.Truncate(actual)); 
+3

Aunque sospecho que son lo mismo bajo el capó si la entrada es decimal, me siento más cómodo usando Decimal.Truncate que Math.Truncate, ya que este último también acepta dobles y por lo tanto se puede entender que es capaz de truncar incluso números que no son base 10, a diferencia de Decimal.Truncate, que es un verdadero truncamiento de un número base 10. – Brian

+6

Los contextos no verificados no se aplican a los decimales; las operaciones en decimales arrojarán OverflowExceptions independientemente. – Dave

+0

@dave Damnit, tienes razón. BRB, ECMA. – Will

6

Yo prefiero usar Math.Round, Math.Floor, Math.Ceiling o Math.Truncate para establecer explícitamente el modo de redondeo según el caso.

Tenga en cuenta que todos devuelven Decimal también, ya que Decimal tiene un rango de valores más grande que un Int32, por lo que aún tendrá que realizar el colado (y comprobar si hay desbordamiento/subdesbordamiento).

checked { 
    int i = (int)Math.Floor(d); 
} 
0

me parece que el operador de fundición no funciona si tiene un número decimal en caja (es decir, un valor decimal en el interior de un tipo de objeto). Convert.ToInt32 (decimal como objeto) funciona bien en este caso.

Esta situación surge cuando se recuperan los valores de identidad/Autonumérico de la base de datos:

SqlCommand foo = new SqlCommand("INSERT INTO...; SELECT SCOPE_IDENTITY()", conn); 
int ID = Convert.ToInt32(foo.ExecuteScalar()); // works 
int ID = (int)foo.ExecuteScalar();    // throws InvalidCastException 

Ver 4.3.2 Unboxing conversions

+2

Añadiéndole más como referencia: eso se debe a que solo puedes desunir el mismo tipo de original. Aquí 'SELECT SCOPE_IDENTITY()' devuelve 'numérico (38, 0)' que se traduce a 'decimal' por .NET. 'foo.ExecuteScalar()' devuelve un 'decimal' en caja como' object' que no puede ser casted directamente a un 'int'. '(int) (decimal) foo.ExecuteScalar()' o 'Convert.ToInt32 (foo.ExecuteScalar())' funcionaría. – rageit

5

decimal d = 5.5;

int i = decimal.ToInt32(d);// you will get i = 5 

ref: link text

3

Completando un decimal al entero más cercano

decimal a ; 
int b = (int)(a + 0.5m); 

cuando a = 49.9, entonces b = 50

cuando a = 49.5, entonces b = 50

cuando a = 49.4, a continuación, b = 49 etc.

Cuestiones relacionadas