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

Can this be done with formatting strings alone?

我想我发现了一些仅靠格式化字符串无法完成的事情:我需要一个字符串,它可以让我格式化双精度数以显示无小数,因此:

我已经到了。

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

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

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

这有效 "ok",除了它会显示带小数点的数字,我需要它们四舍五入。

为了便于说明,我试过:

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)

所以我决定使用第一个格式字符串,然后重新处理那些以“-”形式出现的值,但我想知道是否有办法单独使用格式字符串来完成此操作。

感谢您的帮助!

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

没有

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

三段

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

如果要格式化的数字是非零的,但是根据第一节或第二节的格式舍入后变成零结果零被格式化根据第三节

(强调)

据我所知,使用单一格式字符串似乎不可能在 同一组输出(只有值发生变化)。 "0" 将使用您希望为 "-" 的第三种格式。

而不只是说 'no' - 可以做什么?您是否考虑过创建一种以您需要的格式输出的方法?

您可以使用扩展方法执行此操作:

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

例子

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

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

编辑:您可能需要 (this double value .. 或任何实际值类型,您可以使用默认格式 optional/overloads。

编辑:上面的编辑是为了表明我确实阅读了问题...我总是使用 decimal 以便浮点计算不是问题,正如 weston 在注释。为了完整起见,这里有一个 double 的版本:

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

根据需要更改公差(有人称之为 'epsilon')。