HOWTO · Csharp

Convertir decimal a int en C#

Elija truncamiento, redondeo al entero más cercano o redondeo dirigido al convertir decimal a int en C# y controle valores fuera de Int32.

En esta página

Use (int)value cuando quiera descartar la parte fraccionaria. Use Convert.ToInt32(value) para redondear al entero más cercano y un método Math cuando la regla sea dirigida o tenga una política específica para los puntos medios. El siguiente ejemplo compacto compara estas opciones con valores positivos.

using System;

class Program
{
    static void Main()
    {
        decimal value = 12.9m;
        Console.WriteLine("cast: " + (int)value);
        Console.WriteLine("nearest: " + Convert.ToInt32(12.5m) + ", " + Convert.ToInt32(13.5m));
        Console.WriteLine("floor: " + Math.Floor(value));
        Console.WriteLine("ceiling: " + Math.Ceiling(value));
        Console.WriteLine("away: " + Math.Round(2.5m, MidpointRounding.AwayFromZero));
    }
}
cast: 12
nearest: 12, 14
floor: 12
ceiling: 13
away: 3

La política de conversión es una regla de negocio, no un detalle de formato. Si la parte fraccionaria sigue siendo significativa, como ocurre con el dinero o las mediciones, conserve el valor como decimal. Toda conversión final a int también debe tener en cuenta los valores que no caben en Int32.

Truncar un decimal hacia cero

El cast explícito (int)value es la opción más clara para truncar. Un literal decimal necesita el sufijo m; sin él, un literal como 12.9 es un double. Al convertir un decimal a un tipo entero se trunca hacia cero: (int)12.9m es 12, mientras que (int)-12.9m es -12. Esto no equivale ni a floor ni a ceiling. La referencia sobre conversiones numéricas de C# documenta el comportamiento hacia cero y el error por valores fuera del intervalo.

Redondear al entero más cercano

Convert.ToInt32(decimal) redondea al entero con signo de 32 bits más cercano en lugar de truncar. Cuando la parte fraccionaria es exactamente .5, usa el redondeo de puntos medios al par: Convert.ToInt32(12.5m) es 12, mientras que Convert.ToInt32(13.5m) es 14. Esto resulta útil para mediciones que deben llegar a la unidad entera más cercana, pero no es la política adecuada cuando cada punto medio debe alejarse de cero.

La documentación de la sobrecarga decimal de Convert.ToInt32 especifica OverflowException para los valores que están fuera del intervalo de int. El método no hace que un decimal demasiado grande sea seguro.

Elegir una regla de redondeo explícita

Aplique primero un método Math al decimal y después convierta el resultado entero. Math.Floor se mueve hacia el infinito negativo, por lo que Math.Floor(-12.9m) es -13m; Math.Ceiling se mueve hacia el infinito positivo. Por tanto, ambos difieren de (int)-12.9m, que es -12.

Para redondear al más cercano con una regla de empate deliberada, use Math.Round(value, MidpointRounding.AwayFromZero). Hace que 2.5m se convierta en 3m y -2.5m en -3m. De forma predeterminada, Math.Round(decimal) usa el redondeo de puntos medios al par. Math.Truncate es otra forma clara de obtener un decimal entero hacia cero antes de convertirlo a int.

No haga el cast antes de redondear: (int)value ya ha descartado la fracción, por lo que una llamada posterior a Math.Round no puede recuperar la decisión prevista. Redondee primero, compruebe el resultado y después haga el cast.

Controlar valores fuera del intervalo int

Un int es un entero con signo de 32 bits limitado por int.MinValue y int.MaxValue; Int32 es el tipo correspondiente de .NET. Un decimal puede representar valores que superan esos límites. Una conversión de decimal a int ya produce OverflowException cuando el valor resultante queda fuera del intervalo; no limita el valor al extremo más cercano.

Valide el valor antes de convertirlo cuando sea posible recibir una entrada fuera del intervalo, o capture OverflowException en el límite de la aplicación. Una conversión checked puede hacer explícita la intención y ayudar a probar el contrato del intervalo, pero no es el mecanismo que detecta el desbordamiento en una conversión de decimal a int. Cuando el contrato receptor lo permita, conserve decimal o elija un tipo entero más amplio en lugar de forzar silenciosamente el valor a int.

Elegir la conversión que coincide con la regla

Resultado previsto Usar Comportamiento importante
Descartar la fracción (int)value Trunca hacia cero.
int más cercano Convert.ToInt32(value) Los puntos medios se redondean al par.
Siempre menor o mayor Math.Floor o Math.Ceiling, y después el cast El redondeo dirigido difiere del truncamiento para valores negativos.
Comportamiento personalizado en los puntos medios Math.Round con MidpointRounding, y después el cast Declare explícitamente la regla para resolver empates.

Elija el cast explícito para el truncamiento habitual. Elija Convert.ToInt32 o un método Math solo cuando su política de redondeo sea la que necesita la aplicación, y gestione OverflowException en el límite de int.