Microsoft Excel の ODBC ドライバが持つ小数の誤差について (unibon)

2003年02月25日: 新規作成。
Microsoft Excel を ODBC ドライバ経由でアクセスした際に、理論値を超える小数の誤差があることに気づきました。

実例をあげると 4.6 の取り扱いが変だと思っています。
Excel のあるセルに 4.6 を書いて、それを ODBC ドライバを使ってアクセスすると、見た目には 4.6 が得られます。
その Double の値を IEEE 754 の倍精度の浮動小数点で表現したビットパターンとみなして見てみると、VB 風に書くと &H4012666666666667 という 8 バイトの値が得られます。
しかし、本来、4.6 のビットパターンは &H4012666666666666 であるべきです。桁数が無限に続くなら &H4012666666666666666666666... のように 6 が無限に続くはずです。

(以下、2進数なので桁の概念は厳密には 1 ビットやそれがいくつか連続した n ビットで考えるべきかもしれませんが、 簡単のため 4 ビット単位(16進数の1桁)で考えることにします。)

この値はあたかも最下位の桁が 6 から 7 に切り上げられてしまっているような感じです。
ちなみに 4.3 = &H4011333333333333 でした。また 4.4 = &H401199999999999A でした。
4.3 の場合は最下位が 3 なので切り捨ては妥当だと思われますし、4.4 の場合は最下位が 9 から A に切り上がっていますが、これは 10 進数の4捨5入に相当することが 16 進数では 7捨8入 になると思われますので、妥当だと思われます。
しかし上述の 4.6 は最下位が 6 ですから、これを切り上げるのは 7捨8入 には当てはまりません。
もしかしたら Excel の ODBC ドライバの内部では 7捨8入 を目論んでいるのに、誤って 16 進数でも 4捨5入 にしてしまっているのかもしれません。
ちなみに Excel のセルを Excel VBA でアクセスした限りでは大丈夫でした。また Access(Jet) を ODBC ドライバでアクセスした場合も大丈夫でした。
この問題は Excel を使い、かつそれを ODBC ドライバ(や ODBC ブリッジを使った ADO)でアクセスした場合にのみ発生します。

なお、4.6 以外にも同様に変な扱いになっている値には 3.3 などがあります。


読み物の目次
ホーム
(このページ自身の絶対的な URL)