SQL Server的浮点数小于2.23E-308(最小双精度数)

时间:2016-12-06 15:03:52

标签: sql-server floating-point precision

我们正在使用SQL Server 2014来存储来自C库的结果。最近我们发现有一些值如1.39202924295074E-309存储在一个定义为float的列中。

这很奇怪,因为基于MSDN,浮动范围是

 -1.79E+308 to -2.23E-308, 0 and 2.23E-308 to 1.79E+308

默认情况下与我发现的任何文献一致。

所以问题是为什么我们得到的值小于允许的最小值?

该表的设计类似于

CREATE TABLE [dbo].[CLibDataResult](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Result] [float] NOT NULL
)

3 个答案:

答案 0 :(得分:5)

在互联网上进行一些挖掘后,我想我可以回答我的问题。其中一个参考是此page和此page

这里有两个概念,一个是最小正正常数和最小正subnormal个数。 MSDN页面根据最小正normal个数列出范围。但是基于IEEE 754,最小正正常数是在双扩展格式中可表示的最小正数。

这是双精度这些数字的备忘单,

--------------------------------------------------------------
| max normal number             |   1.7976931348623157e+308  |
--------------------------------------------------------------
| min positive normal number    | 2.2250738585072014e-308    |
--------------------------------------------------------------                                           
| max subnormal number          |   2.2250738585072009e-308  |
--------------------------------------------------------------                                           
| min positive subnormal number |   4.9406564584124654e-324  |
--------------------------------------------------------------

总之,最小可表示为4.9406564584124654e-324且1.39E-309大于此值。因此SQL服务器符合IEEE标准的双精度。

答案 1 :(得分:0)

看起来很奇怪,你给出的值在这个范围内。如果您使用.NET,则可以使用以下代码进行测试:

var d = double.Parse("1.39202924295074E-309");
var min = double.Parse("-1.79E+308");            
Console.WriteLine(d > min);  // returns true

我认为MSDN文本令人困惑。

答案 2 :(得分:0)

如果你从这开始

update [CLibDataResult] set result = power(cast(10.000 as float),-300);

 INSERT [CLibDataResult] VALUES(power(cast(10.000 as float),-300));

然后反复运行

update [CLibDataResult] set result = result / 10;
select * from [CLibDataResult];

你可以看到价值变得越来越小,然后在e-308附近它的精确度似乎会下降到碎片,因为有些数字可用,最后只是消失为零