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 hacia abajo y vuelta)
Dina
128
Sinceramente, no veo el punto de rechazar preguntas genuinas. sí, la respuesta se puede encontrar en google PERO, ¿no mejoraría la calidad del sitio si la gente dejara de cerrar cada segunda pregunta? no es que esta pregunta es spam o cualquier cosa, y estoy seguro de que sería útil para muchos de nuevos productores a C #
jay_t55
Respuestas:
268
Usar Convert.ToInt32desde mscorlibcomo en
decimalvalue=3.14m;int n =Convert.ToInt32(value);
Ver MSDN . También puedes usar Decimal.ToInt32. Nuevamente, vea MSDN . Finalmente, puedes hacer un elenco directo como en
decimalvalue=3.14m;int n =(int)value;
que usa el operador de conversión explícito. Ver MSDN .
Cuidado: Convertir tiene un comportamiento sorprendente para cierta conversión ( nullvs. 0vs. ""). Recomiendo nunca usar Convertir a menos que necesite absolutamente su flexibilidad (es decir, en escenarios de tipo dinámico)
Eamon Nerbonne
1
-1 ya que esto no funcionará para valores como decimal.MaxValue y decimal.MinValue y da como resultado un OverflowException. Creo que @Will proporciona una mejor respuesta aquí stackoverflow.com/a/501165/39532
mezoid
8
Tenga cuidado, porque Convert.ToInt32y Decimal.ToInt32compórtese de manera diferente. Desde MSDN: Decimal.ToInt32- El valor de retorno es la parte integral del valor decimal; los dígitos fraccionarios se truncan . Convert.ToInt32- Valor de retorno 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.
vezucci
67
No puedes
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 lanza un decimal que es mayor que int.MaxValue, se desbordará, y si el decimal es más pequeño que int.MinValue, se desbordará.
¿Qué sucede cuando estás bajo / desbordado? Una de dos cosas Si su compilación no está marcada (es decir, al CLR no le importa si lo hace), su aplicación continuará después de que el valor exceda / disminuya, pero el valor en el int no será lo que esperaba. Esto puede provocar errores intermitentes y puede ser difícil de solucionar. Terminará su aplicación en un estado desconocido que puede provocar que su aplicación corrompa los datos importantes en los que está trabajando. No está bien.
Si su ensamblaje está marcado (propiedades-> compilación-> avanzado-> verifique el desbordamiento / desbordamiento aritmético o la opción / compilador comprobado), su código arrojará una excepción cuando ocurra un desbordamiento / desbordamiento. Esto es probablemente mejor que no; sin embargo, el valor predeterminado para los ensamblajes no es verificar el exceso / desbordamiento.
La verdadera pregunta es "¿qué estás tratando de hacer?" Sin conocer sus requisitos, nadie puede decirle qué 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, debe comunicar su comprensión de que puede ocurrir un desbordamiento y que no importa envolviendo su código de transmisión en un bloque no verificado
unchecked{// do your conversions that may underflow/overflow here}
De esa manera, las personas que vienen detrás de usted entienden que no le importa, y si en el futuro alguien cambia sus compilaciones a / verificado, 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));
Aunque sospecho que son lo mismo bajo el capó si la entrada es un 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 puede truncar números pares que no son de base 10, a diferencia de Decimal.Truncate, que es un verdadero truncamiento de un número de base 10.
Brian
77
Los contextos no verificados no se aplican a los decimales; las operaciones en decimales arrojarán OverflowExceptions independientemente.
Dave
46
int i =(int)d;
le dará el número redondeado hacia abajo.
Si desea redondear al número par más cercano (es decir, se redondeará> .5) puede usar
int i =(int)Math.Round(d,MidpointRounding.ToEven);
En general, puede emitir entre todos los tipos numéricos en C #. Si no hay información que se perderá durante el reparto, puede hacerlo implícitamente:
int i =10;decimal d = i;
aunque aún puede hacerlo explícitamente si lo desea:
int i =10;decimal d =(decimal)i;
Sin embargo, si va a perder información a través del elenco, debe hacerlo explícitamente (para demostrar que sabe que puede estar perdiendo información):
decimal d =10.5M;int i =(int)d;
Aquí estás perdiendo el ".5". Esto puede estar bien, pero debe ser explícito al respecto y hacer un reparto explícito para demostrar que sabe que puede estar perdiendo la información.
En realidad, desea MidpointRounding.AwayFromZero si desea que> * .5 siempre se redondee según mi experiencia probando el código anterior mirando la salida de muestra aquí: msdn.microsoft.com/en-us/library/…
Elijah Lofgren
@ElijahLofgren Depende un poco: si estás haciendo estadísticas, ToEvendebes evitar la deriva estadística. Sin embargo, si opera con artículos o dinero con cargo, AwayFromZeroparece ser la opción correcta.
De la documentación : "Esta API es compatible con la infraestructura de .NET Framework y no está diseñada para usarse directamente desde su código". ¿Por qué no usar Convert.ToInt32?
H.Wolper
7
Un buen truco para el redondeo rápido es agregar .5 antes de convertir su decimal a int.
¿Por qué molestarse en hacer esto cuando hay Math.Floor y Math.Ceiling?
Badaro
En ese momento, era bastante nuevo en 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 era, por ejemplo, -9.3?
Tenga en cuenta que todos ellos también devuelven Decimal, ya que Decimal tiene un rango de valores mayor que un Int32, por lo que aún tendrá que emitir (y verificar si hay desbordamiento / desbordamiento).
Me parece que el operador de conversión no funciona si tiene un decimal en caja (es decir, un valor decimal dentro de un tipo de objeto). Convert.ToInt32 (decimal como objeto) funciona bien en este caso.
Esta situación surge cuando se recuperan los valores IDENTITY / AUTONUMBER de la base de datos:
SqlCommand foo =newSqlCommand("INSERT INTO...; SELECT SCOPE_IDENTITY()", conn);int ID =Convert.ToInt32(foo.ExecuteScalar());// worksint ID =(int)foo.ExecuteScalar();// throws InvalidCastException
Agregarle más como referencia: eso se debe a que solo puede desempaquetar al mismo tipo original. Aquí SELECT SCOPE_IDENTITY()vuelve lo numeric(38, 0)que se traduce en decimal.NET. foo.ExecuteScalar()devuelve un decimalcuadro en el objectque no se puede lanzar directamente a un int. (int)(decimal)foo.ExecuteScalar()o Convert.ToInt32(foo.ExecuteScalar())funcionaría
rageit
0
Ninguna respuesta parece tratar con la excepción OverflowException / UnderflowException que proviene de intentar convertir un decimal que está fuera del rango de int.
int intValue =(int)Math.Max(int.MinValue,Math.Min(int.MaxValue, decimalValue));
Esta solución devolverá el valor int máximo o mínimo posible si el valor decimal está fuera del rango int. Es posible que desee agregar algunos redondeos con Math.Round, Math.Ceiling o Math.Floor para cuando el valor esté dentro del rango int.
Respuestas:
Usar
Convert.ToInt32
desdemscorlib
como enVer MSDN . También puedes usar
Decimal.ToInt32
. Nuevamente, vea MSDN . Finalmente, puedes hacer un elenco directo como enque usa el operador de conversión explícito. Ver MSDN .
fuente
null
vs.0
vs.""
). Recomiendo nunca usar Convertir a menos que necesite absolutamente su flexibilidad (es decir, en escenarios de tipo dinámico)OverflowException
. Creo que @Will proporciona una mejor respuesta aquí stackoverflow.com/a/501165/39532Convert.ToInt32
yDecimal.ToInt32
compórtese de manera diferente. Desde MSDN:Decimal.ToInt32
- El valor de retorno es la parte integral del valor decimal; los dígitos fraccionarios se truncan .Convert.ToInt32
- Valor de retorno 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.No puedes
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 lanza un decimal que es mayor que int.MaxValue, se desbordará, y si el decimal es más pequeño que int.MinValue, se desbordará.
¿Qué sucede cuando estás bajo / desbordado? Una de dos cosas Si su compilación no está marcada (es decir, al CLR no le importa si lo hace), su aplicación continuará después de que el valor exceda / disminuya, pero el valor en el int no será lo que esperaba. Esto puede provocar errores intermitentes y puede ser difícil de solucionar. Terminará su aplicación en un estado desconocido que puede provocar que su aplicación corrompa los datos importantes en los que está trabajando. No está bien.
Si su ensamblaje está marcado (propiedades-> compilación-> avanzado-> verifique el desbordamiento / desbordamiento aritmético o la opción / compilador comprobado), su código arrojará una excepción cuando ocurra un desbordamiento / desbordamiento. Esto es probablemente mejor que no; sin embargo, el valor predeterminado para los ensamblajes no es verificar el exceso / desbordamiento.
La verdadera pregunta es "¿qué estás tratando de hacer?" Sin conocer sus requisitos, nadie puede decirle qué 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, debe comunicar su comprensión de que puede ocurrir un desbordamiento y que no importa envolviendo su código de transmisión en un bloque no verificado
De esa manera, las personas que vienen detrás de usted entienden que no le importa, y si en el futuro alguien cambia sus compilaciones a / verificado, 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.
fuente
le dará el número redondeado hacia abajo.
Si desea redondear al número par más cercano (es decir, se redondeará> .5) puede usar
En general, puede emitir entre todos los tipos numéricos en C #. Si no hay información que se perderá durante el reparto, puede hacerlo implícitamente:
aunque aún puede hacerlo explícitamente si lo desea:
Sin embargo, si va a perder información a través del elenco, debe hacerlo explícitamente (para demostrar que sabe que puede estar perdiendo información):
Aquí estás perdiendo el ".5". Esto puede estar bien, pero debe ser explícito al respecto y hacer un reparto explícito para demostrar que sabe que puede estar perdiendo la información.
fuente
ToEven
debes evitar la deriva estadística. Sin embargo, si opera con artículos o dinero con cargo,AwayFromZero
parece ser la opción correcta.Esto debería funcionar bien.
fuente
Aquí hay una página web de conversión de datos muy útil para aquellos de otros. http://www.convertdatatypes.com/Convert-decimal-to-int-in-CSharp.html
fuente
System.Decimal
implementa laIConvertable
interfaz, que tiene unToInt32()
miembro.¿Las llamadas
System.Decimal.ToInt32()
funcionan para ti?fuente
Un buen truco para el redondeo rápido es agregar .5 antes de convertir su decimal a int.
Todavía se va
i=10
, peroRedondearía para que
i=11
.fuente
Prefiero usar Math.Round , Math.Floor , Math.Ceiling o Math.Truncate para establecer explícitamente el modo de redondeo según corresponda.
Tenga en cuenta que todos ellos también devuelven Decimal, ya que Decimal tiene un rango de valores mayor que un Int32, por lo que aún tendrá que emitir (y verificar si hay desbordamiento / desbordamiento).
fuente
decimal
d = 5.5
;ref: texto del enlace
fuente
Redondeando un decimal al entero más cercano
cuando
a = 49.9
entoncesb = 50
cuando
a = 49.5
entoncesb = 50
cuando
a = 49.4
, entoncesb = 49
etc.fuente
Me parece que el operador de conversión no funciona si tiene un decimal en caja (es decir, un valor decimal dentro de un tipo de objeto). Convert.ToInt32 (decimal como objeto) funciona bien en este caso.
Esta situación surge cuando se recuperan los valores IDENTITY / AUTONUMBER de la base de datos:
Ver 4.3.2 Conversiones de Unboxing
fuente
SELECT SCOPE_IDENTITY()
vuelve lonumeric(38, 0)
que se traduce endecimal
.NET.foo.ExecuteScalar()
devuelve undecimal
cuadro en elobject
que no se puede lanzar directamente a unint
.(int)(decimal)foo.ExecuteScalar()
oConvert.ToInt32(foo.ExecuteScalar())
funcionaríaNinguna respuesta parece tratar con la excepción OverflowException / UnderflowException que proviene de intentar convertir un decimal que está fuera del rango de int.
Esta solución devolverá el valor int máximo o mínimo posible si el valor decimal está fuera del rango int. Es posible que desee agregar algunos redondeos con Math.Round, Math.Ceiling o Math.Floor para cuando el valor esté dentro del rango int.
fuente