1. ホーム
  2. sql-server

会計アプリケーションの金額には、floatとdecimalのどちらを使用しますか?

2023-08-30 11:57:23

質問

私たちは、レガシーな 会計システム をVB.NETとSQL Serverで書き換えています。この書き換えを行うために、.NET/SQLプログラマーの新しいチームを導入しました。システムの大部分はすでに完成しており、ドルの金額には浮動小数点が使われています。私がプログラミングしたレガシー システムの言語には浮動小数点がなかったので、おそらく小数を使用していたことでしょう。

お勧めの方法は何ですか?

ドルの金額にはfloatとdecimalのどちらのデータ型を使用すべきですか?

どちらかの長所と短所は何ですか?

ひとつは コン

に記載されている デイリースクラム で述べたように、小数点以下2桁以上の結果を返す金額を計算する場合は注意が必要です。金額を小数点以下2桁に丸める必要があるようです。

もうひとつ コン は、すべてのディスプレイや印刷物には フォーマットステートメント で、小数点以下が2つ表示されます。これが行われていないために、金額が正しく表示されないことが何度かありました。 (例: 10.2 または 10.2546)

A pro は、10 進法では 9 バイトを消費するところ、フロートのみのアプローチではディスク上で 8 バイトを消費します (10 進法の 12,2)。

どのように解決するのですか?

金額のデータ型はFloatとDecimalのどちらを使用すべきですか?

答えは簡単です。決してフロートではありません。 決して !

浮き輪は、以下の通りです。 IEEE 754 は常にバイナリでしたが、新しい規格である IEEE 754R は 10 進法のフォーマットを定義しています。小数の 2 進法の部分の多くは、正確な 10 進法の表現と等しくなることはありません。

どんな2進数も次のように書くことができます。 m/2^n ( m , n 正の整数)、任意の10進数として m/(2^n*5^n) . バイナリには素数がないため factor 5 がないため、すべての2進数は10進数で正確に表すことができますが、その逆はできません。

0.3 = 3/(2^1 * 5^1) = 0.3

0.3 = [0.25/0.5] [0.25/0.375] [0.25/3.125] [0.2825/3.125]

          1/4         1/8         1/16          1/32

結局、与えられた10進数より大きいか小さいかの数字になるわけですね。常にです。

なぜそれが問題になるのか?四捨五入です。

通常の四捨五入は、下は0...4、上は5...9を意味します。つまりそれは は行います。 であっても問題ありません。 どちらか 0.049999999999 であるか 0.0500000000 ... あなたはこれが5セントの意味であることを知っているかもしれませんが、コンピュータはそれを知らずに、丸めずに 0.4999 ... を切り捨て(間違って)、そして 0.5000 ... 上(正しい)。

浮動小数点演算の結果が常に小さな誤差項を含むことを考えると、その判断は純粋に運と言えます。2進数で10進法のラウンド トゥ イーブン処理をしたい場合は、絶望的な状況になります。

納得がいきませんか?あなたは、あなたの勘定科目システムでは、すべてが完璧に大丈夫だと主張しますか? 資産と負債が同じだと?わかりました、では、各エントリの与えられたフォーマットされた数字をそれぞれ取り、それらを解析し、独立した十進法でそれらを合計してください!

フォーマットされた合計と比較してみてください。おっと、何か間違っていますね?

この計算には、非常に高い精度と忠実度が必要でした (私たちは Oracle の FLOAT を使用しました)。 FLOAT を使用しました)、つまり、10 億分の 1 ペニーを記録することができたのです。

それはこのエラーに対して役に立ちません。なぜなら、すべての人がコンピューターが正しく計算すると自動的に思い込んでしまい、実質的に誰も独自にチェックしないからです。