布団が俺を呼んでいる

丘山大一のぶろぐ

Firebird のお勉強 計算時の小数点以下の有効範囲

SQL上で計算した時の結果がどうにも理解できなくてはまりました。
しかし、同じことを考える人はいるもので。結論はStack overflow に出ています。

以下、ちょっと解説。

計算時の有効桁数具体例
Firebird の 計算時の小数点以下の有効桁数は、「計算に使用した型が持つ有効範囲」を足し合わせたものになります。
……と、こう書いても意味不明なので具体例。

SELECT cast (1/999999999999 AS numeric(18,13)) FROM HOGE;
SELECT cast (1.000000000000/999999999999 AS numeric(18,13)) FROM HOGE;
SELECT cast (1.000000/999999999999.000000 AS numeric(18,13)) FROM HOGE;
SELECT cast (1E0/999999999999 AS numeric(18,13)) FROM HOGE;

結果は、
0.0000000000000
0.0000000000010
0.0000000000010
0.0000000000010
となります。

1つ目は、分子・分母両方とも小数点以下が存在しません。そのため、計算時の有効桁数は「0 + 0 = 0」です。有効桁数が足りないので、結果表示時にnumeric(18,13)を指定しても、結果は「0.0000000000000」となります。
2つ目は、分子に小数点以下の桁数が存在しています。そのため、計算時の有効桁数は「12 + 0 = 12」です。
3つ目は、分子・分母両方に小数点以下が存在します。そのため、計算時の有効桁数は「6 + 6 = 12」です。
4つ目は、分子に「小数点以下を表示するための記号」である「E0」が指定されているため、計算時の有効桁数はdouble 型となるようです。

テーブルで確認してみる

簡単なテーブルを作成してみます。

CREATE TABLE HOGE(
    KEY_NO integer,
    VALUE_INT integer,
    VALUE_NUMERIC_SHORT numeric(18,1),
    VALUE_NUMERIC_LOMG numeric(18,13)
);
INSERT INTO HOGE VALUES(1,1,99999,99999);
SELECT cast (VALUE_INT /VALUE_NUMERIC_SHORT AS numeric(18,13)) FROM HOGE where KEY_NO = 1;
SELECT cast (VALUE_INT /VALUE_NUMERIC_LOMG AS numeric(18,13)) FROM HOGE where KEY_NO = 1;

結果はこうなります。
0.0000000000000
0.0000100001000

理屈は上記と一緒ですね。

無理矢理計算するなら、さらにCASTをかませるという手もなくはありません。

SELECT cast (VALUE_INT / (cast (VALUE_NUMERIC_SHORT AS numeric(18,13))) AS numeric(18,13)) FROM HOGE
where KEY_NO = 1;

こうすれば、
0.0000100001000
となります。


達人に学ぶ SQL徹底指南書 (CodeZine BOOKS)

新品価格
¥2,592から
(2016/8/14 21:47時点)

コメントを書く