这个问题让我发疯了.我正在使用Microsoft SQLExpress 2016来编写存储过程.其中一个要求是进行舍入.但是时不时地四舍五入是错误的.我发现T-SQL舍入与C#不完全相同,但为什么呢?
比较下面的两个舍入:
In T-SQL: ROUND(0.045, 2) --> this will produce 0.05 In C#: Math.Round(0.045, 2) --> this will produce 0.04
为什么C#产生0.04?不应该是0.05吗?
我该怎么办才能使C#舍入= T-SQL舍入?谁能帮我?
谢谢,山姆
出于好奇,我在C#中尝试了这个:
Math.Round(0.055, 2)
猜猜看,C#将它四舍五入?它四舍五入到0.06!现在,我完全糊涂了!
Math.Round(0.045, 2) //this becomes 0.04 Math.Round(0.055, 2) //this becomes 0.06
有谁能解释一下?
谢谢
这是因为.NET默认使用'ToEven'舍入,而SQL使用'AwayFromZero'.看到这个.这些是不同的舍入方法,它们的处理方式不同5.AwayFromZero将其舍入到下一个正数或下一个负数.因此,0.5变为1,-0.5变为-1.ToEven舍入到最近的偶数.因此2.5变为2,3.5变为4(同样对于负数).除5之外的数字处理相同,它们四舍五入到最接近的数字.由于5与两个数字等距,因此它是一个特殊情况,具有不同的策略.
ToEven也称为"银行规则",它是IEEE_754中默认使用的,这就是为什么它是.NET中的默认值.
相反,AwayFromZero也被称为"商业四舍五入".我不知道为什么它是sql server的默认值,可能只是因为它是最广为人知和理解的方法.
当然,您始终可以配置所需的内容:
在C#中你可以做到:
Math.Round(value, MidpointRounding.ToEven)
要么
Math.Round(value, MidpointRounding.AwayFromZero)
在SQL中,您可以使用ROUND(),FLOOR()和/或CEILING().
哪种方法更好,取决于您使用它的方式,以及您想要的方法.对于合理的集合/分布,舍入的toEven值的平均值与其原始值相同.AwayFromZero不一定是这种情况.如果您有一个包含许多.5
数据的集合,则舍入AwayFromZero会将所有这些值视为相同,并引入偏差.结果是舍入值的平均值与原始值不同.舍入点使得值更简单,而它具有相同的含义.如果平均值不匹配则不再是这种情况; 舍入值与原始值具有(略微?)不同的含义.