c# - truncar - redondear decimales online
¿Cómo redondeo un valor decimal a 2 lugares decimales(para la salida en una página) (15)
Cuando se muestra el valor de un decimal actualmente con .ToString()
, tiene una precisión de 15 lugares decimales, y como lo estoy usando para representar dólares y centavos, solo quiero que la salida tenga 2 lugares decimales.
¿Utilizo una variación de .ToString()
para esto?
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
===================
Dado el decimal d = 12.345; las expresiones d.ToString ("C") o String.Format ("{0: C}", d) rinden $ 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{Precision specifier}
como String.Format("{0:C2}", 5.123d)
.
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"));
}
Muy raramente 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.
Ninguno de estos hizo exactamente lo que necesitaba, para forzar 2 dp y redondear a 0.005 -> 0.01
Forzar 2 dp requiere aumentar la precisión en 2 dp para garantizar que tengamos al menos 2 dp
Luego redondear para asegurar que no tengamos más de 2 dp.
Math.Round(exactResult * 1.00m, 2, MidpointRounding.AwayFromZero)
6.665m.ToString() -> "6.67"
6.6m.ToString() -> "6.60"
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 visita este enlace.
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx
Sé que esta es una pregunta antigua, pero me sorprendió ver que nadie parecía publicar una respuesta a eso;
- No usé banqueros redondeo
- No mantuvo el valor como un decimal.
Esto es lo que yo usaría:
decimal.Round(yourValue, 2, MidpointRounding.AwayFromZero);
Si desea que esté formateado con comas y con un punto decimal (pero sin símbolo de moneda), como 3,456,789.12 ...
decimalVar.ToString("n2");
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/
La "m" es un sufijo decimal. Sobre el sufijo decimal:
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 se ha basado en 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"
Si se realizan las mismas operaciones con Double
, no se indicarán decimales ( "25"
) para cada uno de los anteriores.
Cuando quieres un decimal a 2 lugares 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 encontré con el punto en que necesitaba un decimal COMO un decimal era cuando enviaba XML al servicio web de Amazon. El servicio se quejaba 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 lugares 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 podía hacer ToString("N2")
y necesitaba redondearlo y mantenerlo como decimal
.
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"
share fue perfecta para mí en .NET, pero .NET Core no tiene un método de decimal.Round
en el momento de escribir.
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);
}
decimalVar.ToString ("#.##"); // returns "" when decimalVar == 0
o
decimalVar.ToString ("0.##"); // returns "0" when decimalVar == 0
decimalVar.ToString("F");
Esta voluntad:
- Redondear a 2 decimales por ejemplo. 23.456 => 23.46
- Asegúrese de que siempre haya 2 decimales, por ejemplo. 23 => 23.00, 12.5 => 12.50
Ideal para moneda y mostrar cantidades monetarias.
Para documentación sobre ToString ("F"): http://msdn.microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx#FFormatString (gracias a Jon Schneider)