sql server 2014舍入浮点值会产生意外结果

7y4bm7vi  于 2021-08-09  发布在  Java
关注(0)|答案(2)|浏览(408)

有人能解释一下下面的查询结果吗?我认为这是SQLServer2014中的一个bug。

DECLARE @x float
SET @x=58.415
SELECT ROUND(58.415,2), ROUND(@x,2)

y1aodyip

y1aodyip1#

因为第一个参数存储为十进制(5,3):

EXEC sp_describe_first_result_set N'SELECT 58.415 x', null, 0;

您有两个不同的代码:

DECLARE @x float 
SET @x=58.415 
SELECT ROUND(58.415,2), ROUND(@x,2)

GO

DECLARE @x decimal(19,3)
SET @x=58.415 
SELECT ROUND(58.415,2), ROUND(@x,2)

GO

基本上,浮动是
用于浮点数字数据的近似数字数据类型。浮点数据是近似值;因此,并非数据类型范围中的所有值都可以精确表示。
@zohar对值转换为十进制的原因进行了改进:
在transact-sql语句中,带小数点的常量将自动转换为数字数据值,并使用所需的最小精度和小数位数。例如,将常数12.345转换为精度为5、刻度为3的数值

z5btuh9x

z5btuh9x2#

您所看到的解释是,在SQLServer(或任何其他数据库或编程语言)中,浮点算法并不精确。以下是实际发生的情况,显示“真实”值以供解释:

SELECT
    ROUND(58.415, 2),           -- rounds UP to 58.420, this is DECIMAL(10,3), EXACT
    ROUND(58.4149999999999, 2)  -- rounds DOWN to 58.41

这里的问题是,当您进行以下变量赋值时:

DECLARE @x float
SET @x = 58.415

在内部,SQLServer实际上将值存储为近似值,类似于 58.41499999999 . 然后,当四舍五入到小数点后两位时,剩下的是 58.41 .
一般来说,如果需要精确的类型,应该使用精确的类型。在这种情况下, DECIMAL(10,3) 会有用的。

相关问题