シリーズ「コンピュータの計算のしくみ」 第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 を書いてみる。

23
×45
115
92
1035

やっていたのは、次の 3 つである。

  1. 23 に、45 の一の位の 5 を掛ける。115。
  2. 23 に、45 の十の位の 4 を掛ける。92。これを1 桁左にずらして書く。
  3. 縦にそろえて、足す。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 桁だ。

ABA × B
000
010
100
111

第 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 になる。 11 の並びは何も変わっていない。置いた場所が 1 つ左になっただけだ。

では、回路で「ずらす」にはどのゲートを使うのだろうか。

何も使わない。

第 2 回で、加算器を桁の数だけ横に並べた。 そのとき、どの線をどの桁の加算器につなぐかは、こちらで決めていた。 1 桁ずらしたければ、線を 1 つ隣の加算器につなげばいい。それだけである。

ずらすための部品は要らない。増えるゲートは 0 個だ。 2 進法の掛け算で、ずらすのはタダなのだ。

材料はそろった。

  • 部分積を作る … AND
  • ずらす … 配線
  • 足す … 第 2 回の加算器

新しい部品は、1 つも出てこない。

押して、確かめる

4 桁 × 4 桁の掛け算を、筆算の形のまま動かせるようにした。 上の 2 段の青いマスが、掛けたい 2 つの数である。

4 桁の乗算器 シミュレータ

青いマスを押して、掛けたい 2 つの数を 2 進法で作ってみてください

A
B×
B の 1 の位00000000
B の 2 の位00000000
B の 4 の位00000000
B の 8 の位00000000
答え00000000

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 段。

部分積をつくる(AND 16 個)足す(4 桁加算器 3 段)A・BAND × 4部分積 0(ずらさない)AND × 4部分積 1(1 桁 左へ)AND × 4部分積 2(2 桁 左へ)AND × 4部分積 3(3 桁 左へ)4 桁加算器4 桁加算器4 桁加算器第 2 回で作った加算器を、3 段答え(8 桁)

アレイ乗算器の中身。新しい種類の部品は 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 桁の場合だ。

アレイ方式シフト加算方式
AND16 個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 つには、共通点があった。 どれも「桁ごとに決まった処理をして、隣へ渡す」だけで済んでいた。 入力を入れれば、信号が通り抜けて答えが出る。回路は何も迷わない。

割り算は、少し様子が違う。 筆算を思い出してほしい。商を立てるとき、私たちは一度「引けるだろうか」と試している。 引けなければ、書いた商を消してやり直す。

回路に、試させることはできるのだろうか。

次回はそれを見てみよう。

参考文献