サンプル・プログラム
複利計算
そこで、今回は境界値にスポットを当て、whileループを使ってプログラムを改良してみることにする。
44: //複利計算
45: let deposit = principal; //預金額
46: let year = 0;
47: while (deposit <= border) {
48: deposit *= (1 + rate);
49: year++;
50: }
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 \) を \( N \) の約数という。1と \( N \) 自身も、 \( N \) の約数である。
これをプログラムに書いたものが上述の "while2.html" である。
整数Nの約数は、 \( N \) 自身を除くと、最大でも \( N \) の2分の1整数である。無駄なループ回数を省くため、ループの終了条件は \( N \) の2分の1整数とする。
自然数 \( d \) を1から1ずつ加算していき、剰余演算子を使って割り切れれば、約数として文字列 divisor に加えてゆく。
ニュートン法
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();
ある適当な値 \( 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" である。
コラム:天体の位置計算
だが、『三体問題 天才たちを悩ませた400年の未解決問題』(浅田秀樹=著,講談社,2021年3月)にあるように、天体の位置を解く方程式は存在しない。このため漸化式を使って近似計算をしていったのだが、本節で紹介したような簡単な漸化式というわけにはいかず、プログラム電卓の小さなメモリには、ループ部分を収めるのが精一杯で、それ以外の計算は別のプログラムに分離して、プログラムをロードし直さなければならなかった。
関数電卓やExcelを使って複雑な数値計算をやっている方には、とくにプログラム技術を習得することをお勧めする。