为啥 C# 中的数字格式字符串在不使用小数 (F0) 时会将数字四舍五入?
Posted
技术标签:
【中文标题】为啥 C# 中的数字格式字符串在不使用小数 (F0) 时会将数字四舍五入?【英文标题】:Why do the numeric format strings in C# round the number when not using decimals (F0)?为什么 C# 中的数字格式字符串在不使用小数 (F0) 时会将数字四舍五入? 【发布时间】:2016-03-05 00:21:26 【问题描述】:当涉及到 C# 中的标准数字格式字符串时,我遇到了一些非常奇怪的事情。这可能是一个已知的怪癖,但我找不到任何记录它的东西,我无法找到一种方法来真正得到我想要的东西。
我想取一个像 17.929333333333489 这样的数字,并将其格式化为不带小数位。所以我只想要“17”。但是当运行这段代码时。
decimal what = 17.929333333333489m;
Console.WriteLine(what.ToString("F0"));
我得到这个输出
18
查看 Microsoft 的文档,他们的示例显示相同的输出。
https://msdn.microsoft.com/en-us/library/kfsatb94(v=vs.110).aspx
// F: -195489100.84
// F0: -195489101
// F1: -195489100.8
// F2: -195489100.84
// F3: -195489100.838
这是一个显示奇怪问题的代码示例。
http://csharppad.com/gist/d67ddf5d0535c4fe8e39
这个问题不仅限于像“F”和“N”这样的标准问题,还包括像“#”这样的自定义问题。
我怎样才能使用标准的“F0”格式化程序而不是让它围绕我的数字?
【问题讨论】:
【参考方案1】:来自Standard Numeric Format Strings上的文档:
xx 是一个可选的整数,称为精度说明符。精度说明符的范围从 0 到 99,并影响结果中的位数。请注意,精度说明符控制数字字符串表示中的位数。它不会对数字本身进行四舍五入。要执行舍入操作,请使用
Math.Ceiling
、Math.Floor
或Math.Round
方法。当精度说明符控制结果字符串中的小数位数时,结果字符串反映从零四舍五入的数字(即使用 MidpointRounding.AwayFromZero)。
因此文档确实讨论了这一点,并且没有明显的方法可以防止纯粹通过格式字符串对输出进行舍入。
我能提供的最好的方法是使用Math.Truncate()
自己截断数字:
decimal what = 17.929333333333489m;
decimal truncatedWhat = Math.Truncate(what);
Console.WriteLine(truncatedWhat.ToString("F0"));
【讨论】:
【参考方案2】:我相信在最后使用带有“m”的小数会在给定的小数位上四舍五入。
这是我的实验。
decimal what = 17.429333333333489m;
Console.WriteLine(what.ToString("F0"));
Console.WriteLine(what.ToString("N0"));
Console.WriteLine(what.ToString("F1"));
Console.WriteLine(what.ToString("N1"))
17
17
17.4
17.4
如果你想得到 17,我使用了不同的方法,使用 int 和 deciam
double what = 17.929333333333489;
Console.WriteLine(string.Format("0:0", (int)what));
Console.WriteLine(string.Format("0:0", what));
Console.WriteLine(string.Format("0:0.00", Math.Floor(what*100)/100));
Console.WriteLine(string.Format("0:0.00", what));
17
18
17.92
17.93
【讨论】:
以上是关于为啥 C# 中的数字格式字符串在不使用小数 (F0) 时会将数字四舍五入?的主要内容,如果未能解决你的问题,请参考以下文章