[c#] ¿Cómo redondeo un valor decimal a 2 decimales (para salida en una página)



6 Answers

Sé que esta es una vieja pregunta, pero me sorprendió ver que nadie parecía publicar una respuesta;

  1. No usé el redondeo de banqueros
  2. No mantuvo el valor como un decimal.

Esto es lo que usaría:

decimal.Round(yourValue, 2, MidpointRounding.AwayFromZero);

http://msdn.microsoft.com/en-us/library/9s0xa85y.aspx

Question

Cuando se muestra el valor de un decimal actualmente con .ToString() , es preciso tener 15 posiciones decimales, y como lo estoy usando para representar dólares y centavos, solo deseo que el resultado sea 2 decimales.

¿Utilizo una variación de .ToString() para esto?




Ninguno de estos hizo exactamente lo que necesitaba, para forzar 2 dp y redondear como 0.005 -> 0.01

Forzar 2 dp requiere aumentar la precisión en 2 dp para asegurar que tengamos al menos 2 dp

luego redondeando para asegurar que no tenemos más de 2 dp

Math.Round(exactResult * 1.00m, 2, MidpointRounding.AwayFromZero)

6.665m.ToString() -> "6.67"

6.6m.ToString() -> "6.60"



La respuesta mejor calificada describe un método para formatear la representación de cadena del valor decimal, y funciona.

Sin embargo, si realmente desea cambiar la precisión guardada en el valor real, debe escribir algo como lo siguiente:

public static class PrecisionHelper
{
    public static decimal TwoDecimalPlaces(this decimal value)
    {
        // These first lines eliminate all digits past two places.
        var timesHundred = (int) (value * 100);
        var removeZeroes = timesHundred / 100m;

        // In this implementation, I don't want to alter the underlying
        // value.  As such, if it needs greater precision to stay unaltered,
        // I return it.
        if (removeZeroes != value)
            return value;

        // Addition and subtraction can reliably change precision.  
        // For two decimal values A and B, (A + B) will have at least as 
        // many digits past the decimal point as A or B.
        return removeZeroes + 0.01m - 0.01m;
    }
}

Un ejemplo de prueba unitaria:

[Test]
public void PrecisionExampleUnitTest()
{
    decimal a = 500m;
    decimal b = 99.99m;
    decimal c = 123.4m;
    decimal d = 10101.1000000m;
    decimal e = 908.7650m

    Assert.That(a.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("500.00"));

    Assert.That(b.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("99.99"));

    Assert.That(c.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("123.40"));

    Assert.That(d.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("10101.10"));

    // In this particular implementation, values that can't be expressed in
    // two decimal places are unaltered, so this remains as-is.
    Assert.That(e.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
        Is.EqualTo("908.7650"));
}






share fue perfecta para mí en .NET, pero .NET Core no tiene un método decimal.Round en el momento de la escritura.

En .NET Core, tuve que usar:

decimal roundedValue = Math.Round(rawNumber, 2, MidpointRounding.AwayFromZero);

Un método hacky, que incluye la conversión a cadena, es:

public string FormatTo2Dp(decimal myNumber)
{
    // Use schoolboy rounding, not bankers.
    myNumber = Math.Round(myNumber, 2, MidpointRounding.AwayFromZero);

    return string.Format("{0:0.00}", myNumber);
}



Aquí hay un pequeño programa de Linqpad para mostrar diferentes formatos:

void Main()
{
    FormatDecimal(2345.94742M);
    FormatDecimal(43M);
    FormatDecimal(0M);
    FormatDecimal(0.007M);
}

public void FormatDecimal(decimal val)
{
    Console.WriteLine("ToString: {0}", val);
    Console.WriteLine("c: {0:c}", val);
    Console.WriteLine("0.00: {0:0.00}", val);
    Console.WriteLine("0.##: {0:0.##}", val);
    Console.WriteLine("===================");
}

Aquí están los resultados:

ToString: 2345.94742
c: $2,345.95
0.00: 2345.95
0.##: 2345.95
===================
ToString: 43
c: $43.00
0.00: 43.00
0.##: 43
===================
ToString: 0
c: $0.00
0.00: 0.00
0.##: 0
===================
ToString: 0.007
c: $0.01
0.00: 0.01
0.##: 0.01
===================



Si lo quiere formatear con comas y un punto decimal (pero sin símbolo de moneda), como 3,456,789.12 ...

decimalVar.ToString("n2");





Related