SQL Antipatterns ch10 Rounding Errors
- Rounding Errors
- Objective: Use Fractional Numbers Instead of Integers
- Antipattern: Use FLOAT Data Type
- How to Recognize the Antipattern
- Legitimate Uses of the Antipattern
- Solution: Use NUMERIC Data Type
Rounding Errors
Do not use FLOAT if you can avoid it.
- お金絡みの計算で浮動小数点数を使用し、誤差が生じる話
Objective: Use Fractional Numbers Instead of Integers
- 59.95ドルとか表現したい
Antipattern: Use FLOAT Data Type
- 他のプログラミング言語のfloatやdouble同様、IEEE754仕様
- IEEE754仕様の性質を知ることが重要
Rouding by Necessity
- 符号部、指数部、仮数部からなる
- 指数部、仮数部は2進数表現
- 10進数で有限桁で表現できる数値が、2進数では有限桁で表現できなかったりする
- その場合、最も近い値で近似される
- e.g. 59.95 は 59.950000762939...
- DB製品によってはDOUBLE PRECISION型とかREAL型とかがあるが、同様の性質を有する
コラム: Meet the IEEE 754 Format
- 科学計算分野では浮動小数点数が有用
- 値の範囲が広いから
- 【補】有効桁数という考え方があるから
- お金の計算には向かない
- Goldberg氏の資料など参照
Using FLOAT in SQL
- DB製品によっては表示上誤差を無くしてくれたりする
- が、データは誤差含みで格納される
- 厳密な等価比較が成立しない
- 誤差は蓄積する
- 総和
- 総乗はさらに深刻
- 複利計算など
How to Recognize the Antipattern
- 下記データ型が利用されている場所すべてが疑われる
- FLOAT
- REAL
- DOUBLE PRECISION
- たいていのシステムではIEEE754仕様の値域を必要としない
- アプリケーションコード側で「float」等が使われるため引きずられがちだが、より適切なデータ型がある可能性がある
Legitimate Uses of the Antipattern
- INTEGERやNUMERICよりも広い値域が必要な場合
- 科学計算
- OracleのFLOAT型はScaled Numericの意
- 他のDB製品でいうところのFLOATにあたるのはBINARY_FLOAT型
Solution: Use NUMERIC Data Type
NUMERIC(桁数,小数点以下桁数)
- 依然として
1/3
等は正確に表現できないが、少なくとも慣れ親しんだ10進数表現にはなる- 59.95等を正確に格納できる