为什么.Net在String.Format中使用与默认Math.Round()算法不一致的舍入算法?

orj*_*orj 27 .net c# math rounding string-formatting

我注意到C#/ .NET中存在以下不一致之处.我想知道为什么会这样.

Console.WriteLine("{0,-4:#.0} | {1,-4:#.0}", 1.04, Math.Round(1.04, 1));
Console.WriteLine("{0,-4:#.0} | {1,-4:#.0}", 1.05, Math.Round(1.05, 1));
Console.WriteLine("{0,-4:#.0} | {1,-4:#.0}", 1.06, Math.Round(1.06, 1));
Console.WriteLine("{0,-4:#.0} | {1,-4:#.0}", 1.14, Math.Round(1.14, 1));
Console.WriteLine("{0,-4:#.0} | {1,-4:#.0}", 1.15, Math.Round(1.15, 1));
Console.WriteLine("{0,-4:#.0} | {1,-4:#.0}", 1.16, Math.Round(1.16, 1));
Console.WriteLine();
Console.WriteLine("{0,-4:#.0} | {1,-4:#.0}", 1.04, Math.Round(1.04, 1, MidpointRounding.AwayFromZero));
Console.WriteLine("{0,-4:#.0} | {1,-4:#.0}", 1.05, Math.Round(1.05, 1, MidpointRounding.AwayFromZero));
Console.WriteLine("{0,-4:#.0} | {1,-4:#.0}", 1.06, Math.Round(1.06, 1, MidpointRounding.AwayFromZero));
Console.WriteLine("{0,-4:#.0} | {1,-4:#.0}", 1.14, Math.Round(1.14, 1, MidpointRounding.AwayFromZero));
Console.WriteLine("{0,-4:#.0} | {1,-4:#.0}", 1.15, Math.Round(1.15, 1, MidpointRounding.AwayFromZero));
Console.WriteLine("{0,-4:#.0} | {1,-4:#.0}", 1.16, Math.Round(1.16, 1, MidpointRounding.AwayFromZero));
Run Code Online (Sandbox Code Playgroud)

输出:

1.0  | 1.0
1.1  | 1.0
1.1  | 1.1
1.1  | 1.1
1.2  | 1.2
1.2  | 1.2

1.0  | 1.0
1.1  | 1.1
1.1  | 1.1
1.1  | 1.1
1.2  | 1.2
1.2  | 1.2
Run Code Online (Sandbox Code Playgroud)

看来默认的字符串格式化行为是使用MidpointRounding.AwayFromZero而不是Math.Round()的默认值MidpointRounding.ToEven进行舍入.

Eri*_*ert 12

作为一个历史记录,Format $的原始Visual Basic实现也与round-to-even,又名Banker's Rounding不一致.最初的Format $代码由Tim Paterson编写.你可能还记得蒂姆是一个名为QDOS(后来称为MS-DOS)的小程序的作者,这个程序在一段时间内是一个很好的卖家.

也许这是另一个25年向后兼容的案例.