Использование строкового формата для отображения десятичного числа до 2-х знаков или простого целого числа
У меня есть поле цены для отображения, которое иногда может быть либо 100 , либо 100.99 или 100.9, что я хочу, чтобы отобразить цену в 2 десятичных знаках, только если десятичные знаки вводятся для этой цены, например, если ее 100, поэтому она должна показывать только 100, а не 100.00, и если цена 100.2, она должна отображать 100.20 аналогично для 100.22 должно быть одинаковым . Я погуглил и наткнулся на некоторые примеры, но они не соответствовали именно тому, что я хотел:
// 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"
15 ответов:
неэлегантным способом было бы:
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; } }
не элегантно, но работает для меня в подобных ситуациях в некоторых проектах.
извините за повторную активацию этого вопроса, но я не нашел правильного ответа здесь.
в форматировании чисел вы можете использовать
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
. Для некоторых культур.
будет заменен на,
.
это общий форматирование с плавающим числом прецедент.
к сожалению, все встроенные строки однобуквенного формата (например. 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
попробовать
double myPrice = 123.0; String.Format(((Math.Round(myPrice) == myPrice) ? "{0:0}" : "{0:0.00}"), myPrice);
старый вопрос, но я хотел бы добавить простой вариант на мой взгляд.
без тысяч сепараторы:
value.ToString(value % 1 == 0 ? "F0" : "F2")
С тысяч сепараторы:
value.ToString(value % 1 == 0 ? "N0" : "N2")
то же самое, но с строку.Формат:
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 ;) }
Я не знаю, в любом случае, чтобы поставить условие в спецификатор формата, но вы можете написать свой собственный форматер:
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; } } }
простой код в одну строку:
public static string DoFormat(double myNumber) { return string.Format("{0:0.00}", myNumber).Replace(".00",""); }
вот альтернатива методу Уве Кейма, который все равно будет поддерживать тот же вызов метода:
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; }
Я боюсь, что нет встроенного формата, который будет делать это. Вам придется использовать другой формат в зависимости от того, является ли значение целым числом или нет. Или всегда форматируйте до 2 десятичных знаков, а затем манипулируйте строкой, чтобы удалить любой трейлинг ".00".
если ни один из других ответов не работает для вас, это может быть потому, что вы связываете
ContentProperty
управления вOnLoad
функция, которая означает, что это не будет работать:private void UserControl_Load(object sender, RoutedEventArgs e) { Bind.SetBindingElement(labelName, String.Format("{0:0.00}", PropertyName), Label.ContentProperty) }
решение простое: есть
ContentStringFormat
свойство в xaml. Поэтому при создании метки сделайте следующее://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.##"/>
что-то вроде этого будет работать:
String.Format("{0:P}", decimal.Parse(Resellers.Fee)).Replace(".00", "")
чтобы сделать код более ясным, что Кахия написал в (это ясно, но становится сложнее, когда вы хотите добавить больше текста к нему)...попробуйте это простое решение.
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);
мне пришлось добавить дополнительное приведение (десятичное), чтобы иметь математику.Круглое сравнение двух десятичных переменных.
Если ваша программа должна работать быстро, на вызов.ToString (formatString) для ~35% более быстрой производительности форматирования строк относительно $"{value:formatString}" и string.Формата(формата, значения).
сведения
код
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; } }
Исходный Код
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]