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

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

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

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

y1aodyip

y1aodyip1#

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

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

您有两个不同的代码:

  1. DECLARE @x float
  2. SET @x=58.415
  3. SELECT ROUND(58.415,2), ROUND(@x,2)
  4. GO
  5. DECLARE @x decimal(19,3)
  6. SET @x=58.415
  7. SELECT ROUND(58.415,2), ROUND(@x,2)
  8. GO

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

展开查看全部
z5btuh9x

z5btuh9x2#

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

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

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

  1. DECLARE @x float
  2. SET @x = 58.415

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

相关问题