任何人都可以在SQL Server中解释以下结果吗?我很难过。
declare @mynum float = 8.31
select ceiling( @mynum*100)
831
declare @mynum float = 8.21
select ceiling( @mynum*100)
822
我测试了一系列数字(SQL Server 2012
)。有些增加而其他人保持不变。我不知道为什么天花板会以不同的方式处理其中一些。从float
更改为decimal(18,5)
似乎可以解决问题,但我担心可能会有其他因素而导致这样做。任何解释都会有所帮助。
答案 0 :(得分:3)
我认为这称为浮点精度。您几乎可以在所有编程语言和数据库中找到它。这是因为数据仅以一定的精度存储,实际上您设置为8.31
的可能不是8.31
,而是例如8.31631312381813
,并且当它与ceil相乘时,它可能会导致不同的值出现。
在SQL server documentation page ,您可以阅读:
用于浮点数字数据的近似数字数据类型。浮点数据是近似值;因此,并非数据类型范围中的所有值都可以准确表示。
在其他数据库系统中存在同样的问题。例如,在mysql website,您可以阅读:
浮点数有时会引起混淆,因为它们是近似值而不是存储为精确值。在SQL语句中写入的浮点值可能与内部表示的值不同。尝试将浮点值视为比较中的精确值可能会导致问题。它们还受平台或实现依赖性的影响。 FLOAT和DOUBLE数据类型受这些问题的影响。对于DECIMAL列,MySQL执行精度为65位十进制数的操作,这可以解决最常见的不准确问题。
答案 1 :(得分:0)
浮点数不是100%准确。就像MarcinNabiałek所写的8.31你看到的可能是其他东西,比如8.310000000001。有关浮点精度问题的一些有趣读物,请参阅here。
解决方案不使用浮点数据类型,除非你真的需要。您应该使用DECIMAL
或MONEY
数据类型。
如果您真的必须使用浮点数据类型,那么您可以在每{{1}之前添加或减去一个小值(精确度thresold或 epsilon ) }},floor
或比较操作以获得所需的精度。如果你有很多浮点运算,那么编写你自己的floating point comparison functions可能是值得的。