SqlServer无法在FLOAT字段中精确存储0.1?

时间:2017-04-10 16:21:20

标签: c# .net sql-server floating-point

我正在将一个浮点字段读入C#双字段。 DB值0.1读取为0.10000000149011612。我发现这很奇怪,因为这个问题的答案讨论FLOAT使用8个字节,这肯定足够0.1?

  

SQL Server使用4个字节或8个字节来存储非小数   浮点数。

     

如果您指定float< 1>范围内的实数或任何值浮动< 24>,   SQL服务器使用float< 24>内部。如果你使用浮动或任何东西   范围浮点数< 25>浮动< 53> (限制),它使用浮点数< 53>哪一个   也被称为双精度。

我的表包含FLOAT类型的字段,该字段由带参数@Result FLOAT OUT的存储过程读取和返回。

我的C#代码如下所示,请注意它使用Float类型而不是Real

//setting up the query
command.Parameters.Add("@Result", SqlDbType.Float).Direction = ParameterDirection.Output;

//reading the value
double result = Convert.ToDouble(command.Parameters["@Result"].Value);

这应该有效......或者SqlServer FLOAT的工作方式与C#等语言中的普通double类型不同吗?是否应该准确存储和返回0.1?如果我使用Real,我不会感到惊讶,但我认为Float应该非常准确。或者至少精度有限,不会引入错误的数字...

1 个答案:

答案 0 :(得分:0)

运行此查询并注意它会创建一个无限循环。您必须手动停止执行。

 DECLARE @Counter float; 
 SET @Counter = 0; 
 WHILE (@Counter <> 1.0) BEGIN 
    SET @Counter += 0.1; 
    PRINT @Counter; 
 END; 

你会认为它会与此相同,但它不是。

DECLARE @Counter decimal(4,2); 
SET @Counter = 0; 
WHILE (@Counter <> 1.0) BEGIN 
  SET @Counter += 0.1; 
  PRINT @Counter; 
END;

问题是0.1不能精确存储在浮点数据类型中。需要使用十进制数据类型。

十进制数据类型是精确的数值数据类型,其中float是近似数值数据类型。这是一个参考Link

使用float数据类型的查询产生无限循环的原因是因为适当的数值数据类型永远不会等于1.0。