【问题标题】:format decimal values in grid在网格中格式化十进制值
【发布时间】:2015-04-07 20:17:37
【问题描述】:

我正在尝试为数据库中的几个十进制检索字段实现自定义格式。我的价格字段中有1122.454540000 之类的数据。我想在自定义格式化后在网格中显示它。如果小数点后的前四个字段中的至少一个不为零,我想在小数点后显示四位数字。如果我有1122.000100 之类的字段,我想将其显示为1122.0001,但我有9876.000000 之类的值,那么我只想显示没有任何小数点的9876。目前一切正常

string.Format("{0:F4}", Convert.ToDecimal(DataBinder.Eval(Container.DataItem, "Price")))

但我在特定情况下遇到了一个问题。当我得到1122.40001122.5400 之类的值时,它只显示1122.41122.54,而不是显示所有四位数字,无论最后一个尾随数字是否为零。知道我是否朝着正确的方向前进吗?

【问题讨论】:

标签: c# asp.net


【解决方案1】:

如果要将 42.0000001 格式化为 42

可以修改下面的解决方案来做到这一点。 但基本上,您只想从字符串中删除 .00..

您可以使用 RegEx 来做到这一点:

public string Format(string format, double value)
{
    var regex = new Regex(@"^(?<IntPart>.*)([.,]0*)$");
    var s = String.Format("{0:F4}", value);
    var match = regex.Match(s);
    if (match.Success)
    {
        return match.Groups["IntPart"].Value;
    }
    return s;
}

Console.WriteLine(Format("{0:F4}", 1.35687));    // 1.3569
Console.WriteLine(Format("{0:F4}", 1.35));       // 1.3500
Console.WriteLine(Format("{0:F4}", 1));          // 1
Console.WriteLine(Format("{0:F4}", 42.000001));  // 42

如果要将 42.0000001 格式化为 42.0000。

您需要测试该值的小数部分(准确为 0)。

我认为很好地执行它的唯一方法是使用ICustomFormatter

我将创建 F_XX 格式,根据变量是否为 F0FXX整数与否。 (在您的情况下,F_4 将是 F0F4)。

这里是第一次尝试,:

public class MyCustomFormatter : IFormatProvider, ICustomFormatter
{
    // Match "F_XX" where XX are digits.
    private readonly Regex _regex = new Regex("F_(?<DigitCount>\\d+)");

    // IFormatProvider.GetFormat implementation.
    public object GetFormat(Type formatType)
    {
        // Determine whether custom formatting object is requested.
        if (formatType == typeof(ICustomFormatter))
            return this;
        else
            return null;
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        var shouldUseF0 = false;

        var match = _regex.Match(format);

        // Detect F_XX format.
        if (match.Success)
        {
            // Manage float.
            if (arg is float)
            {
                if (((float) arg)%1 == 0)
                {
                    shouldUseF0 = true;
                }
            }

            // Manage double.
            if (arg is double)
            {
                if (((double) arg)%1 == 0)
                {
                    shouldUseF0 = true;
                }
            }

            // TODO: Manage int, long...

            if (shouldUseF0)
            {
                format = "F0";
            }
            else
            {
                // Build the FXX format.
                format = "F" + match.Groups["DigitCount"].Value;
            }
        }

        if (arg is IFormattable) return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
        if (arg != null) return arg.ToString();
        return String.Empty;
    }
}

结果如下:

Console.WriteLine(String.Format(cf, "{0:F_4}", 1.35678));  // 1.3568
Console.WriteLine(String.Format(cf, "{0:F_4}", 1.35));     // 1.3500
Console.WriteLine(String.Format(cf, "{0:F_4}", 1.00));     // 1

【讨论】:

    【解决方案2】:

    如果有一些解决方法是可能的,那么试试这个

       double price= 12.00300;
       string op = null;
       price= Double.Parse(string.Format("{0:0.0000}", value));
       if ((price % 1) != 0)
         op =   string.Format("{0:#.0000}", price);
       else
         op =  string.Format("{0}", price);
    

    您可以像使用实用功能一样使用它,也可以根据需要进行更改。

    1. 对于 12.000000 => 12
    2. 对于 12.001000 => 12.0010
    3. 对于 12.333333 => 12.3333

    【讨论】:

    • 它将42.0000001 格式化为42.0000。 OP需要42
    【解决方案3】:

    很简单

      Math.Round(Convert.ToDecimal(DataBinder.Eval(Container.DataItem, "Price")), 4).ToString("N4")
    

    控制台示例

    static void Main(string[] args)
        {
    
            Console.WriteLine(Math.Round(1122.454540000, 4).ToString("N4"));  // output 1122.4545
            Console.WriteLine(Math.Round(1122.000100, 4).ToString("N4")); // output 1122.0001
            Console.WriteLine(Math.Round(9876.000000, 4).ToString("N4"));// output 9876.0000
            Console.WriteLine(Math.Round(1122.4000, 4).ToString("N4"));// output 1122.4000
            Console.WriteLine(Math.Round(1122.5400, 4).ToString("N4"));// output 1122.5400
                Console.ReadLine();
    
        }
    

    【讨论】:

    • 您的答案是针对实际问题吗?根据问题最后两个应该是 1122.4000 和 1122.5400!
    • 您对1122.4 的输出是1122.4 而不是1122.4000,这不是所要求的。
    • 对不起,我理解错了。。编辑答案@yogi970 和@o
    • 您对9876.0 的输出是9876.0000 而不是9876,这不是所要求的。另外,您不需要Math.Round 是您使用标准格式(N4,...)。
    • 感谢您的回复,但我不想四舍五入我的数据。如果前四个数字中的任何一个不为零,我只想显示小数部分。我想要的 1122.1 输出是 1122.1000 和 1122.000 仅作为 1122。
    【解决方案4】:

    试试这个:

    string.Format("{0:#.0000}", Convert.ToDecimal(DataBinder.Eval(Container.DataItem, "Price")))
    

    # 代表任何数字,0 代表0 如果没有数字,或数字本身。
    More on MSDN about the Custom Numeric formatting in .NET.
    不幸的是,如果您想为整数隐藏零,这种方法不起作用

    Great article mentioned in other answer

    设置固定的小数位数
    这与上面的示例类似,但在我们的格式字符串中,我们使用的是散列 (‘#’)
    将使用零('0'),如下所示:

    string.Format("{0:0.00}", 256.583); // "256.58"
    string.Format("{0:0.00}", 256.586); // "256.59"
    string.Format("{0:0.00}", 256.58);  // "256.58"
    string.Format("{0:0.00}", 256.5);   // "256.50"
    string.Format("{0:0.00}", 256.0);   // "256.00" - No luck here
    

    更新
    正如我所说,如果数字在小数部分没有数字,则不显示前导零是行不通的,因此您可以在格式化之前使用Math.Truncate 方法检查:

    var decimalValue = Convert.ToDecimal(DataBinder.Eval(Container.DataItem, "Price"));
    string.Format((decimalValue - Math.Truncate(decimalValue)) < 0.0001 ? "{0:#.####}" : {0:#.0000}", decimalValue)
    

    但这会给你的程序带来非常大的开销。

    【讨论】:

      【解决方案5】:

      您可以检查小数是否为整数,然后使用适当的格式。带有扩展方法的实现:

       public static class DecimalExtension
        {
          public static string MyFormat(this decimal value)
          {
             decimal rounded = Math.Round(value, 4);
             if ((rounded % 1) == 0)
             {
               return rounded.ToString("0:0");
             }
      
              return rounded.ToString("0:0.0000");
      
            }
        }
      

      【讨论】:

        【解决方案6】:

        您可能想检查一下: http://www.daveoncsharp.com/2009/09/formatting-decimals-in-csharp/

        具体来说:

        string.Format("{0:0.00}", 256.0);   // "256.00"
        

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-24
        • 1970-01-01
        • 2013-08-22
        • 1970-01-01
        • 1970-01-01
        • 2014-11-08
        相关资源
        最近更新 更多