小数点の自動丸めの問題


11

質問は比較的簡単です。中間結果が巨大な10進数である3つの列を計算する必要があります。SQLServerで、キャスト/変換に関係なく基本的に小数点を丸める問題が発生しています。

たとえば、単純な除算を1234/1233としてみましょう。電卓は1,00081103000811を生成します。しかし、SQL Serverでこれを行うと、次のようになります。

-- Result: rounded at 1.000811000... with trailing zeroes up until the 37 precision
SELECT CAST(CAST(1234 AS DEC(38,34))/CAST(1233 AS DEC(38,34)) AS DEC(38,37))

-- Result: rounded at 1.000811
SELECT CONVERT(DECIMAL(38,32), 1234)/CONVERT(DECIMAL(38,32),1233)

-- Correct result at 1,00081103000811
-- But this requires the zeroes to be put in manually when you don't
-- even know the precision of the end result
SELECT 1234.0/1233.00000000000000

この自動丸めが行われるのはなぜですか?そして、テーブルにはさまざまな異なる値が含まれている可能性があるため、数値(intまたはdecの部分)の大きさがわからない場合に、非常に長い10進数値を計算するための最良の方法は何ですか?

ありがとう!

回答:


17

tl; dr

SQL言語で計算を行わない

より長いです

結果のスケールと精度は、MSDNで明確に定義されています。本当に直感的ではありません。ただし、簡単に言えば、入力スケールが高いと精度が失われます。これは、一致する精度の低下で結果スケールを38に下げる必要があるためです。

確認する

  • 最初の例の追加のCASTは単にゼロを追加します
  • 私のMSDNリンク(2番目の例)に従って切り捨てが発生します
  • 定数を使用した3番目の例では、暗黙の10進数値(5、1)と18、14)で十分です。
    これは、結果のスケールと精度に切り捨てがないことを意味します(以下を参照)

1番目と3番目のケースの詳細。

除算の結果スケールはmax(6, s1 + p2 + 1)次のとおりです。

  • 最初の例では、これは77であり、38に下げられます。精度は同様に強制的に下げられ、最低6が適用されます(これを参照)
  • 3番目の例、これは24なので、精度を調整する必要はありません

いくつかのオプションがあります

  • .netなどのクライアントコードで計算する
  • CLR関数を使用して.net計算を行う
  • 正確さを失わずに生きる
  • floatを使用し、最大で15の有効数字でライブする

最後に、SO /programming/423925/t-sql-decimal-division-accuracy/424052#424052でこれを参照してください


1

これが役立つかどうかはわかりませんが、一時テーブルの列が10進数に設定されていたため、convert(decimal(15,2)、0.65)を挿入からtemp_tableに渡していました。これは自動丸めでしたが、渡されたものと一致するように列タイプをdecimal(16,2)に変更しました。テーブルは現在0.65を格納しています。


1

回避する必要がありました。これが私がしたことです:

-----------------------------------
DECLARE @DENIED INT  = 33443
DECLARE @PAID INT = 148353
DECLARE @PCT Decimal (6,2)

SET @PCT = (@DENIED * 100.00 / @PAID)  -- Instead of dividing by 100, I included decimals

SELECT
@DENIED AS DEN
,@PAID AS PAID
,@PCT AS PCT

結果:

DEN PAID    PCT
-----   ----    -----
33443   148353  22.54   -- Instead of 22.00

お役に立てれば。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.