web-dev-qa-db-ja.com

10進数演算に関する質問

次の例では意味のない値が生成されるため、精度とスケールの理解が間違っていると思います。 decimal(32, 14)は結果を小数点以下6桁に丸めますが、decimal(18, 14)は19に丸めます。小数についての私の理解はdecimal(p, [s])です。ここで、pは合計桁数とsは、小数点以下の桁数です(たとえば、decimal(10, 2)は、小数点の左側に8桁、右側に2桁になります)。これは正しくありませんか?

一見奇妙な動作を示す小さな例を作成しました。

--------------------
-- Truncates at pipe
-- 1.043686|655...
--------------------
declare @dVal1 decimal(32, 14) = 10
declare @dVal2 decimal(32, 14) = 9.581419815465469

select @dVal1 Val1, @dVal2 Val2, @dVal1 / @dVal2 CalcResult

----------------
-- Most accurate
----------------
declare @dVal3 decimal(18, 14) = 10
declare @dVal4 decimal(18, 14) = 9.581419815465469

select @dVal3 Val3, @dVal4 Val4, @dVal3 / @dVal4 CalcResult

では、質問について、これを理解するのに何が欠けているのでしょうか?私が読んだ記事やmsdnブログは、(少なくとも私の思考プロセスでは)明確さを提供していないようです。精度を高くするとスケールが失われるように見える理由を誰かに説明できますか?

5
Mythikos

@dVal2@dVal4の桁数が1桁多すぎますが、selectの最後の桁が7に切り上げられるのはこのためです(9.58141981546547)。

除算の丸めに関しては、ドキュメントの の真ん中に隠されています

乗算と除算の演算では、精度が必要です。つまり、結果の整数部分を格納する場所をスケールします。以下のルールを使用して、規模を縮小する場合があります。

整数部分が32未満の場合、結果のスケールはmin(scale、38 –(precision-scale))に縮小されます。これは、38 –(precision-scale)を超えることはできないためです。この場合、結果は丸められる可能性があります。

スケールが6未満で、整数部が32より大きい場合、スケールは変更されません。この場合、decimal(38、scale)に収まらない場合、オーバーフローエラーが発生する可能性があります。

6より大きい場合、および整数部が32より大きい場合、スケールは6に設定されます。この場合、整数部とスケールの両方が削減され、結果の型はdecimal(38,6)になります。整数部が32桁に収まらない場合、結果が小数点以下6桁に丸められるか、オーバーフローエラーがスローされます。

最初のケースdecimal(32,14)では、結果の値decimal(64,28)scale = 28が> 6であり、整数部(64-28) = 36が> 32であるので、スケールは6桁に設定されています。上記の最後のルール。したがって、decimal(38,6)

2番目のケースdecimal(18,14)では、最初のルールがdecimal(36,28)からmin(28, 38 -(36-28)) = min(28,30) = 28の結果値のスケールに適用されています。したがって、decimal(38,28)

3
scsimon