【问题标题】:Formatting double as string in C#在C#中将double格式化为字符串
【发布时间】:2010-09-26 04:23:30
【问题描述】:

我有一个 Double,其值可能在 0.000001 到 1,000,000,000.000 之间

我希望将此数字格式化为字符串,但有条件地取决于其大小。因此,如果它非常小,我想使用以下格式对其进行格式化:

String.Format("{0:.000000000}", number);

如果不是那么小,比如 0.001,那么我想使用类似的东西

String.Format("{0:.00000}", number);

如果结束了,比如 1,000,然后将其格式化为:

String.Format("{0:.0}", number);

有没有一种聪明的方法可以根据我要格式化的值的大小来构造这个格式字符串?

【问题讨论】:

    标签: c# .net formatting


    【解决方案1】:

    跟进 OwenP(以及“扩展”tvanfosson):

    如果它足够常见,并且您使用的是 C# 3.0,我会将其转换为 double 上的扩展方法:

    class MyExtensions 
    {
        public static string ToFormmatedString(this double d)
        {
            // Take d and implement tvanfosson's code
        }
    }
    

    现在你可以在任何有双倍的地方做:

    double d = 1.005343;
    string d_formatted = d.ToFormattedString();
    

    【讨论】:

      【解决方案2】:

      如果是我,我会编写一个自定义包装类并将 tvanfosson 的代码放入其ToString 方法中。这样你仍然可以使用双精度值,但几乎在所有情况下你都会得到正确的字符串表示。它看起来像这样:

      class FormattedDouble
      { 
          public double Value { get; set; }
      
          protected overrides void ToString()
          {
              // tvanfosson's code to produce the right string
          }
      }
      

      也许把它做成一个结构可能会更好,但我怀疑它会产生很大的不同。你可以像这样使用这个类:

      var myDouble = new FormattedDouble();
      myDouble.Value = Math.Pi;
      Console.WriteLine(myDouble);
      

      【讨论】:

        【解决方案3】:

        您问题中的前两个 String.Format 可以通过自动删除尾随零来解决:

        String.Format("{0:#,##0.########}", number);
        

        最后一个你可以通过调用 Math.Round(number,1) 来解决超过 1000 的值,然后使用相同的 String.Format。

        类似:

        String.Format("{0:#,##0.########}", number<1000 ? number : Math.Round(number,1));
        

        【讨论】:

          【解决方案4】:

          使用双精度绝对值的 Math.Log10 来计算小数位左侧(如果为正)或右侧(如果为负)需要多少个 0。根据该值选择格式字符串。您需要单独处理零值。

          string s;
          double epislon = 0.0000001; // or however near zero you want to consider as zero
          if (Math.Abs(value) < epislon) {
              int digits = Math.Log10( Math.Abs( value ));
              // if (digits >= 0) ++digits; // if you care about the exact number
              if (digits < -5) {
                 s = string.Format( "{0:0.000000000}", value );
              }
              else if (digits < 0) {
                 s = string.Format( "{0:0.00000})", value );
              }
              else {
                 s = string.Format( "{0:#,###,###,##0.000}", value );
              }
          }
          else {
              s = "0";
          }
          

          或者根据位数动态构造。

          【讨论】:

            【解决方案5】:

            使用 # 字符作为字符串中的可选位置:

            string.Format("{0:#,###,##0.000}", number);
            

            我认为你不能像这样控制小数位数,因为双精度可能会搞砸。

            要封装决定输出多少小数位的逻辑,您可以查看创建自定义格式化程序。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-10-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-05-10
              • 1970-01-01
              相关资源
              最近更新 更多