p11190.jpg

上式の通り、ごく簡単な、ベキ級数の合計を算出する問題。変数 l, h, k の値はともに1~15000000、hとlとの差は1000以内。

kの値が10以内なら、探せば、それなりの計算式が出てくるが、1500万ではそんな式は存在しないだろう。

力任せで、C言語の数学関数をそのまま使うと、無限大になってしまい、計算不能になる。

考え方
 合計値は級数の後ろの項によってほぼ決まるので、級数の末尾から計算することにしよう。

大事なことは、個々の項の値を、仮数部と指数部に分けておく。

例えば、999100、998100の値を
  999100 仮数部 0.9047921471 指数部 e+300
  998100 仮数部 0.8185668046 指数部 e+300
に分ける。

指数部の値が1つ違うと、項の値として1桁も違ってくる。指数部の値が5も違うと、5桁も右の部分にしか影響しないので、その後の計算を打ち切っても全体の合計値にほとんど影響がないだろうと考えてよい。例えば、
  880100 仮数部 0.2807160311 指数部 e+295
当たりから、その後の合計計算を打ち切る。基数やkの値が大きければ大きいほどすぐに打ち切ることになる。

また、合計の計算では、級数の末尾から項ひとつひとつ足していくが、個々の項の指数部は、末尾項の指数部の値に(つまり、最大指数部)に合わせて、仮数部の小数点をシフトさせる。
 上の例では、級数の末尾項が999100なら、個々の項の指数部の値をe+300に統一して、仮数部の値を合計する。
  970100 仮数部 0.0475525075 指数部 e+300

なお、シフトする前の仮数部、指数部は以下の数学関数でも求めることができる。

 ベキ乗 xk → 仮数部 pow(10, modf(k*log10(x), &e)) 指数部 左の e

最後に、元問題の検証データを載せておく(入力データの各行は左から、l, h, kの値)

10 10 1000000
14999001 15000100 1
14999001 15000000 15000000
0 0 15000000
0 1 15000000
0 0 1
Case 0001: 0.100000e0001000001
Case 0002: 0.164995e0000000011
Case 0003: 0.121628e0107641370
Case 0004: 0.000000e0000000001
Case 0005: 0.100000e0000000001
Case 0006: 0.000000e0000000001

Comments are closed.

Post Navigation