我在SQL Server Management Studio中运行此示例:
SELECT CONVERT(REAL, -2101.12) n INTO #t
SELECT * FROM #t
SELECT SUM(n) FROM #t
第一个SELECT
创建一个临时表#t
,其中列为n
,类型为real,它在其中放入1行,值为-2101.12
。
第二个SELECT
确认该表是使用预期内容创建的,结果是:
n
---------
-2101.12
第三个SELECT
将唯一的数字相加,但结果为:
-2101.1201171875
所以问题是:0.0001171875
来自哪里?
编辑:我知道real和float数据类型缺乏精确性,遗憾的是我无法更改数据库模式。令我感到惊讶的是,我希望在第二个选择中也能看到额外的小数,因为它应该以缺乏精度存储。由于在第二次选择时没有发生,为什么sum函数会选择它?
答案 0 :(得分:4)
您刚刚发现了真实(又称浮点)数据is approximate。 请改用decimal数据类型。
答案 1 :(得分:2)
FLOAT
和REAL
数据类型称为近似数据类型。 FLOAT
和REAL
的行为遵循关于近似数字数据类型的 IEEE 754
规范。
近似数值数据类型不存储为许多数字指定的确切值;它们存储了非常接近的值。对于许多应用,指定值和存储的近似值之间的微小差异不明显。但有时,差异变得明显。由于FLOAT
和REAL
数据类型的近似性质,当需要精确的数字行为时,请不要使用这些数据类型,例如在财务应用程序,涉及舍入的操作或相等检查中。而是使用整数,小数,金钱或小数据数据类型
避免在FLOAT
子句搜索条件中使用REAL
或WHERE
列,尤其是=
或<>
运算符。最好使用FLOAT
或REAL
比较来限制>
和<
列。