Float,Real和Decimal数据类型的回顾

时间:2015-08-12 11:42:43

标签: sql sql-server

我尝试了解在我的方案中在数据库( Sql Server )表中使用真实数据类型的列的影响。我的数据库中有一个真实数据类型的列。 数据是静态的,它始终是0.0,0.1,0.2 ..到1.0范围内的值之一。

使用案例 我必须总结列中的值,并在包含财务数据的一些算术计算中使用总和值。

关注:吗 当我总结列中的值时,它会给我带有更多小数位的结果。

测试

  1. 我想总结列值并在乘法和除法计算中使用它。

  2. 我想在带有decimal和float数据类型的列中为同一组值重复#1。

  3. 过程:我创建了三个不同的表,其中包含一列和相同的值集,但数据类型不同,一个包含十进制,浮点数和实数。并对每个算法进行算术运算。

         CREATE TABLE #tReal(d real);
         INSERT INTO #tReal
         SELECT 0.1 UNION ALL 
         SELECT 1 UNION ALL 
         SELECT 1 UNION ALL 
         SELECT 0.9 UNION ALL 
         SELECT 1 UNION ALL 
         SELECT 0.9 UNION ALL 
         SELECT 1;
         select SUM(d) from #tReal
    

    预期成果:5.9

    实际结果: 5.8999999538064

    并且,如果我对总和执行循环操作,结果是预期的

    declare @sumofd real
    select @sumofd = SUM(d) from #tReal
    select round(@sumofd , 1)
    

    结果:5.9

    另外,如果我将数据类型从 真实 更新为 float

    CREATE TABLE #tfloat(d float);
    INSERT INTO #tfloat
    SELECT 0.1 UNION ALL 
    SELECT 1 UNION ALL 
    SELECT 1 UNION ALL 
    SELECT 0.9 UNION ALL 
    SELECT 1 UNION ALL 
    SELECT 0.9 UNION ALL 
    SELECT 1;
    select SUM(d) from #tfloat
    

    预期成果:5.9

    实际结果: 5.9

    而且,如果我将数据类型从 真实 更新为 十进制

    ,情况也是如此
    CREATE TABLE #tDecimal(d DECIMAL(3,2));
    INSERT INTO #tDecimal
    SELECT 0.1 UNION ALL 
    SELECT 1 UNION ALL 
    SELECT 1 UNION ALL 
    SELECT 0.9 UNION ALL 
    SELECT 1 UNION ALL 
    SELECT 0.9 UNION ALL 
    SELECT 1;
    
    select SUM(d) from #tDecimal
    

    预期成果:5.94

    实际结果: 5.94

    并且,如果我对总和执行一些基本的算术运算,而不是舍入,比如

    declare @sumofdReal real
    declare @sumofdFloat float
    declare @sumofdDecimal decimal(3,2)
    
    select @sumofdReal = SUM(d) from #tReal
    select @sumofdFloat = SUM(d) from #tfloat
    select @sumofdDecimal = SUM(d) from #tDecimal
    

    乘:

    select @sumofdReal * 2
    Result: 11.8
    
    select @sumofdFloat * 2
    Result: 11.8
    
    select @sumofdDecimal * 2
    Result: 11.88
    

    司:

    select @sumofdReal / 2
    Result: 2.95
    
    select @sumofdFloat / 2
    Result: 2.95
    
    select @sumofdDecimal / 2
    Result: 2.97000
    

    删除表:

    drop table #tReal
    drop table #tfloat
    drop table #tDecimal
    

    以下是我的问题

    1. 在我的场景中,将数据类型设为真实会产生任何影响吗?
    2. 如果#1是,是什么样的反响?我是否必须将数据类型更改为float或decimal?为什么?
    3. 如果#1为否,为什么?请解释一下?
    4. 是否浮点数和实数类型可以产生精确结果,是否会出现超出舍入错误的任何内容?

3 个答案:

答案 0 :(得分:0)

如果您在财务计算中使用这些值,那么您应该(几乎)使用十进制类型,否则您将遇到浮点舍入的问题。当你开始失去便士时,人们会非常伤心。

您可能希望在此处阅读有关浮点运算的更多信息:

http://floating-point-gui.de/

十进制类型不受这些限制,应该是准确的。

例如,您最终会遇到尝试将数字舍入为2 DP的情况,例如: 0.695,你可以期望将其上升到0.70。

DECLARE @x REAL = 0.695

SELECT ROUND(@x, 2)

-- outputs 0.69

DECLARE @y DECIMAL(6,4) = 0.695

SELECT ROUND(@y, 2)

-- outputs 0.7000

这是因为你不能准确地将0.695表示为浮点数,而实际上它远远小于0.695。

答案 1 :(得分:0)

使用浮点值总会产生影响,因为它们没有准确表示,并且总会出现一些舍入错误。在将值与常量进行比较时,您必须非常小心,例如: if(a == 0.0)因为如果' a'是数学运算的结果。 Float和Decimal只给你不同的范围和精度。

答案 2 :(得分:0)

SQL Server中的

realfloat(24)的同义词,它占用4个字节,最多7位精度。

float本身与float(53)相同,double也与decimal相同,后者占用8个字节,精度最高可达15位。

  

在我的场景中,将数据类型设为真实会产生任何影响吗?

可能。 floatrealdecimal have different characteristics and are not fully interchangeable。如果要保持精确的十进制表示,请使用具有适当比例和精度的float数据类型。如果您的数字代表不精确的数据(例如温度,高度,时间或其他"自然"测量无法在没有一些不精确的情况下测量)并且想要更快的数学运算,那么请使用real(或{{ 1}}如果你不需要超过7位精度。

  

当我总结列中的值时,它会给我带有更多小数位的结果。

当您添加浮点数时,SQL会确定结果的大小,并使用适当的数据类型。当您添加两个reals时,结果可能具有超过7位数的精度,因此它可能会使用float作为结果数据类型。

  

我是否必须将数据类型更改为float或decimal?为什么呢?

如果精度超过7位数,请使用float,从小数角度来看,不需要绝对精度,并希望使用浮点类型来加快计算速度。

如果您想要一个固定的比例和精度,并希望最小化浮点数所涉及的不精确度,请使用decimal