TSQL Round() 不一致?

Posted

技术标签:

【中文标题】TSQL Round() 不一致?【英文标题】:TSQL Round() inconsistency? 【发布时间】:2011-07-21 13:42:45 【问题描述】:

我们遇到的问题归结为以下两种说法:

select convert(float, (convert(float,5741.61)/convert(float, 196.00)) * convert(float,14.00)) as unrounded, round(convert(float, (convert(float,5741.61)/convert(float, 196.00)) * convert(float,14.00)), 2)  as roundedTo2dp

select convert(float, 410.115) as unrounded, ROUND( convert(float, 410.115), 2) as roundedTo2dp

第一个语句使用浮点数来计算 410.115 的值,并且该结果使用 round() 到小数点后 2 位。四舍五入的值为 410.11。

第二条语句使用浮点值 410.115 并将其四舍五入到小数点后 2 位。四舍五入的结果为 410.12。

为什么一个四舍五入的值相同,而另一个四舍五入?

如何让第一条语句四舍五入到 410.12?

编辑:为格式化道歉——*** 在这台机器上没有显示任何格式(很奇怪)。

【问题讨论】:

【参考方案1】:

小数的精度优于浮点数。如果您将浮点数更改为 DECIMAL(18,2) 之类的值,您将得到您所期望的,并且不再需要调用 round 函数。

select convert(decimal(18,2), (convert(decimal(18,2),5741.61)/convert(decimal(18,2), 196.00)) * convert(decimal(18,2),14.00)) as unrounded, round(convert(decimal(18,2), (convert(decimal(18,2),5741.61)/convert(decimal(18,2), 196.00)) * convert(decimal(18,2),14.00)), 2)  as roundedTo2dp

结果

unrounded   roundedTo2dp
410.12      410.12

关于小数的 MSDN 链接。 http://msdn.microsoft.com/en-us/library/ms187746.aspx

希望对您有所帮助...

【讨论】:

【参考方案2】:

数字不相等:

SELECT  CAST(convert(float, (convert(float,5741.61)/convert(float, 196.00)) * convert(float,14.00)) AS BINARY(8))
UNION ALL
SELECT  CAST(convert(float, 410.115) AS BINARY(8)) as bin

----
0x4079A1D70A3D70A3
0x4079A1D70A3D70A4

【讨论】:

【参考方案3】:

'float' 是一种近似数字数据类型,因此并非数据类型范围内的所有值都可以精确表示。

这是基于http://msdn.microsoft.com/en-us/library/ms173773.aspx。

我相信这就是为什么在使用浮点值时会出现舍入问题。你永远不能百分百确定!

例如。 选择 round(convert(float, 1.5555), 2) --Gives 1.56

选择 round(convert(float, 1.555), 2) --给出 1.55!

对于这样一个简单的数字,使用浮点数时预期结果会有所不同。

【讨论】:

以上是关于TSQL Round() 不一致?的主要内容,如果未能解决你的问题,请参考以下文章

python numpy.row_stack?想知道怎么修改

事务索引和视图

c#访问性不一致的问题

Math.round(),Math.ceil(),Math.floor()的区别

Android依赖库版本不一致的解决办法

HBase 一致性检查与修复