c# - solo - Usando el formato de cadena para mostrar el decimal hasta 2 lugares o un entero simple
string.format c# decimal (15)
Tengo un campo de precios para mostrar, que a veces puede ser 100 o 100.99 o 100.9. Lo que quiero es mostrar el precio en 2 decimales solo si los decimales se ingresan para ese precio, por ejemplo, si es 100, entonces solo debería muestre 100 no 100.00 y si el precio es 100.2 debería mostrar 100.20 de manera similar para 100.22 debería ser igual. Busqué en Google y encontré algunos ejemplos, pero no coincidían exactamente con lo que quería:
// just two decimal places
String.Format("{0:0.00}", 123.4567); // "123.46"
String.Format("{0:0.00}", 123.4); // "123.40"
String.Format("{0:0.00}", 123.0); // "123.00"
Aquí hay una alternativa al método de Uwe Keim, que aún mantendría el mismo método de llamada:
var example1 = MyCustomFormat(123.1); // Output: 123.10
var example2 = MyCustomFormat(123.95); // Output: 123.95
var example3 = MyCustomFormat(123); // Output: 123
Con MyCustomFormat
es algo como:
public static string MyCustomFormat( double myNumber )
{
var str (string.Format("{0:0.00}", myNumber))
return (str.EndsWith(".00") ? str.Substring(0, strLastIndexOf(".00")) : str;
}
Código de una línea simple:
public static string DoFormat(double myNumber)
{
return string.Format("{0:0.00}", myNumber).Replace(".00","");
}
Este es un caso de uso de número flotante de formato común.
Desafortunadamente, todas las cadenas de formato de una letra incorporadas (por ejemplo, F, G, N) no lo lograrán directamente.
Por ejemplo, num.ToString("F2")
siempre mostrará 2 lugares decimales, como 123.40
.
Tendrás que usar el patrón 0.##
aunque se vea un poco detallado.
Un ejemplo de código completo:
double a = 123.4567;
double b = 123.40;
double c = 123.00;
string sa = a.ToString("0.##"); // 123.46
string sb = b.ToString("0.##"); // 123.4
string sc = c.ToString("0.##"); // 123
Esto funcionó para mí!
String amount= "123.0000";
String.Format("{0:0.##}", amount); // "123.00"
Lo siento por reactivar esta pregunta, pero no encontré la respuesta correcta aquí.
Al dar formato a los números, puede utilizar 0
como lugar obligatorio y #
como lugar opcional.
Asi que:
// just two decimal places
String.Format("{0:0.##}", 123.4567); // "123.46"
String.Format("{0:0.##}", 123.4); // "123.4"
String.Format("{0:0.##}", 123.0); // "123"
También puedes combinar 0
con #
.
String.Format("{0:0.0#}", 123.4567) // "123.46"
String.Format("{0:0.0#}", 123.4) // "123.4"
String.Format("{0:0.0#}", 123.0) // "123.0"
Para este método de formateo siempre se utiliza CurrentCulture
. Para algunas culturas .
se cambiará a,.
Me temo que no hay un formato incorporado que haga esto. Deberá usar un formato diferente dependiendo de si el valor es un número entero o no. O siempre formatee con 2 decimales, y luego manipule la cadena para eliminar cualquier ".00".
No sé de ninguna manera poner una condición en el especificador de formato, pero puede escribir su propio formateador:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// all of these don''t work
Console.WriteLine("{0:C}", 10);
Console.WriteLine("{0:00.0}", 10);
Console.WriteLine("{0:0}", 10);
Console.WriteLine("{0:0.00}", 10);
Console.WriteLine("{0:0}", 10.0);
Console.WriteLine("{0:0}", 10.1);
Console.WriteLine("{0:0.00}", 10.1);
// works
Console.WriteLine(String.Format(new MyFormatter(),"{0:custom}", 9));
Console.WriteLine(String.Format(new MyFormatter(),"{0:custom}", 9.1));
Console.ReadKey();
}
}
class MyFormatter : IFormatProvider, ICustomFormatter
{
public string Format(string format, object arg, IFormatProvider formatProvider)
{
switch (format.ToUpper())
{
case "CUSTOM":
if (arg is short || arg is int || arg is long)
return arg.ToString();
if (arg is Single || arg is Double)
return String.Format("{0:0.00}",arg);
break;
// Handle other
default:
try
{
return HandleOtherFormats(format, arg);
}
catch (FormatException e)
{
throw new FormatException(String.Format("The format of ''{0}'' is invalid.", format), e);
}
}
return arg.ToString(); // only as a last resort
}
private string HandleOtherFormats(string format, object arg)
{
if (arg is IFormattable)
return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
if (arg != null)
return arg.ToString();
return String.Empty;
}
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return this;
return null;
}
}
}
Para que el código sea más claro en el que escribió Kahia (está claro, pero se vuelve complicado cuando desea agregarle más texto) ... pruebe esta solución simple.
if (Math.Round((decimal)user.CurrentPoints) == user.CurrentPoints)
ViewBag.MyCurrentPoints = String.Format("Your current Points: {0:0}",user.CurrentPoints);
else
ViewBag.MyCurrentPoints = String.Format("Your current Points: {0:0.0}",user.CurrentPoints);
Tuve que agregar la conversión extra (decimal) para que Math.Round comparara las dos variables decimales.
Pregunta antigua pero quería agregar la opción más simple en mi opinión.
Sin miles de separadores:
value.ToString(value % 1 == 0 ? "F0" : "F2")
Con miles de separadores:
value.ToString(value % 1 == 0 ? "N0" : "N2")
Lo mismo pero con String.Format :
String.Format(value % 1 == 0 ? "{0:F0}" : "{0:F2}", value) // Without thousands separators
String.Format(value % 1 == 0 ? "{0:N0}" : "{0:N2}", value) // With thousands separators
Si lo necesitas en muchos lugares , usaría esta lógica en un método de extensión :
public static string ToCoolString(this decimal value)
{
return value.ToString(value % 1 == 0 ? "N0" : "N2"); // Or F0/F2 ;)
}
Si ninguna de las otras respuestas funciona para usted, puede ser porque está vinculando la ContentProperty
de contenido de un control en la función OnLoad
, lo que significa que esto no funcionará:
private void UserControl_Load(object sender, RoutedEventArgs e)
{
Bind.SetBindingElement(labelName, String.Format("{0:0.00}", PropertyName), Label.ContentProperty)
}
La solución es simple: hay una propiedad ContentStringFormat
en xaml. Así que cuando crees la etiqueta haz esto:
//if you want the decimal places definite
<Label Content="0" Name="labelName" ContentStringFormat="0.00"/>
O
//if you want the decimal places to be optional
<Label Content="0" Name="labelName" ContentStringFormat="0.##"/>
Si su programa necesita ejecutarse rápidamente, llame a value.ToString (formatString) para un rendimiento de formateo de cadena ~ 35% más rápido en relación con $ "{value: formatString}" y string.Format (formatString, value).
Datos
Código
using System;
using System.Diagnostics;
public static class StringFormattingPerformance
{
public static void Main()
{
Console.WriteLine("C# String Formatting Performance");
Console.WriteLine("Milliseconds Per 1 Million Iterations - Best Of 5");
long stringInterpolationBestOf5 = Measure1MillionIterationsBestOf5(
(double randomDouble) =>
{
return $"{randomDouble:0.##}";
});
long stringDotFormatBestOf5 = Measure1MillionIterationsBestOf5(
(double randomDouble) =>
{
return string.Format("{0:0.##}", randomDouble);
});
long valueDotToStringBestOf5 = Measure1MillionIterationsBestOf5(
(double randomDouble) =>
{
return randomDouble.ToString("0.##");
});
Console.WriteLine(
$@" $""{{value:formatString}}"": {stringInterpolationBestOf5} ms
string.Format(formatString, value): {stringDotFormatBestOf5} ms
value.ToString(formatString): {valueDotToStringBestOf5} ms");
}
private static long Measure1MillionIterationsBestOf5(
Func<double, string> formatDoubleUpToTwoDecimalPlaces)
{
long elapsedMillisecondsBestOf5 = long.MaxValue;
for (int perfRunIndex = 0; perfRunIndex < 5; ++perfRunIndex)
{
var random = new Random();
var stopwatch = Stopwatch.StartNew();
for (int i = 0; i < 1000000; ++i)
{
double randomDouble = random.NextDouble();
formatDoubleUpToTwoDecimalPlaces(randomDouble);
}
stopwatch.Stop();
elapsedMillisecondsBestOf5 = Math.Min(
elapsedMillisecondsBestOf5, stopwatch.ElapsedMilliseconds);
}
return elapsedMillisecondsBestOf5;
}
}
Salida de código
C# String Formatting Performance
Milliseconds Per 1 Million Iterations - Best Of 5
$"{value:formatString}": 419 ms
string.Format(formatString, value): 419 ms
value.ToString(formatString): 264 ms
Referencias
Cadenas de formato numérico personalizadas [docs.microsoft.com]
String.Format ("{0: 0.00}", Convert.ToDecimal (totalPrice))
Una forma poco elegante sería:
var my = DoFormat(123.0);
Con DoFormat
es algo como:
public static string DoFormat( double myNumber )
{
var s = string.Format("{0:0.00}", myNumber);
if ( s.EndsWith("00") )
{
return ((int)myNumber).ToString();
}
else
{
return s;
}
}
No elegante pero trabajando para mí en situaciones similares en algunos proyectos.
algo como esto funcionará también:
String.Format("{0:P}", decimal.Parse(Resellers.Fee)).Replace(".00", "")
tratar
double myPrice = 123.0;
String.Format(((Math.Round(myPrice) == myPrice) ? "{0:0}" : "{0:0.00}"), myPrice);