【问题标题】:Can this be done with formatting strings alone?这可以单独使用格式化字符串来完成吗?
【发布时间】:2015-07-18 05:51:24
【问题描述】:

我想我发现了一些仅靠格式化字符串无法完成的事情:我需要一个允许我格式化双精度以不显示小数的字符串,这样:

  • 数字是千分隔的
  • 0 显示破折号
  • 括号内显示负数
  • 0.5 舍入为 1,-0.5 舍入为 -1
  • 0.4999.. 舍入为 0,-0.4999... 舍入为 -0(必须显示为“(0)”)

我已经到了。

"{0:#,0;(#,0);-}"

但是,这会将(-0.5 到 0.5)之间的数字显示为“-”。如果我将其替换为以下内容。

"{0:#,0.#;(#,0.#);-}"

这“没问题”,除了它会显示带小数点的数字,我需要将它们四舍五入。

出于说明目的,我尝试过:

string format = "#,0;(#,0);-";

Console.WriteLine(1000000.ToString(format));
Console.WriteLine(1000.ToString(format));
Console.WriteLine(100.ToString(format));
Console.WriteLine(10.ToString(format));
Console.WriteLine(1.ToString(format));
Console.WriteLine(0.5.ToString(format));
Console.WriteLine(0.4.ToString(format));
Console.WriteLine(0.ToString(format));
Console.WriteLine((-0.4).ToString(format));
Console.WriteLine((-0.5).ToString(format));
Console.WriteLine((-1).ToString(format));
Console.WriteLine((-1000000).ToString(format));

这给出了:

1,000,000
1,000
100
10
1
1
-
-
-
(1)
(1)
(1,000,000)

还有:

string format = "#,0.#;(#,0.#);-";

Console.WriteLine(1000000.ToString(format));
Console.WriteLine(1000.ToString(format));
Console.WriteLine(100.ToString(format));
Console.WriteLine(10.ToString(format));
Console.WriteLine(1.ToString(format));
Console.WriteLine(0.5.ToString(format));
Console.WriteLine(0.4.ToString(format));
Console.WriteLine(0.ToString(format));
Console.WriteLine((-0.4).ToString(format));
Console.WriteLine((-0.5).ToString(format));
Console.WriteLine((-1).ToString(format));
Console.WriteLine((-1000000).ToString(format));

哪些输出:

1,000,000
1,000
100
10
1
0.5
0.4
-
(0.4)
(0.5)
(1)
(1,000,000)

但这就是我想要实现的目标:

1,000,000
1,000
100
10
1
1
0
-
(0)
(1)
(1)
(1,000,000)

所以我决定使用第一个格式字符串,然后重新处理那些显示为“-”的值,但我想知道是否有办法单独使用格式字符串。

感谢您的帮助!

【问题讨论】:

  • 你真正想要的输出是什么?
  • 这是另一个想法。事先单独进行舍入,并使用更简单的字符串格式。显然,这不仅仅是格式字符串。
  • 我已经明确了我现在想要完成的工作,谢谢@Greg。是的,ryanyuyu,我想到了这一点,但让 (0) 以这种方式出现,我取得了很大的成功。
  • "0 显示破折号" 什么是零?仅整数零?
  • 嗨@weston,我已经澄清了我想要完成的工作,并且得到了我所期待的答案。还是谢谢。

标签: c# .net vb.net formatting string-formatting


【解决方案1】:

这可以单独使用格式化字符串来完成吗?

没有。

https://msdn.microsoft.com/en-us/library/0c899ak8%28v=vs.110%29.aspx#SectionSeparator

三个部分

第一部分适用于正值,第二部分适用于负值,第三部分适用于零

如果要格式化的数字非零,但根据第一段或第二段的格式四舍五入后变为0根据第三段的格式,将得到的零格式化。

(强调)

正如我所读到的那样,使用单个格式字符串似乎不可能在同一组输出中获得 both“0”和“-”(只有值改变)。 “0”将使用您想要的第三种格式“-”。

与其说“不”,还能做什么?您是否考虑过创建一种以您需要的格式输出的方法?

您可以使用扩展方法来做到这一点:

public static string ToStringZeroDash(this decimal value, string format)
{
    return value == 0 ? "-" : value.ToString(format);
}

例子

(0.4).ToStringZeroDash("{0:#,0.#;(#,0.#);0}")

注意格式的第三部分是 0,但扩展名在到达那里之前返回“-”。

编辑:您可能需要(this double value .. 或任何实际值类型,您可以使用默认值将格式设为可选/重载。

编辑:上面的编辑是为了表明我确实阅读了这个问题......我总是使用decimal,因此浮点计算不是问题,正如weston在cmets中指出的那样。为了完整起见,这里是double 的版本:

public static string ToStringZeroDash(this double value, string format)
{
    const double tolerance = 0.0001;
    return Math.Abs(value) < tolerance ? "-" : value.ToString(format);
}

根据需要更改容差(有些人称之为“epsilon”)。

【讨论】:

  • If the number to be formatted is nonzero, but becomes zero after rounding according to the format in the first or second section, the resulting zero is formatted according to the third section. 哦!在查看文档时,我没有阅读该段落。是的,我已经为特殊情况拼凑了自己的格式化功能。谢谢!
  • 由于对double 的评论而取消了我的赞成票。您不想使用 == 将双打与 0 进行比较
猜你喜欢
  • 1970-01-01
  • 2010-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
  • 2015-07-20
相关资源
最近更新 更多