2010-06-11 53 views
3

我明白在比较花车的问题主机,并哀叹他们在这种情况下使用 - 但我不是表作者,只有一个小障碍攀登...TSQL - 使字面浮点值

有人已经决定使用浮点数,因为你期望使用GUID。我需要检索具有特定浮点值的所有记录。

sp_help MyTable 

-- Column_name Type Computed Length Prec 
-- RandomGrouping float no 8 53 

这是我天真的尝试:

--yields no results 
SELECT RandomGrouping 
FROM MyTable 
WHERE RandomGrouping = 0.867153569942739 

这里是一个大约工作尝试:

--yields 2 records 
SELECT RandomGrouping 
FROM MyTable 
WHERE RandomGrouping BETWEEN 0.867153569942739 - 0.00000001 
     AND 0.867153569942739 + 0.00000001 

-- 0.867153569942739 
-- 0.867153569942739 

在我天真的尝试,是字面浮点文字?或者它确实是一个十进制文字,稍后会被转换?

如果我的文字不是浮点文字,那么创建浮点文字的语法是什么?

编辑:我发生了另一种可能性......它可能是一个比显示更精确的数字存储在这一列。创建代表这个数字的文字可能是不可能的。我会接受证明情况如此的答案。


编辑:对DVK的响应。

TSQL是MSSQLServer的SQL方言。

这个脚本工作,所以可以确定性浮点类型之间进行平等:

DECLARE @X float 
SELECT top 1 @X = RandomGrouping 
FROM MyTable 
WHERE RandomGrouping BETWEEN 0.839110948199148 - 0.000000000001 
    AND 0.839110948199148 + 0.000000000001 
    --yields two records 
SELECT * 
FROM MyTable 
WHERE RandomGrouping = @X 

我说:“大约”,因为一定范围的方法测试。用这种方法,我可以得到不等于我预期值的值。

链接的文章不适用,因为我不是(故意)试图跨越小数和浮点之间的世界边界。我正在尝试仅使用花车。这不是关于小数不可兑换为浮点数的问题。


响应Zinglon:

字面值,可以找到我的记录,谢谢。

DECLARE @Y binary(8) 
SET @Y = 0x3FEAD9FF34076378 

SELECT * 
FROM MyTable 
WHERE convert(binary(8), RandomGrouping) = @Y 

回答

1

有可能显示值正在被截断。我假设专栏没有独特的约束,否则这个问题是没有意义的。在我的设置中,SSMS截断了此脚本中更精确的值。

create table flt (f float not null primary key) 
insert into flt 
select 0.111111111111111 
union all 
select 0.1111111111111111 
select f, cast(f as binary(8)) from flt 

同样,如果这些值是不同的,你可以将它们转换成二进制(8),并确定它们基于该值,如:

select f from flt 
where cast(f as binary(8)) = 0x3FBC71C71C71C71C 
0

问题不在于它是否是浮点数字。

问题是,在Sybase(或任何数据库服务器)中比较两个等式的浮点数是不确定的,因为4.00000000000000000000 ...和3.99999999999999999999 ...是相同的确切数字,但不相等。

你的第二个解决方案是比较浮点“平等”的唯一正确方法(也就是说,它们是否与精度相同)。

为什么你说你的第二种方法“大​​约工作”?

既然你没有提供你使用特定的数据库服务器,这里的问题的一个相当不错的写了(与基本与上述相同的结论)为MySQL

http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html