sql server2005中,请看以下数据计算结果为0.000078,而我用计算器算出的结果为0.000077720565,这是什么原因呢?
select convert(numeric(16,8),80.6)*convert(numeric(16,8),11.5)*convert(numeric(16,8),0.075)*convert(numeric(16,8),1.118)*0.00000100

解决方案 »

  1.   

    你的位数少了点select convert(decimal(16,12),80.6)*convert(decimal(16,12),11.5)*convert(decimal(16,12),0.075)*convert(decimal(16,12),1.118)*0.00000100
    ---------------------------------------
    0.000077720565000000(1 行受影响)
      

  2.   

    select 80.6*11.5*0.075*1.118*cast(0.000001 as dec(18,10))
    ------------------------------
    0.000077720565000000(1 行受影响)这样就可以,不好解释为什么
      

  3.   

    select 80.6*11.5*0.075*1.118*0.000001
    ------------------------
    0.00007772056500(1 行受影响)如果说位数少,没有加入长度转化,这样出来也是对的.
      

  4.   


    select cast(80.6*11.5*0.075*1.118*0.0000010000 as dec(16,8))
    -----------------------
    0.00007772(1 行受影响)
      

  5.   


    select cast((convert(numeric(16,11),80.6)*convert(numeric(16,11),11.5)*convert(numeric(16,11),0.075)*convert(numeric(16,11),1.118)*0.00000100) as decimal(8,8))---------------------------------------
    0.00007772(1 行受影响)
      

  6.   

    原因:1、numeric 采用的浮点数的存储方式,2005中采用的IEEE754-96的标准,select cast(convert(numeric(16,8),80.6) as varbinary)可以查看
    2、一步一步测试就可以知道到了,当算到最后的时候,结果使用5的是五个字节来保存结果的。
    select datalength(convert(numeric(16,8),80.6)*convert(numeric(16,8),11.5)*convert(numeric(16,8),0.075)*convert(numeric(16,8),1.118)*0.00000100) 就可以知道了。至于为什么参见:
    转换 decimal 和 numeric 数据
    对于 decimal 和 numeric 数据类型,SQL Server 会将精度和小数位数的每个特定组合视为不同的数据类型。 例如,将 decimal(5,5) 和 decimal(5,0) 视为不同的数据类型。在 Transact-SQL 语句中,带有小数点的常量将自动转换为 numeric 数据值,而且使用必需的最小精度和小数位数。 例如,常量 12.345 将被转换为精度为 5,小数位数为 3 的 numeric 值。从 decimal 或 numeric 转换为 float 或 real 会导致精度的降低。 从 int、smallint、tinyint、float、real、money 或 smallmoney 转换为 decimal 或 numeric 会导致溢出。默认情况下,将数字转换为较低精度和小数位数的 decimal 或 numeric 值时,SQL Server 会进行舍入。 但如果 SET ARITHABORT 选项为 ON,则发生溢出时,SQL Server 会产生错误。 若仅降低精度和小数位数,则不会产生错误
    要保留8位的话,对计算结果进行转换,而不是对每一个数进行转换。
    select cast(80.6*11.5*0.075*1.118*0.0000010000 as dec(16,8))