Align significands【NandGame編】
はじめに
いつもブログをご覧いただきありがとうございます。
コーストFIRE中のIPUSIRONです😀
Align significandsレベル
Align significandsレベルのゴールは、2つの数が同じ指数を共有するように、指数と仮数を調整する回路を実装することです。
ここでいう指数の共有とは、入力された指数のうちもっとも大きい指数に合わせることです。大きい指数を持つ数の仮数はそのまま出力されますが、小さい指数を持つ数の仮数は指数の変化に合わせて調整されます。
指数が大きくなるということは、同一の数を保つためには仮数を小さくすればよいわけです。指数は2のべきであるため、仮数を小さくするには右シフトすればよいことになります。
入力 | A | ・exp:指数 ・sf:仮数 |
B | ・exp:指数 ・sf:仮数 | |
出力 | exp | 指数のうち、最大のもの。 |
asf | 入力Aの仮数。 ※Aの指数の方が小さい場合は、仮数を調整する。 | |
bsf | 入力Bの仮数。 ※Bの指数の方が小さい場合は、仮数を調整する。 |

Align significandsレベルを解く
1:最大の指数を出力する
指数のところだけに注目するとmaxコンポーネントで十分です(左図参照)。
しかしんがら、ステップ2での回路を考えると分解された回路の方が都合がよいため、maxコンポーネントの右にある下矢印アイコンから「Replace with parts」を選びます。すると、右図のようになります。
※いきなり右図のようにコンポーネントを配置しても構いません。


2:調整後の仮数を出力する
右シフトするためにshr nコンポーネントが用意されています。

※シフトする桁は入力のnピンで指定します。桁をずらすということは最大で16桁しかないので、nは4ビットになっています。もし、4ビットのnピンに、16ビットのピンからワイヤリングしたとしても、その16ビットの下位4ビットだけを使います。
問題はどれだけ右シフトすればよいのかです。
ステップ1の回路には指数の差分を求める箇所があります。この差分の絶対値こそが右シフトすべき回数になります。
ここで絶対値を取っているのは、差分が負の数になる可能性があるからです。負の数であれば、マイナス記号を取り除かなければなりません。回路的には負の数の場合は、0から再度引けばよいだけです。
以上を踏まえて回路を実装すると次のようになります。
※AとBのどちらに0から再度引く回路をつなげるのか迷うかもしれません。もし間違えたとしても、ステップ3のテストにより、ミスに気づくのが感覚で実装してしまってもよいでしょう。

3:テストする
2パターンを手動でテストしてみましょう。
※アクティブになっている線(青色の線)、ピンの出ている数値も注目しながらトレースしてください。
[1]Aのexp>Bのexpの場合をテストする
次に示す具体的な値を入力として与えます。
- Aのexp=12h、Bのexp=10h
- Aのsf=Bのsf=400h

出力のexpが12hになっているので、expの回路は問題なさそうです。
出力のasfとbsfに注目します。
Aのexpの方が大きかったので、asfはAのsfがそのまま出力されています。
一方、Bのsfは400h(=0000 0100 0000 0000b)でしたが、bsfは0100h(=0000 0001 0000 0000b)になっています。つまり、2ビット分だけ右シフトしたことになります。
[2]Aのexp<Bのexpの場合をテストする
次に示す具体的な値を入力として与えます。
- Aのexp=10h、Bのexp=12h
- [1]のときと逆。
- Aのsf=Bのsf=400h
- [1]のときと同じ。

出力のexpが12hになっているので、expの回路は問題なさそうです。
Bのexpの方が大きかったので、bsfはBのsfがそのまま出力されています。
一方、Aのsfは400h(=0000 0100 0000 0000b)でしたが、asfは0100h(=0000 0001 0000 0000b)になっています。つまり、2ビット分だけ右シフトしたことになります。
以上で手動のテストを終えます。
あとは自動テストに任せます。テストにパスするとクリアになります。
