我注意到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));输出:
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看起来默认的字符串格式化行为是使用MidpointRounding.AwayFromZero而不是Math.Round()的默认MidpointRounding.ToEven进行舍入。
发布于 2010-02-09 14:45:10
作为一个历史记录,最初的Visual Basic实现的Format$也与四舍五入,也就是银行家的舍入不一致。原始格式$ code是由Tim Paterson编写的。您可能还记得,Tim是一个名为QDOS (后来称为MS-DOS)的小程序的作者,在那里有一段时间是相当畅销的。
也许这是25年来向后兼容的又一案例。
发布于 2015-01-21 22:28:39
看起来这个问题比“简单的”不一致更糟糕:
double dd = 0.034999999999999996;
Math.Round(dd, 2); // 0.03
Math.Round(dd, 2, MidpointRounding.AwayFromZero); // 0.03
Math.Round(dd, 2, MidpointRounding.ToEven); // 0.03
string.Format("{0:N2}", dd); // "0.04"这简直是胡说八道。谁知道它是从哪里弄来的"0.04“。
发布于 2010-02-09 09:31:41
请看这里:Possible Bug: Math.Round returning inconsistent results
WriteLine()只是调用Object.ToString(),这最终导致对Number.FormatDouble(this,null,NumberFormatInfo.CurrentInfo)的调用。如您所见,格式字符串的参数为null。如果想要从ToString()获得真正的东西,就必须使用System.Diagnostics.Debug.WriteLine(n.ToString("R")).
“使用此说明符设置单值或双精度值的格式时,首先使用常规格式对其进行测试,双精度为15位精度,单精度为7位精度。如果该值成功解析回相同的数值,则使用常规格式说明符进行格式化。如果该值未成功解析回相同的数值,则使用17位精度的双精度位和9位单精度位的精度进行格式化。”Standard Numeric Format Strings
https://stackoverflow.com/questions/2226081
复制相似问题