3.4 whileループ

(1/1)
whileループ
whileループを使って複利計算や約数を求める。また、ニュートン法(近似計算法)によって平方根を求めるプログラムを作る。

目次

サンプル・プログラム

複利計算

JavaScriptで複利計算
3.3 forループ」で作った複利計算プログラム "for5.html" だが、期間 period が短いと、境界値を超える前に forループが終了してしまい、期待通りの結果を得られない。
そこで、今回は境界値にスポットを当て、whileループを使ってプログラムを改良してみることにする。

  44:         //複利計算
  45:         let deposit = principal;    //預金額
  46:         let year = 0;
  47:         while (deposit <border) {
  48:             deposit *= (1 + rate);
  49:             year++;
  50:         }

whileループは次のようにして使う。
while (繰り返し条件) {
    処理;
}
繰り返し条件が成立する間、ブレース {...} で囲まれたブロック文を実行する。

"while1.html" では、預金額 deposit が境界値 border 以下である間、複利計算を続けるようにしている。また、何年目の計算をしているのか分かるように、変数 year に計算回数を代入する。
whileループを使うことで、if文break を使うこともなく、簡単に結果を求めることができる。

約数を求める

次に、約数を求めるプログラムを作ってみよう。
約数計算

  35:         //約数計算
  36:         let a = Math.floor(n / 2+ 1;      //Nの2分の1整数
  37:         let d = 1;                          //除数
  38:         let divisor = '';                   //約数を格納
  39:         while (d <a) {
  40:             if (n % d == 0) {
  41:                 if (d > 1) {
  42:                     divisor +', ';
  43:                 }
  44:                 divisor +d.toString();
  45:             }
  46:             d++;
  47:         }
  48:         if (n > 1) {
  49:             divisor +', ';
  50:         }
  51:         divisor +n.toString();        //自分自身
  52:         ret = '約数は... ' + divisor;

整数 \(N, a, b \) について \( N = ab \) が成り立つとき \( a \) は \( N \) の約数という。ここで、 \( a \neq 0 \) とする。
言い方を変えると、 \( N \) を割り切れる自然数 \( a \) を \( N \) の約数という。1と \( N \) 自身も、 \( N \) の約数である。

これをプログラムに書いたものが上述の "while2.html" である。
整数Nの約数は、 \( N \) 自身を除くと、最大でも \( N \) の2分の1整数である。無駄なループ回数を省くため、ループの終了条件は \( N \) の2分の1整数とする。
自然数 \( d \) を1から1ずつ加算していき、剰余演算子を使って割り切れれば、約数として文字列 divisor に加えてゆく。

ニュートン法

約数を求める方程式は見つかっていない。そこで、"while2.html" ではループを回して、1つずつ約数に該当するかどうかを力ずくで計算した。このように方程式が存在しない問題の解を求めるとき、whileループがよく使われる。
ニュートン法による平方根計算
次に、ニュートン法を使って平方根を求めるプログラム "while3.html" を紹介しよう。

  37:         //平方根計算
  38:         let x = y * 2;      //xの初期値
  39:         while (true) {
  40:             //ニュートン法で新しいyを求める
  41:             let x2 = x - (x * x - y) / (x * y);
  42:             //誤差範囲内になったら計算終了
  43:             if (Math.abs(x2 - x< e)    break;
  44:             //x←x2として計算を繰り返す
  45:             x = x2;
  46:         }
  47:         root = '近似値 = ' + x.toString();

ニュートン法とは、 \( f(x)=0 \) の解 \( x \) を求める近似計算法である。
ある適当な値 \( x_0 \) から計算を開始し、
\[ x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)} \]
という漸化式を計算すると、\( n \) が大きくなるほど解 \( x \) に収束していく。

平方根 \( \sqrt y \) の解を求めるには、
\[ f(x) = x^2 - y \]
とおき、 \( f(x)=0 \) の解を求めることを考える。
ここで、 \( f'(x)=2x \) であることから、漸化式は
\[ x_{n+1} = x_n - \frac{x_{n}^2 - 2}{2 x_n} = \frac{1}{2}(x_n + \frac{2}{x_n}) \]
となる。
あらかじめ誤差 \( e \) を設けておき、 \( x_{n}^2 \) と \( y \) の差が \( e \)より小さくなるまで漸化式を繰り返し計算する。これをプログラムにしたものが "while3.html" である。

コラム:天体の位置計算

関数電卓「FX-31」
関数電卓「FX-31」
「1.3 四則計算と変数」のコラムに書いたように、私がプログラムを作り始めたきっかけはハレー彗星の位置を計算することだった。
だが、『三体問題 天才たちを悩ませた400年の未解決問題』(浅田秀樹=著,講談社,2021年3月)にあるように、天体の位置を解く方程式は存在しない。このため漸化式を使って近似計算をしていったのだが、本節で紹介したような簡単な漸化式というわけにはいかず、プログラム電卓の小さなメモリには、ループ部分を収めるのが精一杯で、それ以外の計算は別のプログラムに分離して、プログラムをロードし直さなければならなかった。
それでも、関数電卓を使って漸化式の結果を計算帳に手書きでメモした時に比べれば格段に早く計算ができた。

関数電卓やExcelを使って複雑な数値計算をやっている方には、とくにプログラム技術を習得することをお勧めする。
(この項おわり)
header