使用字符串格式显示最多2位的十进制或简单整数

Mr *_*r A 266 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.Format("{0:0.00}", 123.4);         // "123.40"
String.Format("{0:0.00}", 123.0);         // "123.00"
Run Code Online (Sandbox Code Playgroud)

Gh6*_*h61 485

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

在格式化数字中,您可以将其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"
Run Code Online (Sandbox Code Playgroud)

你也可以结合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"
Run Code Online (Sandbox Code Playgroud)

因为总是使用这种格式化方法CurrentCulture.对于一些文化.将改为,.

  • 哎呀,我再读一遍,你说对了.所以,这不是正确的答案,但至少有人可能觉得这很有用. (35认同)
  • 起初,我认为这应该是答案,直到我多次重读原始问题.OP并不完全清楚他究竟想要什么,但如果有人输入分数,他似乎总是想要2位小数.所以,如果有人进入1.1,那么他会想要1.10; 这段代码不会这样做. (20认同)
  • OP所需的内容可以通过以下方式实现:http://stackoverflow.com/a/33180829/2321042 (3认同)

Uwe*_*eim 145

一种不雅的方式是:

var my = DoFormat(123.0);
Run Code Online (Sandbox Code Playgroud)

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

不优雅,但在某些项目的类似情况下为我工作.

  • @ BrainSlugs83:取决于当前线程的`CurrentCulture`,小数分隔符可能不是`.`.除非`CultureInfo.InvariantCulture`与`string.Format`一起使用,否则你必须检查`CultureInfo.NumberFormat.NumberDecimalSeparator`的值,这将是一个真正的PITA.:) (16认同)
  • 这不是真正被问到的问题 - 但事实如此 - 为什么不使用string.Format("{0:0.00}").替换(".00","")? (5认同)
  • 这个答案就是一个“重新发明方轮”的案例。没有考虑文化或这已经由 .NET 处理的事实。 (2认同)

det*_*ale 58

这是一种常见的格式化浮点数用例.

不幸的是,所有内置的单字母格式字符串(例如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
Run Code Online (Sandbox Code Playgroud)

  • 但他想要123.40而不是123.4. (7认同)
  • 不解决这个问题而是解决我的问题.我赞成这个让其他人看到. (7认同)

And*_*rew 39

老问题,但我想在我看来添加最简单的选项.

没有千位分隔符:

value.ToString(value % 1 == 0 ? "F0" : "F2")
Run Code Online (Sandbox Code Playgroud)

数千个分隔符:

value.ToString(value % 1 == 0 ? "N0" : "N2")
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

如果你在很多地方需要它,我会在扩展方法中使用这个逻辑:

public static string ToCoolString(this decimal value)
{
    return value.ToString(value % 1 == 0 ? "N0" : "N2"); // Or F0/F2 ;)
}
Run Code Online (Sandbox Code Playgroud)


Yah*_*hia 27

尝试

double myPrice = 123.0;

String.Format(((Math.Round(myPrice) == myPrice) ? "{0:0}" : "{0:0.00}"), myPrice);
Run Code Online (Sandbox Code Playgroud)

  • string.Format((number%1)== 0?"{0:0}":"{0:0.00}",number); (5认同)

Tim*_*han 7

无论如何我都不知道在格式说明符中添加条件,但是你可以编写自己的格式化程序:

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*eve 6

这是Uwe Keim方法的替代方法,它仍将保持相同的方法调用:

var example1 = MyCustomFormat(123.1);  // Output: 123.10
var example2 = MyCustomFormat(123.95); // Output: 123.95
var example3 = MyCustomFormat(123);    // Output: 123
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 根据当前线程的"CurrentCulture",小数分隔符可能不是`.`.除非`CultureInfo.InvariantCulture`与`string.Format`一起使用,否则你必须检查`CultureInfo.NumberFormat.NumberDecimalSeparator`的值,这是相当不优雅的. (5认同)

Phi*_*yck 6

简单的一行代码:

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


Nei*_*ice 6

如果您的程序需要快速运行,则调用value.ToString(formatString)可使字符串格式化性能比$“ {value:formatString}”和string.Format(formatString,value)快约35%。

数据

C#字符串格式化性能-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;
   }
}
Run Code Online (Sandbox Code Playgroud)

代码输出

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;
   }
}
Run Code Online (Sandbox Code Playgroud)

参考文献

Custom Numeric Format Strings [docs.microsoft.com]

Qt Charts BarChart Example [doc.qt.io]


小智 6

尝试这个:

var number = 123.4567;
var str = number.ToString("N2");
Run Code Online (Sandbox Code Playgroud)


Nik*_*cke 5

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


小智 5

尝试:

String.Format("{0:0.00}", Convert.ToDecimal(totalPrice));
Run Code Online (Sandbox Code Playgroud)