C# 使用字符串格式显示最多2位小数或简单整数

C# 使用字符串格式显示最多2位小数或简单整数,c#,regex,string-formatting,number-formatting,C#,Regex,String Formatting,Number Formatting,我有一个要显示的价格字段,有时可以是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.

我有一个要显示的价格字段,有时可以是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"

恐怕没有内置的格式可以做到这一点。根据值是否为整数,必须使用不同的格式。或始终将格式设置为小数点后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;
    }
}
public static string MyCustomFormat( double myNumber )
{
    var str (string.Format("{0:0.00}", myNumber))
    return (str.EndsWith(".00") ? str.Substring(0, strLastIndexOf(".00")) : str;
}

虽然不优雅,但在一些项目中,在类似情况下为我工作。

我不知道如何在格式说明符中设置条件,但您可以编写自己的格式设置程序:

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 DoFormat( double myNumber )
{
    var s = string.Format("{0:0.00}", myNumber);

    if ( s.EndsWith("00") )
    {
        return ((int)myNumber).ToString();
    }
    else
    {
        return s;
    }
}
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);

我必须添加额外的cast(decimal)来进行数学运算。四舍五入比较两个十进制变量。

很抱歉重新激活此问题,但我在这里找不到正确的答案

在格式化数字时,您可以将
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"
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)
}
您还可以将
0
#
组合使用

为此,始终使用格式化方法
CurrentCulture
。对于某些区域性,
将更改为

对原问题的答复: 最简单的解决方案来自@Andrew()。所以我个人会用这样的东西:

var number = 123.46;
String.Format(number % 1 == 0 ? "{0:0}" : "{0:0.00}", number)
这对我有用

String amount= "123.0000";
String.Format("{0:0.##}", amount);      // "123.00"

如果其他答案都不适用于您,可能是因为您在
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"/>
//如果要确定小数位数

//如果希望小数位数是可选的

老问题,但我想添加我认为最简单的选项

数千个分离器:

value.ToString(value % 1 == 0 ? "F0" : "F2")
value.ToString(value % 1 == 0 ? "N0" : "N2")
带有数千个分隔符:

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 ;)
}
如果您在许多地方需要它,我将在扩展方法中使用此逻辑:

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","");
}
尝试:


如果您的程序需要快速运行,请调用value.ToString(formatString),相对于$“{value:formatString}”和string.Format(formatString,value),字符串格式化性能提高约35%

资料

代码 工具书类


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

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

所以,我是这样做的:

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);
    }
}
用法示例:

// 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"
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)
}

最近的一个项目也有类似的要求。我写了这个十进制扩展方法, 它使用。除了删除零之外,它还可以选择十进制数字精度、货币符号、分隔符和区域性

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

RE的可能重复:“我想要的是仅在输入该价格的小数点后2位显示价格”--因此,如果用户键入“100.00”,您希望显示“100.00”,但如果他们键入“100”,您只希望显示“100”?--数字类型只跟踪数字的值——而不是用户输入的不重要数字中的哪些不是——因此您需要使用字符串。@BinaryWorrier我认为这个问题可能是重复的,但它有更好、更完整的答案。在我看来,另一个应该被标记为这一个的副本。只需添加。替换(“.00”,即“”)您所需要的就是
value
.ToString(“0.##”);这对我来说不起作用,因为TrimEnd似乎需要像{',',',',','}这样的字符数组,而不是像.00这样的字符串-看你是对的-不确定我怎么会错过它。我已更新以正常工作。根据当前线程的
CurrentCulture
,十进制分隔符可能不是
。除非
CultureInfo.InvariantCulture
string.Format
一起使用,否则您必须检查
CultureInfo.NumberFormat.NumberDecimalSeparator
的值,这相当不雅。这并不是真正要问的问题——但如果是这样的话——为什么不直接使用string.Format(“{0:0.00}”)。替换(“.00)”,“”)?@BrainSlugs83:根据当前线程的
CurrentCulture
,十进制分隔符可能不是
。除非