2011-04-14 54 views
2

我在执行计算,但没有得到我期望的答案。我在计算中失去了一些比例。执行计算时的比例损失

Calc是:1000分之651* -413.72063274 = -269.33213191(8 DP)

在SQL Server我这样做:

declare @var numeric(28,8) 
declare @a numeric(28,8) 
declare @b numeric(28,8) 

set @var = -413.72063274 
set @a = 651.00000000 
set @b = 1000.00000000 

select CAST((@a/@b) * @var as numeric(28,8)) as result_1 
    , CAST(CAST(@a as numeric(28,8)) 
     /CAST(@b as numeric(28,8)) as numeric(28,8)) 
     *CAST(@var as numeric (28,8)) as result_2 

结果是

result_1:-269.33213200 (正确到6dp)
result_2:-269.332132(正确到6dp)

我如何得到查询返回:-269.33213191(相关ct到8dp)?

+0

您发布的查询无效。它挂着'/'你能修好吗? – 2011-04-14 12:57:36

+0

opps抱歉,现在已修复。 – Stagg 2011-04-14 12:59:16

回答

4

对于这种特定情况,您可以通过首先将所有值相乘并将最终结果除以该乘数来作弊。

declare @var numeric(28,8) 
declare @a numeric(28,8) 
declare @b numeric(28,8) 
declare @m numeric(28,8) 

set @var = -413.72063274 
set @a = 651.00000000 
set @b = 1000.00000000 
set @m = 10000000 


select CAST(((@a*@m) * (@var*@m)/(@b*@m)) AS NUMERIC(28, 8))/@m 
-- Result: -269.3321319137 

编辑

,另一方面

,下面保留了其精确度,而无需使用乘数

select CAST(@a * @var AS NUMERIC(28, 8))/@b 
-- Result: -269.3321319140 
+0

太棒了,谢谢!我用你的编辑。 – Stagg 2011-04-14 13:15:56

0

你从分裂开始,然后乘以。精确度的损失在分工中。这是四舍五入到8 DP,结果乘以一个3位数(413)值(因此缺少的最后两位数)

解决方法是对中间结果使用较大的精度,或先乘法。

(@a * @var)/ @b在数学上等于您的计算,但可能会得出更准确的结果。

+0

师的实际给予10dp。随后的乘法会导致截断。 – 2011-04-14 13:16:31

5

规则为decimaldecimal转换乘法和除法are described in BOL

*结果精度和标有38的绝对最大当 结果精度大于38, 相应规模被减小到 防止被截断的结果 的不可分割的一部分。

但是没有说明这种截断是如何执行的。 This is documented here。但是有时只是使用试验和错误更容易!

下面的中间演员给你想要的结果。你能和这些人一起生活吗?

DECLARE @var NUMERIC(19,8) 
DECLARE @a NUMERIC(19,8) 
DECLARE @b NUMERIC(19,8) 

SET @var = -413.72063274 
SET @a = 651.00000000 
SET @b = 1000.00000000 

DECLARE @v SQL_VARIANT 
SET @v = CAST(@a/@b AS NUMERIC(24,10))* CAST(@var AS NUMERIC(23,8)) 

SELECT CAST(SQL_VARIANT_PROPERTY(@v, 'BaseType') AS VARCHAR(30)) AS BaseType,  
      CAST(SQL_VARIANT_PROPERTY(@v, 'Precision') AS INT) AS PRECISION,  
      CAST(SQL_VARIANT_PROPERTY(@v, 'Scale') AS INT) AS Scale 
+0

thx马丁,你总是设法教我新的东西。 – 2011-04-14 14:53:06