DECIMAL/NUMERIC 型の演算結果後の有効桁数が良く分からない。。。

MSDN を見ると、こんな感じの表が載っている。有効桁数、小数点以下桁数、および長さ (Transact-SQL)

演算 結果の有効桁数 結果の小数点以下桁数
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)

この結果桁数が大きくなった場合は、次のようなルールで桁数が調整されるようです。

有効桁数、小数点以下桁数、および長さ (Transact-SQL) より引用

結果の有効桁数と小数点以下桁数の絶対最大値は 38 です。結果の有効桁数が 38 を超える場合、結果の整数部分が切り捨てられないように、対応する小数点以下桁数が減らされます。


さてここで、次のクエリを実行してみます。

SELECT CAST(10.5555 AS DECIMAL(12,4)) + CAST(1.23 AS DECIMAL(38, 2))
SELECT CAST(10.5555 AS DECIMAL(12,4)) - CAST(1.23 AS DECIMAL(38, 2))
SELECT CAST(10.5555 AS DECIMAL(12,4)) * CAST(1.23 AS DECIMAL(38, 2))
SELECT CAST(10.5555 AS DECIMAL(12,4)) / CAST(1.23 AS DECIMAL(38, 2))


これを、上の表に当てはめてみると

演算 結果の有効桁数 結果の小数点以下桁数
CAST(10.5555 AS DECIMAL(12,4)) + CAST(1.23 AS DECIMAL(38, 2)) max(4, 2) + max(12-4, 38-2) + 1 max(4, 2)
CAST(10.5555 AS DECIMAL(12,4)) - CAST(1.23 AS DECIMAL(38, 2)) max(4, 2) + max(12-4, 38-2) + 1 max(4, 2)
CAST(10.5555 AS DECIMAL(12,4)) * CAST(1.23 AS DECIMAL(38, 2)) 12 + 38 + 1 4 + 2
CAST(10.5555 AS DECIMAL(12,4)) / CAST(1.23 AS DECIMAL(38, 2)) 12 - 4 + 2 + max(6, 4 + 38 + 1) max(6, 4 + 38 + 1)

計算すると…

演算 結果の有効桁数 結果の小数点以下桁数
CAST(10.5555 AS DECIMAL(12,4)) + CAST(1.23 AS DECIMAL(38, 2)) 41 4
CAST(10.5555 AS DECIMAL(12,4)) - CAST(1.23 AS DECIMAL(38, 2)) 41 4
CAST(10.5555 AS DECIMAL(12,4)) * CAST(1.23 AS DECIMAL(38, 2)) 51 6
CAST(10.5555 AS DECIMAL(12,4)) / CAST(1.23 AS DECIMAL(38, 2)) 53 43

実行結果のイメージから実際の桁数を予測すると、こんな感じ。

演算 結果の有効桁数 結果の小数点以下桁数
CAST(10.5555 AS DECIMAL(12,4)) + CAST(1.23 AS DECIMAL(38, 2)) 38 2
CAST(10.5555 AS DECIMAL(12,4)) - CAST(1.23 AS DECIMAL(38, 2)) 38 2
CAST(10.5555 AS DECIMAL(12,4)) * CAST(1.23 AS DECIMAL(38, 2)) 38 6
CAST(10.5555 AS DECIMAL(12,4)) / CAST(1.23 AS DECIMAL(38, 2)) 29 28

有効桁数、小数点以下桁数、および長さ (Transact-SQL) より引用

結果の有効桁数と小数点以下桁数の絶対最大値は 38 です。結果の有効桁数が 38 を超える場合、結果の整数部分が切り捨てられないように、対応する小数点以下桁数が減らされます。

このルールが良く分からないなぁ。。