あなたが提起する問題を使用して、デジタル処理の問題を解決するためにデジタル回路がどのように設計されているか、CPUがどのように加算と乗算を実装するかを考えてみましょう。
まず、直接的な質問を邪魔にならないようにしましょう。プログラミング言語はどのように乗算と加算を効率的に評価するのでしょうか。答えは簡単で、それらをコンパイルして乗算命令と加算命令にコンパイルします。たとえば、次のコード:
a = 1 + 1;
b = a * 20;
以下のように単純にコンパイルされます:
ADD 1 1 a
MUL a 20 b
(上記のアセンブリは、単純化のために、存在しない架空のCPU用です)。
この時点で、上記の答えは単に問題をシフトし、ハードウェアマジックによってそれを解決することがわかります。次の質問は、明らかに、そのハードウェアの魔法はどのように機能するのでしょうか?
最初に、より単純な問題である加算を見てみましょう。
まず、おなじみの問題を行い、通常の10進数を追加します。
17
+28
最初のステップは7と8を追加することです。しかし、これは1桁以上の15になります。だから私たちは1を運びます:
(1)
17
+28
= 5
次に、1、1、2を一緒に追加します。
17
+28
=45
したがって、これから次のルールを取得します。
加算の結果が複数桁の場合、最下位桁を保持し、最上位桁を繰り上げます
列に数字が繰り越されている場合は、追加する数字とともに追加します
ここで、上記のルールを基数2(ブール代数)で解釈します。
したがって、ブール代数では、0と1を一緒に追加する=1。0と0 = 0を追加します。1と1 = 10を追加します。
これから、真理値表を作成できます。
a b | sum carry
-------------------
0 0 | 0 0
0 1 | 1 0
1 0 | 1 0
1 1 | 0 1
これから、2つの回路/ブール方程式を構築できます。1つは合計の出力用で、もう1つはキャリーの出力用です。最も単純な方法は、すべての入力を単純にリストすることです。どんなに大きくて複雑でも、この形式で言い換えることができる真理値表:
(AND inputs in first row) OR (AND of inputs in second row) OR ...
これは基本的に製品の合計フォームです。結果が1になり、0を無視する出力のみを確認します。
sum = (NOT a AND b) OR (a AND NOT b)
AND ORおよびNOTをプログラミング言語のシンボルに置き換えて、読みやすくします。
sum = (!a & b) | (a & !b)
基本的に、テーブルを次のように変換しました。
a b | sum equation
-------------------
0 0 | 0
0 1 | 1 (!a & b)
1 0 | 1 (a & !b)
1 1 | 0
これは、回路として直接実装できます。
_____
a ------------| |
\ | AND |-. ____
\ ,-NOT--|_____| \ | |
\/ `--| OR |----- sum
/\ _____ ,--|____|
/ `-NOT--| | /
/ | AND |-`
b ------------|_____|
観察者は、この時点で、上記のロジックが実際に単一のゲートとして実装できることに気付くでしょう-真理値表に必要な動作を便利に行うXORゲート:
_____
a ------------| |
| XOR |---- sum
b ------------|_____|
ただし、ハードウェアがXORゲートを提供しない場合、上記の手順は、AND、OR、およびNOTゲートの観点からそれを定義および実装する方法です。
論理ゲートを実際のハードウェアに変換する方法は、使用しているハードウェアによって異なります。メカニズムが何らかのスイッチング動作を提供する限り、さまざまな物理メカニズムを使用して実装できます。論理ゲートは、水や空気の噴出(流体)からトランジスタ(電子工学)、落下する大理石まで、あらゆるもので実装されています。それはそれ自体が大きなトピックなので、私はそれを大雑把に言い、論理ゲートを物理デバイスとして実装することが可能であると言うつもりです。
キャリー信号についても同じことを行います。キャリー信号が真になる条件は1つしかないため、式は単純です。
carry = a & b
キャリーは簡単です:
_____
a ------------| |
| AND |---- carry
b ------------|_____|
それらを組み合わせると、半加算器と呼ばれるものが得られます。
_____
a ------;-----| |
| | XOR |---- sum
b --;---|-----|_____|
| | _____
| '-----| |
| | AND |---- carry
'---------|_____|
ところで、上記の回路の方程式は次のようになります。
sum = a ^ b
carry = a & b
半加算器に何かがありません。結果が繰り越しよりも1桁以上の場合、最初のルールを実装しましたが、2番目のルールは実装していません-キャリーが存在する場合、それを数字と加算します。
したがって、1桁以上の数値を加算できる加算回路である全加算器を実装するには、真理値表を定義する必要があります。
a b c | sum carry
---------------------
0 0 0 | 0 0
0 0 1 | 1 0
0 1 0 | 1 0
0 1 1 | 0 1
1 0 0 | 1 0
1 0 1 | 0 1
1 1 0 | 0 1
1 1 1 | 1 1
合計の式は次のとおりです。
sum = (!a & !b & c) | (!a & b & !c) | (a & !b & !c) | (a & b & c)
上記のように、同じプロセスを経て方程式を因数分解して単純化し、回路などとして解釈することもできますが、この答えは長すぎると思います。
ここまでで、デジタルロジックがどのように設計されているかがわかるはずです。Karnaughマップ(真理値表を単純化するために使用)やespressoなどの論理コンパイラー(ブール式を手動で因数分解する必要がない)など、私が言及していない他のトリックもありますが、基本は基本的に上記の概要:
1ビット(桁)レベルで作業できるようになるまで、問題を分解します。
真理値表を使用して、必要な出力を定義します。
テーブルをブール方程式に変換し、方程式を単純化します。
方程式を論理ゲートとして解釈します。
論理ゲートを実装して、論理回路を実際のハードウェア回路に変換します。
これが、根本的な(または、低レベルの)問題が実際に解決される方法です-たくさんの真理値表。実際の創造的な作業は、MP3デコードなどの複雑なタスクをビットレベルに分解して、真理値表で作業できるようにすることです。
申し訳ありませんが、乗算を実装する方法を説明する時間がありません。乗算の動作時間のルールを考え、それをバイナリで解釈し、それを真理値表に分解してみることで、それに挑戦することができます。または、Wikipediaを読むことができます:http : //en.wikipedia.org/wiki/Binary_multiplier