シリーズ「コンピュータの計算のしくみ」 第6回
回路が「掛ける」とは?
九九は、いくつあるか
小学校で覚えた九九は、81 通りあった。 1 × 1 から 9 × 9 まで、表にすると 9 行 9 列。あれを暗記させられたのは、 掛け算をするには「1 桁どうしの答え」を全部知っていないと始まらないからだ。
では、0 と 1 しか使えない世界の九九は、何通りあるだろうか。
0 × 0、0 × 1、1 × 0、1 × 1。4 通りである。
覚えるも何もない。しかもこの 4 行の表は、このシリーズの第 1 回にもう出ている。 そのことは、あとで確かめる。
まずは、掛け算そのものをどうやるかから考えたい。
足し算を、繰り返せばいいのでは
掛け算は足し算の繰り返しだ、と習ったことがあると思う。 5 × 3 は、5 を 3 回足すことだった。
私たちはもう 4 桁の加算器を持っている。 ならば同じ数を何度も足し込めば、掛け算はできてしまう。新しい回路は 1 つも要らない。
たしかにできる。ただし、回数を考えてほしい。
4 桁どうしなら、最大でも 15 回である。まあ、待てなくもない。 けれど桁が増えると、回数は掛ける数そのものと同じだけ増えていく。 8 桁なら最大 255 回。32 桁なら——最大で約 43 億回。
これは、第 1 回で電卓の中に答えの表を入れようとしたときと同じ失敗である。 桁が増えると、素朴なやり方は現実的でなくなる。
そのときの答えは「筆算」だった。今回も、同じところに戻ってみよう。
筆算を、思い出す
十進法の掛け算の筆算は、こんな形だった。23 × 45 を書いてみる。
やっていたのは、次の 3 つである。
- 23 に、45 の一の位の 5 を掛ける。115。
- 23 に、45 の十の位の 4 を掛ける。92。これを1 桁左にずらして書く。
- 縦にそろえて、足す。1035。
途中で書いた 115 や 920 のことを、部分積という。 筆算とは、部分積を作って、ずらして並べて、足すことだった。
ここで効いてくるのが、さっきの「0 と 1 しか使えない世界の九九は 4 通り」である。
十進法では、23 に 5 を掛ける段階で、5 × 3 や 5 × 2 の九九が必要だった。 2 進法では、掛ける数の各桁は 0 か 1 しかない。 つまり部分積を作るとき、やることは 2 つに 1 つしかない。
- 掛ける数のその桁が 1 なら、掛けられる数をそのまま写す。
- 掛ける数のその桁が 0 なら、0 を並べる。
掛け算らしい計算は、どこにも出てこない。
4 通りの表は、どこにあったか
「そのまま写すか、0 を並べるか」を、1 桁ぶんの表にしてみる。 A が掛けられる数の 1 桁、B が掛ける数の 1 桁だ。
| A | B | A × B |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
第 1 回で、半加算器の繰り上がりのランプにつながっていたゲートを思い出してほしい。 AND である。入力が両方とも 1 のときだけ 1 になる、と書いた。
その表と、いまの表を見比べてほしい。同じである。
半加算器を作ったときと、話の順序は変わらない。 誰かが掛け算のために AND を発明したのではない。 AND はただ、入力が両方 1 のときだけ 1 を返すだけの部品だ。 その振る舞いが、たまたま 1 桁の掛け算と一致していた。
2 進法の九九は、AND ゲート 1 つである。
「ずらす」は、タダである
残っているのは「1 桁左にずらす」だ。 十進法でずらすのが 10 倍を意味したように、2 進法で 1 桁左にずらすのは 2 倍を意味する。
例 十進法の3を1桁左にずらすと30となる。 2進数で
0011は 3 だが、1 桁左にずらして0110と書けば 6 になる。1と1の並びは何も変わっていない。置いた場所が 1 つ左になっただけだ。
では、回路で「ずらす」にはどのゲートを使うのだろうか。
何も使わない。
第 2 回で、加算器を桁の数だけ横に並べた。 そのとき、どの線をどの桁の加算器につなぐかは、こちらで決めていた。 1 桁ずらしたければ、線を 1 つ隣の加算器につなげばいい。それだけである。
ずらすための部品は要らない。増えるゲートは 0 個だ。 2 進法の掛け算で、ずらすのはタダなのだ。
材料はそろった。
- 部分積を作る … AND
- ずらす … 配線
- 足す … 第 2 回の加算器
新しい部品は、1 つも出てこない。
押して、確かめる
4 桁 × 4 桁の掛け算を、筆算の形のまま動かせるようにした。 上の 2 段の青いマスが、掛けたい 2 つの数である。
4 桁の乗算器 シミュレータ
青いマスを押して、掛けたい 2 つの数を 2 進法で作ってみてください
0000 × 0000 = 00000000
10 進法でいう 0 × 0 = 0
いまは「一気に足す」を選んである。まずは、いくつか作ってみてほしい。
0011 × 0101(3 × 5)。部分積の 4 行のうち、1 が並ぶのは 2 行だけだ。B の 1 の位の行に 3 が、B の 4 の位の行に 3 が 2 桁ずれて(つまり 12 として)置かれている。 足して 15。答えは00001111。1011 × 0110(11 × 6)。1 が並ぶのは真ん中の 2 行。22 と 44 だ。足して 66、01000010。1011 × 0001(11 × 1)。1 が並ぶのは一番上の行だけ。ずらしていないので、1011がそのまま答えになる。
部分積の行に並んでいる数字は、A をそのまま写したものか、0 かのどちらかしかない。 どの行を見ても、A と違う模様は出てこない。位置がずれているだけである。
最後に 1111 × 1111(15 × 15)を作ってみてほしい。
答えは 11100001、10 進法で 225。8 桁がちょうど埋まる。
4 桁どうしを掛けた答えは、どんなに大きくても 8 桁に収まる。 一番大きい 15 × 15 でも 225 で、8 桁で表せる 255 を超えないからだ。 足し算では 1 桁しか増えなかったのに、掛け算では桁数が倍になる。
一気に足す
さて、部分積は 4 本ある。これをどう足すかで、回路の形が変わる。
素直なのは、加算器をたくさん並べて一度に足してしまう方法である。 部分積 0 と 1 を足し、その答えに部分積 2 を足し、さらに部分積 3 を足す。加算器は 3 段。
アレイ乗算器の中身。新しい種類の部品は 1 つも要らない。
この形をアレイ乗算器という。図のとおり、中身は AND と加算器しかない。
AND は、A の 4 桁 × B の 4 桁で 16 個。 加算器は 4 桁のままで足りる。 段ごとに一番下の桁は確定して、そのまま答えの桁に落ちていくからだ。
スイッチを入れれば、信号は左から右へ流れて答えに届く。 待つのは信号が通り抜ける時間だけで、手順を繰り返す必要はない。速い。
代わりに、部品は多い。
1 本ずつ足す
部分積を 4 本まとめて足すから、加算器が 3 つ要る。 では、加算器1つだけで掛け算はできるだろうか。
シミュレータの下で「1 本ずつ足す(シフト加算方式)」を選んでみてほしい。 「1 本足す」を押すたびに、部分積が 1 行ずつ合計に足し込まれていく。
1011 × 0110(11 × 6)で試すと、加算器の1 回目は 0 を足す(B の 1 の位が 0 だから)。この結果をいったん保存する。- 加算器の2 回目の計算では入力にいったん保存した1回目の結果(0)と 22 が入って、合計 22。これをいったん保存する。
- 加算器の3 回目の計算では入力にいったん保存した2回目の結果(22)と 44 が入って、合計 66。これをいったん保存する。
- 加算器の4 回目の計算では入力にいったん保存した3回目の結果(66)と 0 が入って、66 のまま。ここで答えが出そろう。
このやり方なら、使う加算器は1 つでいい。 1 本足すたびに、同じ加算器へ次の部分積を入れ直せばよいからだ。 AND も、1 回につき 4 個あれば足りる。
代わりに、途中の合計を覚えておく場所が要る。 別シリーズの第 1 回で作った SR ラッチのような、覚える回路の出番である。 そして何より、4 回ぶんの時間がかかる。
この方式をシフト加算方式という。 掛ける数を 1 桁ずつ見ながら、ずらして足すことを繰り返す。
速さと、部品の数
2 つの方式を並べてみる。4 桁 × 4 桁の場合だ。
| アレイ方式 | シフト加算方式 | |
|---|---|---|
| AND | 16 個 | 4 個 |
| 4 桁加算器 | 3 つ | 1 つ |
| 覚えておく場所 | 要らない | 要る |
| かかる手順 | 1 回(通り抜けるだけ) | 4 回 |
どちらが正しいという話ではない。同じ答えを、違う配分で買っているだけである。 部品を多く使って時間を買うか、時間をかけて部品を節約するか。
桁が増えると、この差は開いていく。 32 桁どうしなら、アレイ方式の AND は 32 × 32 で 1024 個になる。 シフト加算方式なら AND は 32 個のままだが、手順は 32 回かかる。
それでも、はじめに考えた「足し算を繰り返す」方法の 43 億回に比べれば、 32 回はほとんど一瞬である。
いまのコンピュータの多くは、アレイ方式に近い専用の乗算器を積んでいる。 それでも掛け算は、足し算より少しだけ時間がかかる。 プログラムを速くしたいとき、掛け算を足し算やずらしに書き換える工夫が 語られることがあるのは、このためだ。
ひとつだけ、落とし穴
ここまでの話は、すべて 0〜15 の読み方でのものだった。 では第 4 回のように、同じ 4 桁を -8〜7 と読んだまま掛けると、どうなるだろう。
1111 × 0001 を作ってみてほしい。
-8〜7 で読めば -1 × 1 で、答えは -1 のはずだ。
けれど回路が出すのは 00001111。8 桁で読めば +15 である。
ただし、下の 4 桁だけを見てほしい。1111。-8〜7 で読めば、-1 である。合っている。
1111 × 1111(-1 × -1 = 1)も同じだ。
答えは 11100001 で、8 桁で読めば -31。けれど下 4 桁は 0001、つまり 1 である。
第 4 回で、「16 違う」ことはこの回路にとって「違わない」のと同じだ、と書いた。 輪の上では同じ席に着くからだった。 掛け算でも、その性質はそのまま生き残る。 だから下 4 桁はいつでも正しく、狂うのは上の 4 桁のほうだ。
上の 4 桁まで正しくしたければ、掛ける前にひと手間が要る。 そこは今回は踏み込まないでおく。
残るは、割り算
第 2 回で、残るのは引き算・掛け算・割り算だと書いた。 引き算は足し算に化け、掛け算は AND と配線と加算器に分解された。
残っているのは、割り算である。
ここまでの 3 つには、共通点があった。 どれも「桁ごとに決まった処理をして、隣へ渡す」だけで済んでいた。 入力を入れれば、信号が通り抜けて答えが出る。回路は何も迷わない。
割り算は、少し様子が違う。 筆算を思い出してほしい。商を立てるとき、私たちは一度「引けるだろうか」と試している。 引けなければ、書いた商を消してやり直す。
回路に、試させることはできるのだろうか。
次回はそれを見てみよう。
参考文献
- 松下俊介 著. 基礎からわかる論理回路. 第2版, 森北出版, 2021.7. 978-4-627-82842-1. https://ndlsearch.ndl.go.jp/books/R100000002-I031573740
- 馬場敬信 著. 算数で読み解くコンピュータのしくみ, 技術評論社, 2022.8. 978-4-297-12960-6. https://ndlsearch.ndl.go.jp/books/R100000002-I032268791