base.py プログラム技術ドキュメント

プログラムの動作

base.py は、指定された数値をある基数から別の基数に変換するためのPythonスクリプトです。このプログラムは、コマンドライン引数として変換対象の数値、変換元の基数、そして変換先の基数の3つを受け取ります。

主な機能は以下の通りです。

  1. コマンドライン引数の解析: 変換対象の数値(文字列)、変換元の基数(整数)、変換先の基数(整数)をコマンドラインから読み込みます。

  2. 基数チェック: 変換元および変換先の基数が、対応する最大基数(36)を超えていないか、また、入力された数値の各桁が変換元の基数と互換性があるかを確認します。

  3. 基数変換プロセス:

    • まず、与えられた数値を変換元の基数から基数10(10進数)に変換します。

    • 次に、基数10に変換された数値を、指定された変換先の基数に変換します。

  4. 対応文字: 数値の各桁は '0' から '9'、そして 'A' から 'Z' までの文字で表現され、最大で基数36までの変換に対応しています。

  5. 途中経過の表示: 変換の各段階(基数10への変換、基数10からの変換)において、計算の途中経過と最終結果を標準出力に詳細に表示します。

このスクリプトは、数値の基数変換という基本的な計算を、教育的な目的も兼ねて、そのプロセスを可視化しながら実行することを目指しています。

原理

base.py プログラムは、数値をある基数から別の基数へ変換するために、中間段階として常に基数10(10進数)を使用します。変換プロセスは以下の2つの主要なステップで構成されます。

1. 任意の基数から基数10への変換

基数 \(b_{source}\) で表された数値 \(N_{source}\) を基数10の数値 \(N_{10}\) に変換します。基数 \(b_{source}\)\(d_k d_{k-1} \dots d_1 d_0\) と表される数値は、以下のように基数10に変換されます。

\[N_{10} = d_k \cdot b_{source}^k + d_{k-1} \cdot b_{source}^{k-1} + \dots + d_1 \cdot b_{source}^1 + d_0 \cdot b_{source}^0\]

ここで、\(d_i\) は数値の \(i\) 番目の桁(右から0番目開始)が基数10で表す値です。例えば、16進数の 'A' は基数10では '10' に相当します。プログラムでは value_base 関数がこの \(d_i\) の値を特定し、for ループ内で上記数式に従って v10 に累積加算していきます。

2. 基数10から任意の基数への変換

基数10の数値 \(N_{10}\) を基数 \(b_{target}\) の数値に変換します。この変換は、繰り返し除算と剰余の原理に基づいています。

  1. \(N_{10}\)\(b_{target}\) で割り、商 \(Q_0\) と剰余 \(R_0\) を求めます。\(R_0\) が変換後の数値の最下位桁となります。 \(N_{10} = Q_0 \cdot b_{target} + R_0\)

  2. 次に、商 \(Q_0\)\(b_{target}\) で割り、商 \(Q_1\) と剰余 \(R_1\) を求めます。\(R_1\) が次の桁となります。 \(Q_0 = Q_1 \cdot b_{target} + R_1\)

  3. このプロセスを商が0になるまで繰り返します。得られた剰余 \(R_k, R_{k-1}, \dots, R_1, R_0\) を逆順に並べたものが、基数 \(b_{target}\) での表現となります。

プログラムでは、while ループ内でこの繰り返し除算を実行し、residue (剰余) を base_chars 文字列を用いて対応する文字に変換し、結果文字列 starget の先頭に追加することで、正しい順序の変換結果を構築します。

必要な非標準ライブラリとインストール方法

base.py はPythonの標準ライブラリのみを使用しており、sys モジュール以外に特別な非標準ライブラリは必要としません。 そのため、pip コマンドなどを使った追加のライブラリインストールは不要です。Pythonがインストールされていれば、すぐに実行可能です。

必要な入力ファイル

base.py プログラムは、入力ファイルを必要としません。すべての必要な情報はコマンドライン引数として直接与えられます。

期待されるコマンドライン引数の形式と内容を以下に示します。

  1. val (文字列): 変換対象となる数値。

    • 例: '10', 'FF', '17'

    • この数値は、base_source で指定された基数での表現でなければなりません。使用できる文字は '0'-'9' および 'A'-'Z' です。

  2. base_source (整数): 変換元の基数。

    • 例: 10 (10進数), 2 (2進数), 16 (16進数)

    • 2 から 36 までの整数である必要があります。

  3. base_target (整数): 変換先の基数。

    • 例: 2, 10, 16

    • 2 から 36 までの整数である必要があります。

これらの引数が正しく指定されない場合、プログラムはエラーメッセージまたは使用方法(Usage)を表示して終了します。

生成される出力ファイル

base.py プログラムは、いかなる出力ファイルも生成しません。 すべての変換結果、途中経過、およびエラーメッセージは、標準出力(コンソール)に表示されます。

出力される主な内容:

  • プログラムの実行開始時と終了時に空行。

  • 基数 base_source から基数10への変換過程の詳細(各桁の値、寄与、途中合計)。

  • 基数10から基数 base_target への変換過程の詳細(繰り返し除算の商、剰余、途中結果)。

  • 最終的な変換結果。

コマンドラインでの使用例 (Usage)

base.py をコマンドラインから実行する際の基本的な構文は以下の通りです。

python base.py val base_source base_target

各引数の意味は以下の通りです。

  • val: 変換する数値。文字列として指定します。例: 10, FF, 1010

  • base_source: 変換元の基数。整数で指定します。2から36の範囲。例: 10, 16, 2

  • base_target: 変換先の基数。整数で指定します。2から36の範囲。例: 2, 10, 16

コマンドラインでの具体的な使用例

例1: 10進数「10」を2進数に変換

10進数の 10 を2進数に変換します。

python base.py 10 10 2

実行結果の説明: まず、10 (基数10) が基数10に変換されます(このステップでは数値自体は変化しません)。 次に、基数10の 10 が繰り返し2で割られ、剰余が計算されます。 その結果、10 (基数10) は 1010 (基数2) に変換されます。

Convert 10 in base 10 to base 10
0-th digit = 0_10:   + 0*10^0 => +          0_10 =>          0_10
1-th digit = 1_10:   + 1*10^1 => +         10_10 =>         10_10

Convert 10 in base 10 to base 2
        10 =          5 *         2 +  0:  base_2 => 0
         5 =          2 *         2 +  1:  base_2 => 10
         2 =          1 *         2 +  0:  base_2 => 010
         1 =          0 *         2 +  1:  base_2 => 1010

例2: 16進数「F」を10進数に変換

16進数の F を10進数に変換します。

python base.py F 16 10

実行結果の説明: まず、F (基数16) が基数10に変換されます。F は基数10で 15 に相当します。 次に、基数10の 15 が基数10に変換されます(数値はそのままです)。

Convert F in base 16 to base 10
0-th digit = 15_16:   + 15*16^0 => +         15_10 =>         15_10

Convert 15 in base 10 to base 10
        15 =          1 *        10 +  5:  base_10 => 5
         1 =          0 *        10 +  1:  base_10 => 15

例3: 8進数「17」を16進数に変換

8進数の 17 を16進数に変換します。

python base.py 17 8 16

実行結果の説明: まず、17 (基数8) が基数10に変換されます。 \(7 \cdot 8^0 = 7\) \(1 \cdot 8^1 = 8\) 合計 \(7 + 8 = 15\) となります。 次に、基数10の 15 が基数16に変換されます。15 は基数16で F に相当します。

Convert 17 in base 8 to base 10
0-th digit = 7_8:   + 7*8^0 => +          7_10 =>          7_10
1-th digit = 1_8:   + 1*8^1 => +          8_10 =>         15_10

Convert 15 in base 10 to base 16
        15 =          0 *        16 + 15:  base_16 => F