web-dev-qa-db-ja.com

小数を乗算すると、精度とスケールはどのように計算されますか?

小数が除算されると、 this 式により、結果値の精度とスケールが計算されます。

最大精度=(p1-s1 + s2)+ MAX(6、s1 + p2 + 1)-最大38

最大スケール= MAX(6、s1 + p2 + 1)

小数を掛けたときの計算式は?

例えば:

_IF OBJECT_ID('tempdb..#DataSource') IS NOT NULL
BEGIN
    DROP TABLE #DataSource;
END;

SELECT CAST(1 AS DECIMAL(9,0)) / CAST(2 AS DECIMAL(9,0)) AS C1 
      ,CAST(1 AS DECIMAL(9,0)) / CAST(2 AS DECIMAL(9,0)) * 100 AS C2
      ,CAST(1 AS DECIMAL(9,0)) / CAST(2 AS DECIMAL(9,0)) * CAST(100  AS DECIMAL (3, 0)) AS C3
INTO #DataSource;

EXEC tempdb.dbo.sp_help '#DataSource';
_

enter image description here

列_C1_の精度とスケールは、指定された式に基づいて計算されます。

_p1 = 9
p2 = 9
s1 = 0
s2 = 0

max precision = (9 - 0 + 0) + MAX(6, 0 + 9 + 1) --> 19
max scale = MAX(6, 0 + 9 + 1) --> 10
_

この結果に_100_を掛けると(値_100_はDECIMAL(3,0)に変換されます)、結果の精度は_23_で、スケール_10_になります。

同じ数式を適用すると、値は次のようになります。

_p1 = 19
p2 = 3
s1 = 10
s2 = 0

max precision = (19 - 10 + 0) + MAX(6, 10 + 3 + 1) --> 9 + 14 = 23
max scale = MAX(6, 10 + 3 + 1) --> 14
_

したがって、精度は正しいですが、スケールは大きくなります-_14_の代わりに_10_。

小数が乗算されたときに、精度とスケールを計算するための式が何かは誰かに教えてもらえますか?

3
gotqn

StackOverflowに関する非常によく似た質問に対する答えがあります。

計算列のデータ型をどのように制御しますか?

しかし、ここでより完全に述べると:


質問にリンクされている投稿で使用されているソースドキュメントを確認することをお勧めします。小数を含む6つの異なる演算に使用する式 精度、スケール、長さ について説明しているためです。そのグラフは次のことを示しています。

操作:e1 * e2
結果の精度:p1 + p2 + 1
結果スケール:s1 + s2

DECIMAL(19, 10) * DECIMAL(3, 0)がある場合、次の値から始めます。

p1 = 19
p2 =  3

s1 = 10
s2 =  0

それは私たちに与えます:

Precision = (19 + 3 + 1) = 23
Scale     = (10 + 0) = 10

そして、SQL Serverによって報告されたDECIMAL(23, 10)と一致します。

さらに明確にするために、4番目の列をテストクエリに追加して、最初の除算の計算を結果のDECIMAL(19, 10)に減らしました。これにより、C2C3で発生する3つの数学演算の順序に疑問はありません。 。 sys.dm_exec_describe_first_result_set DMVも使用しているため、一時テーブルを作成する必要はありません:-)

SELECT rs.column_ordinal, rs.name, rs.system_type_name, rs.max_length,
       rs.[precision], rs.[scale]
FROM   sys.dm_exec_describe_first_result_set(N'
SELECT CAST(1 AS DECIMAL(9,0)) / CAST(2 AS DECIMAL(9,0)) AS C1
      ,CAST(1 AS DECIMAL(9,0)) / CAST(2 AS DECIMAL(9,0)) * 100 AS C2
     ,CAST(1 AS DECIMAL(9,0)) / CAST(2 AS DECIMAL(9,0)) * CAST(100 AS DECIMAL (3, 0)) AS C3
      ,CAST(0.5 AS DECIMAL(19,10)) * CAST(100 AS DECIMAL(3,0)) AS C4
', '', 0) rs

戻り値:

column_ordinal    name    system_type_name    max_length    precision    scale
--------------    ----    ----------------    ----------    ---------    -----
1                 C1      decimal(19,10)       9            19           10
2                 C2      decimal(23,10)      13            23           10
3                 C3      decimal(23,10)      13            23           10
4                 C4      decimal(23,10)      13            23           10

上記のリンクされたMSDNページからの精度およびスケール計算の完全なチャートは、便宜上以下にコピーされます。

Operation           Result precision                          Result scale *
---------           -----------------------------------       ------------
e1 + e2             max(s1, s2) + max(p1-s1, p2-s2) + 1       max(s1, s2)

e1 - e2             max(s1, s2) + max(p1-s1, p2-s2) + 1       max(s1, s2)

e1 * e2             p1 + p2 + 1                               s1 + s2

e1 / e2             p1 - s1 + s2 + max(6, s1 + p2 + 1)        max(6, s1 + p2 + 1)

e1 UNION |          max(s1, s2) + max(p1-s1, p2-s2)           max(s1, s2)
  EXCEPT |
 INTERSECT e2 

e1 % e2             min(p1-s1, p2 -s2) + max( s1,s2 )         max(s1, s2)

* The result precision and scale have an absolute maximum of 38.
  When a result precision is greater than 38, the corresponding scale
  is reduced to prevent the integral part of a result from being truncated.
2
Solomon Rutzky