¿Cómo redondeo un valor decimal a 2 lugares decimales (para la salida en una página)?

StackOverflow https://stackoverflow.com/questions/164926

  •  03-07-2019
  •  | 
  •  

Pregunta

Cuando se muestra el valor de un decimal actualmente con .ToString () , es preciso que me gusten los 15 lugares decimales, y como lo estoy usando para representar dólares y centavos, solo quiero la salida ser 2 decimales.

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

¿Fue útil?

Solución

decimalVar.ToString ("#.##"); // returns "" when decimalVar == 0

o

decimalVar.ToString ("0.##"); // returns "0"  when decimalVar == 0

Otros consejos

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

  1. No usé redondeos bancarios
  2. No se mantuvo el valor como decimal.

Esto es lo que usaría:

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

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

decimalVar.ToString("F");

Esto hará que:

  • Redondea a 2 decimales, por ejemplo. 23.456 = > 23.46
  • Asegúrese de que haya son siempre 2 decimales por ejemplo. 23 = > 23.00, 12.5 = > 12.50

Ideal para moneda y mostrar cantidades monetarias.

Para obtener documentación sobre ToString (" F "): http://msdn.microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx#FFormatString (gracias a Jon Schneider)

Si solo necesita esto para mostrar, use string.Format

String.Format("{0:0.00}", 123.4567m);      // "123.46"

http://www.csharp-examples.net/string-format-double /

El " m " Es un sufijo decimal. Sobre el sufijo decimal:

http://msdn.microsoft.com/en-us/library/ 364x0z75.aspx

Dado decimal d = 12.345; las expresiones d.ToString (" C " ;; o String.Format (" {0: C} " ;, d) produce $ 12.35 : tenga en cuenta que se utilizan las configuraciones de moneda de la cultura actual, incluido el símbolo.

Tenga en cuenta que " C " utiliza el número de dígitos de la cultura actual. Siempre puede anular el valor predeterminado para forzar la precisión necesaria con C {Especificador de precisión} como String.Format (" {0: C2} " ;, 5.123d) .

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

decimalVar.ToString("n2");

Ya hay dos respuestas de puntaje alto que se refieren a Decimal.Round (...) pero creo que se necesita un poco más de explicación, porque hay una propiedad inesperada importante de Decimal que no es obvia.

Un decimal 'sabe' cuántos decimales tiene según el origen.

Por ejemplo, lo siguiente puede ser inesperado:

Decimal.Parse("25").ToString()          =>   "25"
Decimal.Parse("25.").ToString()         =>   "25"
Decimal.Parse("25.0").ToString()        =>   "25.0"
Decimal.Parse("25.0000").ToString()     =>   "25.0000"

25m.ToString()                          =>   "25"
25.000m.ToString()                      =>   "25.000"

Al hacer las mismas operaciones con Double no aparecerán lugares decimales ( " 25 " ) para cada uno de los anteriores.

Cuando quieres un decimal a 2 decimales, hay aproximadamente un 95% de probabilidad porque se trata de una moneda, en cuyo caso es probable que esté bien para el 95% del tiempo:

Decimal.Parse("25.0").ToString("c")     =>   "$25.00"

O en XAML solo usa {Binding Price, StringFormat = c}

Un caso en el que me topé con el punto en que necesitaba un decimal COMO un decimal era cuando enviaba XML al servicio web de Amazon. El servicio se estaba quejando porque un valor decimal (originalmente de SQL Server) se enviaba como 25.1200 y se rechazaba, ( 25.12 era el formato esperado).

Todo lo que tenía que hacer era Decimal.Round (...) con 2 decimales para solucionar el problema.

 // This is an XML message - with generated code by XSD.exe
 StandardPrice = new OverrideCurrencyAmount()
 {
       TypedValue = Decimal.Round(product.StandardPrice, 2),
       currency = "USD"
 }

TypedValue es de tipo Decimal por lo que no pude hacer ToString (" N2 ") y fue necesario para redondearlo y mantenerlo como un decimal .

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: <*>.00
0.00: 0.00
0.##: 0
===================
ToString: 0.007
c: <*>.01
0.00: 0.01
0.##: 0.01
===================

Ninguno de estos hizo exactamente lo que necesitaba, para forzar 2 d.p. y redondear a 0.005 - > 0.01

Forzando 2 d.p. Requiere aumentar la precisión en 2 d.p. para asegurarnos de tener al menos 2 d.p.

luego redondee para asegurarse de que no tenemos más de 2 d.p.

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

6.665m.ToString() -> "6.67"

6.6m.ToString() -> "6.60"

Muy rara vez querría una cadena vacía si el valor es 0.

decimal test = 5.00;
test.ToString("0.00");  //"5.00"
decimal? test2 = 5.05;
test2.ToString("0.00");  //"5.05"
decimal? test3 = 0;
test3.ToString("0.00");  //"0.00"

La respuesta mejor calificada es incorrecta y ha perdido 10 minutos del tiempo (de la mayoría) de las personas.

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 de unidad:

[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"));
}

Puede usar system.globalization para formatear un número en cualquier formato requerido.

Por ejemplo:

system.globalization.cultureinfo ci = new system.globalization.cultureinfo("en-ca");

Si tiene un decimal d = 1.2300000 y necesita recortarlo a dos lugares decimales, entonces puede imprimirse así: d.Tostring (" F2 " ci); donde F2 es una cadena que se forma con 2 decimales y ci es la configuración regional o cultureinfo.

para más información revisa este enlace
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx

La respuesta de Mike M. fue perfecta para mí en .NET, pero .NET Core no tiene un 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, incluida 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);
}

https://msdn.microsoft. com / en-us / library / dwhawy9k% 28v = vs.110% 29.aspx

Este enlace explica en detalle cómo puede manejar su problema y qué puede hacer si desea obtener más información. Para simplificar, lo que quieres hacer es

double whateverYouWantToChange = whateverYouWantToChange.ToString("F2");

si desea esto para una moneda, puede hacerlo más fácil escribiendo '' C2 '' en lugar de " F2 "

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top