当前位置: 首页 > 编程语言 > C#

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

时间:2023-04-10 22:17:27 C#

为什么.Net在String.Format中使用了与默认的Math.Round()算法不一致的舍入算法?我注意到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));控制台.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.01.1|1.01.1|1.11.1|1.11.2|1.21.2|1.21.0|1.01.1|1.11.1|1.11.1|1.11.2|1.21.2|1.2似乎默认的字符串格式化行为是使用MidpointRounding.AwayFromZero而不是Math.Round()的默认MidpointRounding.ToEven进行舍入作为历史记录,Format$的原始VisualBasic实现也与舍入不一致-甚至,又名银行家的四舍五入。最初的Format$代码是由TimPaterson编写的。您可能还记得,蒂姆是一个名为QDOS(后来的MS-DOS)的小程序的作者,该程序在一段时间内很畅销。也许这是25年向后兼容的另一个例子。看来这个问题比“简单”的不一致更糟糕:doubledd=0.034999999999999996;Math.Round(dd,2);//0.03Math.Round(dd,2,MidpointRounding.AwayFromZero);//0.03Math.Round(dd,2,MidpointRounding.ToEven);//0.03string.Format("{0:N2}",dd);//“0.04”这绝对是香蕉。谁知道它从哪里得到“0.04”。请查看:可能的错误:Math.Round返回不一致的结果WriteLine()仅调用Object.ToString(),最终调用Number.FormatDouble(this,null,NumberFormatInfo.CurrentInfo)。如您所见,格式字符串的参数为空。如果你想从ToString()中得到真正的东西,你必须使用System.Diagnostics.Debug.WriteLine(n.ToString("R"))。“当使用此说明符格式化Single或Double值时,首先使用通用格式对其进行测试,Double的精度为15位,精度为7位。如果该值成功解析为相同的数值,则将其与一般格式说明符Formatting。如果该值没有成功解析回相同的数值,则Double具有17位精度和9位精度。标准数字格式字符串WriteLine(string,paramsobject[])调用string.Format和传递当前的CultureInfo,因此您本地化的NumberFormatInfo将用于确定如何编写该数字。Math.Round不考虑文化,因为您正在指定它的确切舍入方式。好吧,戳一下反射器,也许不是:)以上是C#学习教程:为什么.Net使用的舍入算法与String.Format中默认的Math.Round()算法不一致?所有内容分享,如果对大家有用还需要了解更多关于C#学习教程,希望大家多多关注——本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: