オオスミBLOG スタッフが現場の様子をお届けオオスミBLOG スタッフが現場の様子をお届け

コンピューターの苦手な計算

 本来、数は無限です。しかし、それをコンピューターで扱う場合、有限なonとoffの処理となるため、数値のズレが生じます。そのズレは、通常の計算では十分無視できるものですが、場合によっては、それが間違った結果を出すこともあります。

有効数字の丸めを自動処理したい

 1tu-rusakusei.jpg私たちの行っている環境測定においては、測定結果を報告する際に、測定値を有効数字で表示する必要があります。業務でデータ処理を行う際は、エクセルへ測定値を入力して計算を行った後、その計算結果ついて、ひとつずつ手作業で表示桁数を合わせていくといったことを行ったりします。

 測定値が膨大となると、この作業が煩雑となり、「計算までは自動処理で行っているのに、なんでここに手間を掛けなければいけないのか、表示桁合わせまで自動で処理できれば余計な手間を掛けずにすむのに」と思えたので、エクセルのVBAを使って有効数値で丸めを行うユーザー定義関数を作成したことがあります。

有効数字で丸める方法

 まず、値の丸めはRound関数で行えます。しかし、未知の数値を有効数字で丸めるには、値の桁が不明のため、丸めを行う桁数が幾つなのかを求めなければなりません。

 そこで演算を行う方法を考えてみました。

 結果、値の桁数は、常用対数で算出することができます。まず、対象となる値の常用対数を計算し、その整数部を求め、それに有効桁分を加味すれば良いので、「-Int(Log(数値)/log(10))+有効数字の桁数-1」の計算結果をRound関数で丸める桁として指定すれば、有効数字での丸める関数を作れる。ということで、ユーザー定義関数を作成し、実際に動作させてみました。

作成した関数を動作させたところ

 その結果、大方はうまく動作したものの、まれに表示桁がおかしくなることもありました。特定の条件で適応しない計算方法になっているかと見直ししてみましたが、何度見直しても計算方法に問題はなさそうに思えました。

 そのため、演算過程の値を確認していったところ、演算中の値にズレが生じており、例えば、Log10(1000)=3でなければならないところが、Log10(1000)=2.9999....となっており、3桁の値でなく2桁の値として処理がおこなわれていました。これは、10進数の値を、有限桁の2進数として表現する際に発生してしまう誤差であり、他のプログラム言語では10進数用の変数の型などあるようですが、エクセルVBAでは回避できないものとなります。

 そこで、数値の桁数を得るための別の方法を考えてみました。

桁数を得る方法

 pc.jpg10進数をコンピューターで扱う際に誤差をなくす方法としては、整数か文字列で扱うと良いらしい、ということで、文字列として処理を行う方法を取ることとしました。

 その方法とは、数値を文字列へ変換し、1より大きい値ならば、小数点の左側の文字数を数える、1より小さければ、小数点の後に続く「0」の個数を数えるという、人が数値の桁を知るために行うのと同じような方法です。そして、この方法で行えば、計算によるズレが生じることもなく、値の桁を得ることができるようになりました。

コンピューターの演算には誤差が生じている

 この有効数字を求めるユーザー定義関数の作成にあったっては、当初、コンピューターは数値の扱いが得意であろうと思い、値の桁数を演算により求めることがスマートかつ正しい結果を得られると考えていました。しかし、実際は、間違いが発生する結果となり、それよりも、文字数を数えるといった、あまりスマートとは思えない処理を行うほうが、正しい答えを得ることが可能でした。

 コンピューターでの演算処理は、あくまで近似値であり、常に微小な誤差を含んでいます。通常の計算では問題になることはないものの、たまに、それが悪さをしてしまうこともあります。

調査第二グループ 灰塚