2011-04-14 51 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