Использование String Format для отображения десятичной до 2-х мест или простого целого
У меня есть поле цены для отображения, которое иногда может быть 100 или 100.99 или 100.9. То, что я хочу, это отобразить цену в 2 десятичных знаках, только если десятичные числа введены для этой цены, например, если ее 100 так он должен показывать только 100 не 100,00, и если цена 100,2, она должна отображать 100.20, так же для 100.22 должна быть такой же.
Я googled и наткнулся на некоторые примеры, но они не соответствовали точно, что я хотел:
// 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"
Ответы
Ответ 1
Неэлегантным способом было бы:
var my = DoFormat(123.0);
С DoFormat
будет что-то вроде:
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;
}
}
Не элегантный, но работающий для меня в подобных ситуациях в некоторых проектах.
Ответ 2
Извините за повторную активацию этого вопроса, но я не нашел здесь правильного ответа.
При форматировании чисел вы можете использовать 0
в качестве обязательного места и #
в качестве необязательного места.
Итак:
// 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"
Вы также можете комбинировать 0
с #
.
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"
Для этого всегда используется метод форматирования CurrentCulture
. Для некоторых культур .
будет изменено на ,
.
Ответ на оригинальный вопрос:
Самым простым решением является @Andrew (здесь). Так что я бы лично использовал что-то вроде этого:
var number = 123.46;
String.Format(number % 1 == 0 ? "{0:0}" : "{0:0.00}", number)
Ответ 3
Это обычный вариант использования плавающего числа с форматированием.
К сожалению, все встроенные однобуквенные форматированные строки (например, F, G, N) не достигнут этого напрямую.
Например, num.ToString("F2")
всегда будет показывать 2 десятичных знака, например 123.40
.
Вам придется использовать шаблон 0.##
, даже если он выглядит немного подробным.
Полный пример кода:
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
Ответ 4
Старый вопрос, но я хотел добавить самый простой вариант, на мой взгляд.
Без тысяч разделителей:
value.ToString(value % 1 == 0 ? "F0" : "F2")
С разделителями тысяч:
value.ToString(value % 1 == 0 ? "N0" : "N2")
То же самое, но с 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
Если вам это нужно в во многих местах, я бы использовал эту логику в методе расширения:
public static string ToCoolString(this decimal value)
{
return value.ToString(value % 1 == 0 ? "N0" : "N2"); // Or F0/F2 ;)
}
Ответ 5
попробовать
double myPrice = 123.0;
String.Format(((Math.Round(myPrice) == myPrice) ? "{0:0}" : "{0:0.00}"), myPrice);
Ответ 6
Я вообще не знаю, как поставить условие в спецификаторе формата, но вы можете написать собственный форматтер:
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;
}
}
}
Ответ 7
Вот альтернатива методу Уве Кейма, которая по-прежнему будет поддерживать тот же метод:
var example1 = MyCustomFormat(123.1); // Output: 123.10
var example2 = MyCustomFormat(123.95); // Output: 123.95
var example3 = MyCustomFormat(123); // Output: 123
С MyCustomFormat
будет что-то вроде:
public static string MyCustomFormat( double myNumber )
{
var str (string.Format("{0:0.00}", myNumber))
return (str.EndsWith(".00") ? str.Substring(0, strLastIndexOf(".00")) : str;
}
Ответ 8
Простой код:
public static string DoFormat(double myNumber)
{
return string.Format("{0:0.00}", myNumber).Replace(".00","");
}
Ответ 9
Я боюсь, что нет встроенного формата, который сделает это. Вам придется использовать другой формат в зависимости от того, является ли значение целым числом или нет. Или всегда форматируйте до двух знаков после запятой и затем произвольно манипулируйте строкой, чтобы удалить любые завершающие ".00".
Ответ 10
Если ваша программа нуждается в быстром запуске, вызовите value.ToString(formatString), чтобы повысить производительность форматирования строки на ~ 35% по сравнению с $ "{value: formatString}" и string.Format(formatString, value).
данных![C# String Formatting Performance - VS2017 15.4.5]()
Код
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(
[email protected]" $""{{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;
}
}
Вывод кода
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
Ссылки
Пользовательские строки числового формата [docs.microsoft.com]
Пример Qt Charts BarChart [doc.qt.io]
Ответ 11
Если ни один из других ответов не работает для вас, возможно, это связано с тем, что вы привязываете ContentProperty
элемента управления в функции OnLoad
, что означает, что это не сработает:
private void UserControl_Load(object sender, RoutedEventArgs e)
{
Bind.SetBindingElement(labelName, String.Format("{0:0.00}", PropertyName), Label.ContentProperty)
}
Решение прост: в xaml есть свойство ContentStringFormat
. Поэтому, когда вы создаете ярлык, сделайте следующее:
//if you want the decimal places definite
<Label Content="0" Name="labelName" ContentStringFormat="0.00"/>
или
//if you want the decimal places to be optional
<Label Content="0" Name="labelName" ContentStringFormat="0.##"/>
Ответ 12
что-то вроде этого тоже будет работать:
String.Format("{0:P}", decimal.Parse(Resellers.Fee)).Replace(".00", "")
Ответ 13
Пытаться:
String.Format("{0:0.00}", Convert.ToDecimal(totalPrice));
Ответ 14
Чтобы сделать код более понятным, что написал Kahia (это понятно, но становится сложным, если вы хотите добавить к нему больше текста)... попробуйте это простое решение.
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);
Мне пришлось добавить дополнительный листинг (десятичный), чтобы Math.Round сравнивал две десятичные переменные.
Ответ 15
Это сработало для меня!
String amount= "123.0000";
String.Format("{0:0.##}", amount); // "123.00"