在 C# 中实现复杂数字格式的最佳方法

本文关键字:格式 最佳 方法 数字 复杂 实现 | 更新日期: 2023-09-27 17:57:22

C# 中复制类似行为的最佳方法是什么?

// Converts decimal to a 0-padded string with minimum specified width and precision.
sprintf(out, "%0*.*lf", width, precision, decimal);

我阅读了标准、自定义和复合格式字符串,但我看不出有什么好方法可以实现这一点。

问的原因是我刚刚在我维护的一些代码中遇到了这个丑陋的片段,我们需要根据外部接口指定的可变宽度和精度格式化一堆小数:

private static String ZEROS = "00000000000000000000000000";
public override string Format(decimal input, int width, int precision)
{
    String formatString = ZEROS.Substring(0, width - precision - 1) 
                          + "." + ZEROS.Substring(0, precision);
    return ToDecimal(input).ToString(formatString);
}

我想用一些不那么可怕的东西代替它。

更新

由于最终答案被埋在评论中,这里是:

public override string Format(decimal input, int width, int precision)
{
    string.Format("{0," + width + ":F" + precision + "}", input).Replace(" ","0");
}

在我的情况下,输入总是正的,所以这也有效:

public override string Format(decimal input, int width, int precision)
{
    return input.ToString("F"+precision).PadLeft(width, 0);
}

在 C# 中实现复杂数字格式的最佳方法

你可以这样写,生成一个标准格式的字符串,然后使用它:

public static string Format(decimal input, int width, int precision)
{
    var format = string.Format("{{0,{0}:F{1}}}", width, precision);
    // generates (e.g. width=15, precision=5)  "{0,15:F5}"
    // then format using this and replace padding with zeroes
    return string.Format(format, input).Replace(" ", "0");
}

或者,根据您的喜好,不要调用格式两次,只需连接格式字符串:

string.Format("{0," + width + ":F" + precision + "}", input).Replace(" ","0")

之后必须替换空格,因为无法指定填充字符。或者,您可以编写自己的格式化程序以填充特定字符。这虽然有效:)

编辑:这匹配所有输入的原始输入,除了precision = 0时。在这种情况下,原始文件是不正确的,因为它将小数点计为宽度的一部分,即使它不存在。

糟糕:忘了检查负数。

这是一个更简单的版本,但必须检查数字是否为负数才能使填充正确:

public override string Format(decimal input, int width, int precision)
{
    var output = input.ToString("F" + precision);
    return input < 0
        ? "-" + output.Substring(1).PadLeft(width, '0')
        :       output             .PadLeft(width, '0');
}

像这样:

return input.ToString(new string('0', width) + '.' + new string('0', precision));

编辑:从字面上看,这是一个更好的:

return input.ToString(new string('0', width - 1).insert(width - precision, '.'));

好吧,摆脱ZERO的一种方法是

public override string Format(decimal input, int width, int precision)
{
    String formatString = new string('0', width - precision - 1) 
                      + "." + new string('0', precision);
    return ToDecimal(input).ToString(formatString);
}

不确定你是否可以做很多其他事情。

这几乎是最好的:

public static string double2string( double value , int integerDigits , int fractionalDigits )
{
  string        decimalPoint = CultureInfo.CurrentUICulture.NumberFormat.NumberDecimalSeparator ;
  StringBuilder sb           = new StringBuilder() ;
  sb.Append('0',integerDigits)
    .Append(decimalPoint)
    .Append('0',fractionalDigits)
    ;
  return value.ToString( sb.ToString() ) ;
}
我相信

你可以调用Decimal.ToString并传递给它可以生成的自定义数字格式字符串。