Perl で 2進数 実数 変換Perl の基礎を学習する上で、2進数から実数に変換するプログラムを扱うことにしました。 ハードウェアを設計していて、算術演算回路の符号付きで小数点以下の数値を扱う場合、デジタルなので当然 2進数で演算するのですが、2進数から整数の変換をしてくれる電卓はあるものの、2進数から実数に変換してくれる電卓がなく、いちいち手計算で検証するのは大変です。 そこで、 Perl でプログラムを書いてみました。あとで解説しますが、まずは全体を載せておきます。 なお、このプログラムは以下のように実行します。
第1引数:符号 すると、結果がこのように表示されます。
それでは1つずつ解説していきます。 実行属性の付け方
1行目のこれ↑は 実行コマンドの perl がインストールされている path を指定しています。実行コマンドの perl がどの path にあるかは、以下のように which コマンドで確認します。
#!/usr/bin/perl のように1行目に path を指定しておき、perl の script ファイル (ここでは bin2real.pl) のファイル属性に実行属性を付けておけば、script ファイル名を入力するだけで perl プログラムが実行できるようになります。
これで bin2real.pl という script は実行属性が付きましたので、以下のように実行させることができます。
サブルーチンいきなりですが、3〜9行目にはサブルーチンが定義されています。これは引数も戻り値も持たない簡単なサブルーチンです。
このサブルーチンの目的は、外部引数が必要な bin2real.pl を実行させるとき、誤った引数が与えられたときに表示する syntax error メッセージであり、引数の与え方を忘れてしまったときに、あえて表示させる help メッセージの代わりとなっています。 サブルーチンの書き方として、引数の受け取りの仕方や戻り値の書き方の説明は、長くなるので別のところで説明したいと思います。 外部引数の受け取り11〜17行目に書かれているのは、bin2real.pl に必要な引数の代入を行っています。また、引数として2つが必要なため、2つ以外の引数が与えられた場合はプログラムが終了する仕掛けになっています。
1つ目の引数は、符号です。 なお、2つ目の引数は、必ず小数点付きの2進数が入力されなければなりません。 整数部 と 小数部 に分離19行目に書かれているのは、外部引数から与えられた小数点付きの2進数 $input_bin を整数部と小数部に分ける文です。
split は perl が持っている標準関数です。 整数部の10進数変換21〜31行目で整数部の2進数から10進数への変換を行っています。
連続した0と1のパターンでは扱うのが大変ですので、まずは、1文字ずつに変換します。 そうして、先ほどもあった split 関数を使って 1文字ずつに変換します。 配列化した後、その要素数 $#tmp 分の 10進数化 演算を for文 を使って行います。 また、33行目で 外部から与えられた 小数点付き2進数 が負の数である場合に備えて、その 2進数の桁数における最大値を $max として保存しておきます。 小数部の10進数変換35〜45行目で小数部の2進数から10進数への変換を行っています。
演算の仕方は、整数部と同様です。ただ 2の-1乗,-2乗,... と for文 で演算しています。 整数部と小数部の合算47〜53行目で整数部と小数部を合算して、外部引数で与えられた 符号によって最終結果を出しています。
外部引数1 $input_sign が - であった場合、外部引数2 で与えられた 2進数は 2の補数 であったことになるので、外部引数2 のbit幅で表すことの出来る最大値 $max から引き算します。 理由を以下に説明します。 コンピューターの中では、0 と 1 の値しかありませんから、負 (-) を表現するために一般的に使われているルールがあります。それが 2の補数を 負の数として扱うもので、分かりやすく説明するために整数を使って8bitで表現すると以下の数列のようになります。
2の補数というのは、もとの2進数を反転させて+1した数値のことです。 3の2の補数は、3:00000011 を反転:11111100 して +1 した 11111101 です。
桁上がりで8bitの外に出てしまった1を無視すると、2:00000010 が得られました。 さて、3の2の補数:11111101は、そのまま10進数の正の整数で表すと 253 です。これは、2の8乗である 256 を -3 した値です。2の補数がそういうものですから当然です。 最後に演算結果を表示してプログラムは終了です。
|
自己紹介 50才になる半導体エンジニアです。大学で電子電気工学を学び、1990年にその分野のまま就職。ASICやマイコンの設計を長く続けてきましたが20年も同じ分野にいると業態も衰退したり変化するもので退職し、今は外資のIT系会社に再就職して設計請負業をやっております。 お問い合わせは nakata.xianzhi@outlook.com Linux と 小ネタ デジタル回路設計
海外駐在後記
|