|
●概要 級数で求めるが、収束速度を速める工夫を行う。 ●級数 eX = (Xk/k!) [k = 0 to ∞] で、X = 1 とすれば良い。そのままでは、100万桁に達するには、約21万回の演算が必要となる。 ●1/N する e = (e(1/N))N であるから、e(1/N) を求め、N乗すれば e となるはず。今、例えば、N = 108 とすれば、e0.00000001 を計算する。これで、収束が速くなる。一般的に表せば、 d = ((10-m)k/k!) とすれば、e = d^10m となる。 下表は、m の値による100万桁までの収束回数を求めたものである。級数の演算時間は期待できる。
T正直 > T1/N + T冪乗 であれば、この方式は成立。 ●実際の演算 d = 1 + 10-m/1 + 10-2m/(1・2) + 10-3m/(1・2・3) + ・・・・・・・・・・・・ k番目の一般項は、(10-(k-1)m・10-m)/((k-1)!・k) となる。良く見ると、赤字の部分は、一つ前の項目の値である。つまり、前の部分値の10-m を乗算し、それを k で割れば良いことになる。 ところで、(10-m)k の計算は、正直に冪乗する必要はなく、浮動小数点の指数部のみの加算で済む。そうすれば乗算はなくなり、除算も DivI であるから速い。実際には、10-m で乗算しても内部では指数部の加減算のみで行っている。しかし、オーバヘッドが多いので、直接指数部の加減算をした方が速い。 演算カーネルを示すと、
演算時間として考慮すべき部分は、上カーネルの赤字部分である。当然、10m乗は二進展開法で算出する。最後の冪乗による精度の劣化が気になるところであるが。 ●時間予測 今、N = 10m で m を、4、8、12、16 として予測してみる。 ○級数演算時間 下図は、ユーティリティのカーネル演算時間予測ツールで予測した結果である。実測値は多分これより大きくなるが目安にはなる。
変数オーダ 0 が、そのまま級数で求めた場合である。これらの時間には、冪乗算時間 T冪乗 は含まれていない。次に、T冪乗 を予測する。100万桁ではまともに行うより、4倍くらい高速化されそう。 ○冪乗算時間 まともに、X10^m を行えば途方もない時間が掛かってしまう。当然、二進展開法で行う。正確に予測するために、先ず10m を二進数で表し、ビット長と 1 のビット数の合計を算出する。この数が乗算回数となる。以下の表のようになった。
桁数の大きい部分では、級数時間に加算しても影響は小さく、T正直 > T1/N + T冪乗
が成立するのでので、本法は有効と言えそう。 ●実測 下図は上記の方法で実際に確認した結果である。
級数直接は、(1/k!) で求めたもの、10^m は、1/10^m した場合である。冪乗算の時間も含まれる。結果は、収束回数/時間/真値との一致桁数となっている。桁数が大きいところでは 10^16 の効果が大きい。さすがに、一致桁数は減少するが、予め公称精度を余計にしておけば済む。
|