使用字符串格式显示最多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"
957136 次浏览

恐怕没有内置格式可以做到这一点。您必须使用不同的格式,这取决于该值是否为整数。或者始终格式化到小数点后2位,然后操作字符串以删除任何尾随的“.00”。

试一试

double myPrice = 123.0;


String.Format(((Math.Round(myPrice) == myPrice) ? "{0:0}" : "{0:0.00}"), myPrice);

不优雅的说法是:

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;
}
}

不是很优雅,但在一些项目中,我遇到了类似的情况。

我不知道如何在格式说明符中放入一个条件,但你可以编写自己的格式化程序:

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;
}
}
}

下面是Uwe Keim的方法的替代方案,它仍然保持相同的方法调用:

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;
}

像这样的东西也可以:

String.Format("{0:P}", decimal.Parse(Resellers.Fee)).Replace(".00", "")

为了让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。对两个十进制变量进行四舍五入比较。

很抱歉重新激活这个问题,但我在这里没有找到正确的答案。

在格式化数字时,可以使用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)

如果其他答案都不适合你,这可能是因为你在OnLoad函数中绑定了控件的ContentProperty,这意味着这将不起作用:

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.##"/>

老问题了,但我想在我看来添加一个最简单的选项。

没有千分离器:

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

这是一个常见的格式化浮点数用例。

不幸的是,所有内置的单字母格式字符串(例如。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

简单的一行代码:

public static string DoFormat(double myNumber)
{
return string.Format("{0:0.00}", myNumber).Replace(".00","");
}

试一试:

String.Format("{0:0.00}", Convert.ToDecimal(totalPrice));

如果你的程序需要快速运行,调用value. tostring (formatString)可以获得比$"{value:formatString}"和string快35%的字符串格式化性能。格式(formatString值)。

数据

 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(
$@"            $""\{\{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

参考文献

自定义数字格式字符串[learn.microsoft.com]

Qt图表BarChart示例[doc.qt.io] .io

当处理来自(T-)SQL数据库的小数时,您希望能够将可为空的小数和不可为空的小数转换为x位小数,并且能够根据表定义轻松地检查代码——当然,还要向用户显示正确的小数数量。

不幸的是,实体框架不会自动将SQL decimal(18,2)之类的东西转换成具有相同小数点数的。net等价值(因为只有具有完全精度的小数可用)。您必须手动截断小数点数位。

所以,我是这样做的:

public static class Extensions
{
public static string ToStringDecimal(this decimal d, byte decimals)
{
var fmt = (decimals>0) ? "0." + new string('0', decimals) : "0";
return d.ToString(fmt);
}


public static string ToStringDecimal(this decimal? d, byte decimals)
{
if (!d.HasValue) return "";
return ToStringDecimal(d.Value, decimals);
}
}

使用示例:

void Main()
{
decimal d = (decimal)1.2345;
decimal? d2 = null;


Console.WriteLine(d.ToStringDecinal(2)); // prints: "1.23" (2 decimal places)
Console.WriteLine(d.ToStringDecinal(0)); // prints: "1" (show integer number)
Console.WriteLine(d2.ToStringDecimal(2)); // prints: "" (show null as empty string)
}
最近的一个项目也有类似的要求。我写了这个十进制扩展法, 它使用货币(“C")格式说明符。除了删除零之外,它还具有十进制数字精度、货币符号、分隔符和区域性选项
public static DecimalExtension{


public static string ToCurrency(this decimal val,
int precision = 2,
bool currencySymbol = false,
bool separator = false,
CultureInfo culture = null)
{
if(culture == null) culture = new CultureInfo("en-US");
                                                   

NumberFormatInfo nfi = culture.NumberFormat;
nfi.CurrencyDecimalDigits = precision;
            

string zeros = new String('0', precision);
                    

//Remove zeros
var result = val.ToString("C",fi).Replace(nfi.CurrencyDecimalSeparator + zeros,"");
                     

if(!separator) result = result.Replace(nfi.CurrencyGroupSeparator,"");
                    

return currencySymbol? result: result.Replace(nfi.CurrencySymbol,"");
}
}

例子:

decimal Total = 123.00M;
Console.WriteLine(Total.ToCurrency());
//output: 123


decimal Total = 1123.12M;
Console.WriteLine(Total.ToCurrency());
//Output:  1123.12


Console.WriteLine(Total.ToCurrency(4));
//Output:  1123.1200


Console.WriteLine(Total.ToCurrency(2,true,true));
//output:  $1,123.12
 

CultureInfo culture = new CultureInfo("pt-BR")  //Brazil
Console.WriteLine(Total.ToCurrency(2,true,true, culture));
//output:  R$ 1.123,12

试试这个

string Output = String.Format("{0:0.00}", Decimal.Parse(InputStringValue));

试试这个:

var number = 123.4567;
var str = number.ToString("N2");