普通の電卓で対数を求める

普通の電卓には対数を求める機能はないと思いますが、何とかして求めてみます。

たとえば、 \log_{10} 2を求めてみます。

2×2=4、4×2=8、8×2=16……のように2nを求めていきます。すると、210=1024が10の累乗数に近いことが分かります。この関係から、 \log_{10} 2 \fallingdotseq 0.3であることが分かります。

このまま2nをどんどん求めていけばより正確な値が分かるはずですが、さすがに非効率なのでもうちょっとましな方法を考えます。

先ほど求めた210=1024は、10の累乗数より少し大きい値でした。これを二乗したりしても、10の累乗数から遠ざかるばかりで、精度のよい近似が得られるわけではなさそうです。 そこで、逆に10の累乗数より少し小さな値を探します。今まで求めた数の中では、23=8が10の累乗数を超えずになるべく近い値になっています。

ここで、両者を掛け合わせると、213=8192となって23=8よりも10の累乗数に近づきました。23=8はもう覚えておく必要はありません。210=1024と213=8192だけ覚えておきましょう。

次は213=8192と210=1024を掛け合わせます。すると223=8388608が得られます。213=8192はもう忘れて、223=8388608だけ覚えておきます。

この手順を繰り返して223=8388608と210=1024を掛け合わせると、電卓の桁数制限に引っかかってしまうかもしれません。適宜10で割ることで桁あふれしないように注意しながら繰り返します。

すると、293=9.90352×1027や2103=1.01412×1031が得られます。後者は10の累乗数より大きい値で、210=1024よりも10の累乗数に近い値なので、210=1024と交代して以降続けます。

この手順を高校の授業で知った時は感動したのですが、今から思うとこの方法はかなり非効率です。

この方法は \log_{10} 2の上界の最良近似分数と下界の最良近似分数を列挙していくアルゴリズムになっています。やっていることは \log_{10} 2と1の間の最大公約数を求めるユークリッドアルゴリズムを互減法で実行していることに等しく、最悪の場合は求めたい精度の逆数に比例した時間がかかります。 これは必要な桁数の指数に比例する時間がかかるということで、大変非効率です。

なんとかして互除法的にアルゴリズムを効率化できないでしょうか?

 xが小さい時に成り立つ \ln (1+x) \simeq xという近似式を使って \ln 1.024 \simeq 0.024 \ln 0.8 \simeq -0.2と思えば、対数の底の変換公式を用いて \frac{\log_{10} 0.8}{\log_{10} 1.024} =\frac{\ln 0.8}{\ln 1.024}\simeq-8.33と(普通の電卓のみを用いて)計算できます。

これが意味するところは、 2^3 \times \left(2^{10}\right)^8は10の累乗数よりやや小さく、 2^3 \times \left(2^{10}\right)^9は10の累乗数よりやや大きいという意味になります。 あっていませんね。 \ln 0.8 \simeq -0.2という部分の誤差が大きかったのが原因です(実際は \ln 0.8 = -0.223なので、10%以上ずれています)。

近似値を使っているため、このように1ずれることが発生することがあります。結局、 2^3 \times \left(2^{10}\right)^9を計算してみて10の累乗数より小さいか大きいかということは確かめる必要があります。

このようにすれば互除法的な速度で精度を上げていくことができるはずです。