2008年2月25日

エクセルは小数の計算が苦手・・・

00c89c88.gif http://pc.nikkeibp.co.jp/pc21/special/index.shtml

 後輩から,以前私がエクセルで作ったアンケート処理の式が理解できない,との苦情・・・
 配列数式で条件式(20代の男性で市内在住で女性問題に関心のある人の数をカウント,とか)をやっている部分

 一くさりうんちくを・・・と思いきや,残念ながら突然の来客があって,結局,{}の出し方を教えてその場はおしまい・・

 で,Webでうまい説明をしているところはないかと検索をかけて出てきたのが,このページ(◆"達人"芳坂和行氏に学ぶ、エクセル「配列数式」講座)
です。
 大変よくまとめてあり,非常によくわかります。

(ここから本題)
 さて,10年ほど前の職場では,123とエクセルが半々のシェアを争っていました。
 どちらを使うかは職員の好みだったのですが,私は,マクロの可読性の高さから,できるだけエクセルを使うようにしていました。(123のマクロは,アセンブラみたいだった)

 で,数字をかけたり割ったりしていると,時々,1だけ,「計算が合わない」場合があることに気付きました。
 随分気を付けてシートをチェックするのですが,「計算が合わない」場合の一般条件は,結局見つけられませんでした。

 問題が,エクセル内部の演算処理にあることは明らかだったのですが,どのような場合に「計算が合わない」のか,が明らかに出来ないと,対処のしようがありません・・・

 会社のシステム担当に相談すると,「全ての式をroundせよ」という,非現実的な答えが返ってきました・・(再計算に10分くらい掛かったはず・・・)

 そのころエクセルのマクロ本を出している人が運営していたメーリングリストでいろいろやり取りして,お書物の計算式とおりに式を組むと,誤差が累乗的に増加する場合があること(小数のかけ算・割り算とか),このような場合は,式を誤差が出にくい形に変形することとかいった処理で,随分「計算が合わない」場合は減ってきたのですが,それでも,誤差の出る計算式がどこに隠れているかわからない・・・

 たとえば,(当時の)地方債などは,積算は10万単位で申請は原則100万円単位,でも償還は1円単位(当たり前ですな)となっていて,それぞれに決められた様式があって,それで1000000で割ったり100000をかけたりしていました。(あと補助裏や充当率のチェックなど・・)

 ですから,1合わないということは,最大100万円合わないと言うことになります・・

 で,最終的に採った方法は,全て1円単位の整数で処理をして,最後に単位で揃えること。
 つまり,計算は別のシートで全て1円単位の整数でやってしまい,様式に表示するときのみ,様式の要求する単位に揃える,という方法です。

 エクセルは,整数は999兆円(15桁)までは正確にやってくれるので,
まあ,単年度の借金の計算くらいなら大丈夫,なわけです・・

 で,ここら辺の事情と対処法が,このURLの「◆"達人"芳坂和行氏に学ぶ、エクセル(Excel)「演算誤差」対策講座」に,詳しく解説されています。
 
 あの頃にこんなサイトが有れば,あんなに苦労しなくて済んだのに・・・
 なんだか悔しくて,全部読んでしまいました・・・


余談 その1)
 マクロでユーザー関数の定義はやりましたが,微小数を加える,というのは考えつかなかったなぁ・・・
 でも,あの膨大なシートの計算式から,対処の必要な式を対策するのは,事実上無理だったですな(3月前のシートの処理など,覚えていられないし)・・

余談 その2)
 そう言えば,決算統計の「1だけ合わない」にも困らされましたね・・
 いまはMD持ち込みだそうですが,これも1円単位なら「1だけ合わない」こともないのですね・・

余談 その3)
 国と地方の借金の総額(国際+地方債の額)は,19年度末で,773兆円です。
 もうすぐ,エクセルでは誤差が生じる領域に突入しそうです・・・
http://www.mof.go.jp/zaisei/con_03_g03.html