こんにちは高木です。今回も別サイトで過去に投稿した内容のリライトになります。 今回の内容は特定のプログラミング言語に依存した内容ではありませんし、おそらくプログラミング以外でも役に立つのではないかと思っています。
プログラミングをやっていると、ちょっとした数学的な計算が必要になることがあります。たとえば、半径が分かっている円の円周を求めたいといったことですね。
半径を \(r\) とすると、円周は \(2 \pi r\) で求まりますね。プログラミングでは、\(\pi\) に実際の数値をあてはめて、\(2 \times 3.141593 \times r\) のように計算します。
ところが円周率を表す部分で小数が出てきます。コンピュータでは、小数の計算にはFPU(= Floating Point Unit)という専用のハードウェアを使うのですが、ローエンドのマイコンはそんな高級なハードウェアは持っていません。
FPUが使えない場合、やむを得ずソフトウェアで計算を行うのですが、そうなるとプログラムはとても大きく、とても遅くなります。場合によっては、使用可能なメモリのサイズを超えてしまうかもしれませんし、要求されている時間内に計算を終えることができないかもしれません。
何とか小数を使わずに円周率の計算を行いたいものです。もっとも安直な方法は、円周率を小数点以下第6位まで表現するのであれば、あらかじめ100万倍した円周率を掛け、最後に100万分の1にするというものです。
$$2 \times 3141593 \times r \div 1000000$$
ところが、この方法だと大きな桁を扱わなければなりません。ローエンドのマイコンの場合、4~5桁ならともかく、それ以上を扱うときは、小数ほどではありませんが、プログラムが大きく、遅くなります。
そこで、円周率の近似値に \(3.141593\) という小数ではなく、\(\frac {355} {113}\) という分数を使うことにしてみます。
$$2 \times \frac {355} {113} \times r$$
\(r\) の値にもよりますが、今度はそれほど大きな桁にはならずに済みそうです。
この \(\frac {355} {113}\) という分数は、小数に直すと \(3.14159292 \cdots\) ということで、かなり精度の高い近似値です。これは、\(113355\) という覚えやすい数字の並びを真ん中で半分にして、分母と分子にすればよいので、小数を覚えるよりずっと楽です。
この類いのノウハウを知っていると、プログラミングはずいぶん楽になりますし、小さく速いプログラムを書けるかどうかにも関わってくるのです。