JavaScript 「369の法則」の計算と出力 3/3

前回は、天才発明家ニコラ・テスラ氏の「369の法則」の計算式を、Windows 環境ならばインストール不要で使えるプログラミング言語 JavaScript で作成して実行した例を紹介しました。

前回の記事:JavaScript 「369の法則」の計算と出力 2/3 | Compota-Soft-Press

https://pixabay.com/ja/photos/ニコラ-テスラ-電気-パワー-3228001/
ニコラ テスラ 電気 – Pixabayの無料写真 – Pixabay
JavaScript 倍加した値の各桁の和を 1 桁になるまで繰り返す処理の出力結果
「369の法則」の通り、3, 6, 9 の倍数ではない場合、計算結果は 1, 2, 4, 8, 7, 5 を繰り返し、 3, 6, 9 は現れません。

今回は、前回作った「369の法則」の計算式の初期値や繰り返し回数HTML の Input 要素で指定して計算できるようにユーザーインターフェースを追加します。
また、大きな数値も扱えるように JavaScript の長整数 BigInt に変更する手順も紹介します。
※OS は Windows 10、HTML を開くウェブブラウザは Chrome です。

HTML の Input 要素を追加する

HTML の Input 要素は type 属性に

  • “text” と指定すれば文字列を入力するボックス
  • “number” と指定すれば数字を入力するスピン(数値を増減する上下の三角形)付きのボックス
  • “button” と指定すれば指定した JavaScript 関数を呼び出せるボタン

というように、 type によって様々な入力形式に対応した GUI を表示できます。

参照:入力欄(フォーム入力)要素 – HTML: ハイパーテキストマークアップ言語 | MDN

今回は、以下のように「倍加する初期値」と「倍加を繰り返す回数」と「計算を実行するボタン」の Input 要素を追加します。

<!DOCTYPE html>
<html>
<body bgcolor="#CCFF99">

<h1>倍加した値の桁ごとの和が 1 桁になるまで繰り返す計算</h1>

<label>倍加する初期値</label>
<input id="initialValue" type ="number" value="1" min="1"/>
<label>倍加の繰り返し回数</label>
<input id="loopCount" type ="number" value="33" min="1"/>
<input type="button" value="Calculate" onclick="SumOfDigitsOfDoubledNumber()" />
<br>
<p id="demo">ここに計算結果が出力されます。</p>

<script>
	function SumOfDigitsOfDoubledNumber()
	{
		digits = [];	// 各桁の値を出力用に保持する一時的な配列
		str = "";	// 出力する文字列の変数
		val = document.getElementById("initialValue").value;	// 倍加する初期値
		loopCount = document.getElementById("loopCount").value;	// 倍加を繰り返す回数
		// =====関数のコード以下省略=====
	}
</script>

</body>
</html>

HTML の最初の方に input タグの要素を 3 つ追加しました。

id が initialValue の input は type 属性が number で、倍加する初期値を入力する数値のボックスです。
id が loopCount の input は type 属性が number で、倍加を繰り返す回数を入力する数値のボックスです。

JavaScript のコードでは、 getElementById 関数に id の initialValue, loopCount を指定することで、それぞれの要素の value (入力されている値) を受け取っています。

id が Calculate の input は type 属性が button で、ボタンが表示されます。このボタンを押すと onClick 属性で指定した関数名と同じ JavaScript のコード内の関数が呼び出されます。

今までは <script> タグの中に直接処理を書いていましたが、ボタンから呼び出せるように、 function で定義した関数の中に処理を移動しました。

JavaScript 369の法則の計算のパラメータを HTML の Input 要素で指定する例

JavaScript の変数が扱う数値の上限

Input 要素を追加した実行例の図を見ると、最後の (25) 行目に

(25) val > 9007199254740991(Number.MAX_SAFE_INTEGER)

と表示されています。
これは、筆者が追加したコードによって表示された値です。

Number.MAX_SAFE_INTEGER は、JavaScript の通常の変数で数値を扱う際の上限値を表していて、それを超えた場合、正しい計算が出来なくなります。

そのため、変数 val の値を倍加した際に上限値を超えた場合は、このメッセージを表示して処理を終了するようにしました。

長整数 BigInt への変換

JavaScript で扱う数値の上限値を超えた計算をしたい場合は、JavaScript 標準で利用できる長整数 BigInt を利用します。

BigInt の利用例を紹介します。

		val = BigInt(document.getElementById("initialValue").value);
		tmp = 3n;
		val = val * 2n;

1行目は、変数の値を BigInt に変換して代入する例です。
代入先変数 = BigInt(代入元変数); の形式で代入することで、代入先変数は代入元変数の数値を BigInt で扱います。

2 行目は、変数ではなく直接数値を代入する際のリテラルです。数値の後に n をつけることで代入先変数は BigInt でその値を扱います。

3 行目は BigInt の計算式では数値を混ぜることができないため 2n というように長整数リテラルで BigInt にして計算しています。

今回の場合は、倍加する値を扱う変数 val, tmp を BigInt に変換します。

BigInt の注意点

BigInt と数値を混ぜた計算は以下のようにエラーになります。

Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions

このエラーを回避するには以下が挙げられます。

  • どちらも BigInt にする
  • BigInt を数値に戻す

BigInt を数値に戻す場合は num = Number(bigint); のように Number 関数を使います。
※ parseInt 関数を使う方法もあります。

digit = Number(tmp % base);

tmp と base は BigInt です。しかし、base = 10 なので、 10 以下の余りしか digit 変数は受け取りません。
そこで、右辺を Number 関数で通常の数値に戻します。
これにより、後で変数 digit と一緒に用いる変数を BigInt に置き換える無駄が解消されます。

また、数値を引数に取る Math.floor 関数なども BigInt には対応していません
しかし、BigInt は整数だけを扱うため、小数点以下を切り捨てる処理は不要になり、 Math.floor 関数を取り除くだけで問題は解消しました。

長整数に対応した「369の法則」のプログラム

以下が、今回作成してきた「369の法則」の計算プログラムの完成系です。
※自己責任でご利用ください。

<!DOCTYPE html>
<html>
<meta charset="utf-8">
<body bgcolor="#CCFF99">

<h1>倍加した値の桁ごとの和が 1 桁になるまで繰り返す計算</h1>

<label>倍加する初期値</label>
<input id="initialValue" type ="number" value="1" min="1"/>
<label>倍加の繰り返し回数</label>
<input id="loopCount" type ="number" value="33" min="1"/>
<input type="button" value="Calculate" onclick="SumOfDigitsOfDoubledNumber()" />
<br>
<p id="demo">ここに計算結果が出力されます。</p>

<script>
	function SumOfDigitsOfDoubledNumber()
	{
		digits = [];	// 各桁の値を出力用に保持する一時的な配列
		str = "";	// 出力する文字列の変数
		val = BigInt(document.getElementById("initialValue").value);	// 倍加する初期値
		loopCount = document.getElementById("loopCount").value;	// 倍加を繰り返す回数
		base = 10n; // 基数(10進数なので 10 )
		
		for (i = 0; i < loopCount; i++)
		{
			str += "(" + (i + 1).toString() + ") ";
			str += "<b>" + val.toString()  + " -> " + "</b>"; 	// 倍加する値の出力
			tmp = val;	// 1 桁ずつ取り出すために 10 で除算する際の一時的な変数
			while (true)
			{
				sum = 0;	// 各桁の値の和
				digit = 0;	// 各桁の値
				while(tmp > 0n)
				{
					digit = Number(tmp % base);	// 剰余で 10 で割った際の余りを求めて下位 1 桁の値を得る
					digits.push(digit);	// 出力用に桁の値を配列の最後尾に追加。
					sum += digit;	// 桁の和の変数に、今取得した桁の値を加算
					tmp = tmp / base;	// 1 つ上位の桁の値を同様に求めるために、10 で除算。(16 ならば 6 を得たので、16 / 10 で 1 にして、次ループで 1 を得る)
				}
				tmp = BigInt(sum);	// 各桁の値の和が 2 桁以上の場合は、再びその各桁の和を求めるため、桁の値を取り出すための tmp を sum に置き換えます。
				
				// 出力
				str += digits.pop().toString();
				length = digits.length;
				for (j = 1; j < length; j++)
				{
					str += " + " + digits.pop().toString();
				}
				
				if (tmp >= base)
				{
					str += " = " + sum.toString()
					str += "<b>" + " -> " + "</b>";
				}
				else
				{
					str += " = " + "<b>" + sum.toString() + "</b>" + "<br>";
					break;	// tmp ( = sum ) の各桁の和が基数(10)より小さければ1桁になったので、各桁の和を求めるループから抜けます。
				}
				
			}
			val = val * 2n;	// 数値の倍加
		}
		// HTML の p 要素のテキストを変数 str の文字列に変更。
		document.getElementById("demo").innerHTML = str;

	}
</script>

</body>
</html>

テスト

HTML ファイルを保存して、ダブルクリックなどでウェブブラウザで表示してみましょう。

3, 6 の倍数を初期値にした場合は、計算結果は 3, 6 を繰り返し、
9 の倍数を初期値にした場合は、計算結果は 9 を繰り返し、
その他の倍数を初期値にした場合は、計算結果は 1, 2, 4, 8, 7, 5 を繰り返すことが確認できます。

まとめ

今回は、天才発明家ニコラ・テスラ氏の「369の法則」の計算式を、Windows 環境ならばインストール不要で使えるプログラミング言語 JavaScript で作成したものに、初期値や繰り返す回数をページ上で指定できる HTML の Input 要素を追加して便利にしました。
JavaScript の数値の上限以上の値を扱うために長整数 BigInt の利用例も紹介しました。

作成した HTML は、本ウェブサイト内の「369 の法則の計算」ページで試すことができます。

参照サイト Thank You!

記事一覧 → Compota-Soft-Press

コメント

Ads Blocker Image Powered by Code Help Pro

お願い - Ads Blocker Detected

このサイトは広告を掲載して運営しています。

ポップアップを閉じて閲覧できますが、よろしければ

このサイト内の広告を非表示にする拡張機能をオフにしていただけませんか?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

タイトルとURLをコピーしました