- ベストアンサー
C言語の四則演算について
これからプログラミングを勉強する為、C言語の入門書を買ってきたのですが、その中で、コンピューターでは四則演算を1の補数と2の補数を用いてすべて足し算で行うと書いてありました。詳しく解説してないのでどういうことなのか良くわかりません。掛け算や割り算などを足し算でできるのでしょうか。 この辺のところに詳しい方、ぜひ、ご解説をお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
他の方と同じく、C言語の勉強として必要性が全く感じられない知識です。 C言語は、メモリやスタック等のCPUの動作をある程度意識してプログラムを組む必要がある言語ですが、だからといってそんなことまで知っている必要は全くありません。 今時、小さなCPUでも四則演算の命令はありますから、この知識が必要なのは旧式のCPUのプログラマか、CPUの設計者くらいなんじゃないでしょうか? もう、ほとんど”トリビア”に近いです。 さて、引き算を補数と足し算で行うやり方ですが、概念がわかる程度に解説させていただきます。 この補数による引き算は10進数でもできるので、10進数で説明します。 (#2さんと同じ話をしています) (1)2進数の世界での1の補数と2の補数は、10進数の世界での9の補数と10の補数にあたります。 (2)補数を考えるときは桁数を限定しないといけません。 ここでは桁数を4桁にします。 つまり a.0000~9999までしか数を表現できない b.足し算をして4桁を超えた部分は無視 ← これ大事 (3)ある数Xの9の補数は、引き算をせずとも求まります。 対応表を使います。 0123456789 ↓↓↓↓↓↓↓ 9876543210 例えば45の4桁の9の補数は、 45=0045→9954 になります。 (4)同じく10の補数は9の補数に1を足すと得られます。 例えば45の4桁の10の補数は、 9954+1=9955 です。 さて、9と10の補数についてわかっていただいたところで早速引き算をしてみましょう。 123-45の計算をしてみます。 1)足す数と引く数を4桁で表す。 0123 - 0045 2)引く数の10の補数を求める 0123 9955 3)足し算する 0123 + 9955 ----------------------- 10078 4)桁を超えた部分を削る 0078 計算終了 と、こんな具合です。 2進数でも同じ要領です。 9、10の補数が1、2の補数になっただけで、桁数の限定、はみ出た桁の無視は同じです。 ところで、上のやり方で9の補数を求めるのに表を使っていましたが、2進数で1の補数を求めるときはその必要はありません。 0/1のビットを反転するだけでできるからです。 ですから2進数の引き算では、加算とビット演算だけで実現できてしまうのです。(加算だって論理演算の固まりですけどね) ....今、この知識が必要な場面を一つ思いつきました。 整数型においての負数表現です。 詳細はここでは述べませんが、その場合でも「なぜ負の数を2の補数で表現するのか?」の理由として紹介する方が適切かも知れません。 ですから根こそぎ必要ない知識ではないですが、CPUが割り算をどう計算しているのかとは、あまり関係のない話ですね。
その他の回答 (4)
- tadys
- ベストアンサー率40% (856/2135)
No.3さんと同じ意見です。解説が無いのであれば取り上げる必要も無いのです。 高機能のCPUでは乗算回路や除算回路を採用している場合がありますがローコストのCPUでは加減算しかできないものも多いのです。 こういうCPUでは乗除算を加減算で行う必要があります。 掛け算は足し算の繰り返しですので足し算で出来ます。 例えば2x5=2+2+2+2+2です。 割り算は何回引き算が出来るかで計算できます。 例えば7÷2は 1回目 7-2 = 5 2回目 5-2 = 3 3回目 3-2 = 1 これ以上引けないので答えは3で余りが1 ただし、これらの方法では効率が悪いのでシフトと加減算を利用する方法を利用します。 これらの計算法は原理的には筆算で行う方法と同じです。ただし表現は2進数が対象になります。 2x5の場合、2進数では10x101です。 10 x 101 ____ 10 00 + 10 ____ 1010 =10(10進数) 割り算は多少複雑です。割り算の場合、最初に割る数と割られる数の最上位の桁が合うように割る数をシフトしておきます。 例えば10÷3の場合は 1回目1010 -1100 (10進の3。桁合わせの為に0を挿入しています) _________ 余り 1010 引けない。 商は0 2回目1010 -0110 _________ 余り 0100 引けた。 商は01 3回目0100 -0011 _________ 余り 0001 引けた。 商は011 答えは 商3、余り1です。 実際には最初にシフトした分の補正などが必要になります。 参考URLにはマイクロチップのCPUのMATHルーチンを示しておきます。
お礼
tadysさん、凄いです。 プログラマー入門者の私では、まだ理解不能です。 ただ漠然とそうなのか~という感じです。 このご回答は保存して、勉強が進んでからまた熟読させていただきます。 ありがとうございました。
- a-saitoh
- ベストアンサー率30% (524/1722)
その本は捨ててください。だめな本だと思われます。 いまどきのコンピュータで整数表現に1の補数を使っているCPUはありません。2の補数ばかりです。 「すべて足し算でおこなう」というのも、大昔のメインフレームでの話です。1970年代にはすでに引き算命令は普通にありましたし、掛け算命令を持つCPUも現れていました。 現代では、加減乗除命令を持つCPUは普通です。たとえばWindowsが動くようなぱCPUでは、整数と浮動小数点の加減乗除がCPUで行えます。 補数を求めることと加算を行うことさえできれば、加減乗除がすべて行えるのは本当です。実際は、左右シフトとかも欲しいですが。
お礼
a-saitohさん、このテキストは古本屋にでも売ることにします。 もっと勉強が進んでからでないと、難しそうですね。 めげずに頑張ってやって行きます。 ありがとうございました。
- Willyt
- ベストアンサー率25% (2858/11131)
コンピュ-タにはアダーと呼ばれる加算機があるだけなのです。それは引き算は引く数の補数をとれば引き算が足し算になってしまうのです10進3桁の場合で 1-1の計算をやって見ます。 1の補数は999です。すると 1-1 は1+999=10000となりますが、4桁目がないので答えは0になりますね(^_-) 2-1=2+999=1(4桁目をねぐる) になりますね 二進数の場合、補数は1とゼロを反転させるだけで簡単に作ることができますから引き算の回路は要らないということになります。 更に掛け算は足し算の連続、割算は引き算の連続ですから、アダーだけで計算ができてしまうことになります。勿論乗除算は専用の回路を作りますがそれを構成するのはやはり加算回路だけです。
お礼
Willytさん、ご回答ありがとうございます。 初心者がすべき質問ではない内容でした。 ちょっとまだ理解できないので、勉強の過程でまたお尋ねするかもしれません。その際には宜しくお願いします。
- PrintScree
- ベストアンサー率25% (538/2091)
まず、コンピュータで使用しているCPUは基本的には足し算と引き算しかできません。 かけ算、割り算をどういうロジックで計算しているか知りたければアセンブラを勉強してください。 ただ、高性能CPUではかけ算、割り算の命令セットがあるので、プログラマがそのロジックを考える必要はありません。
お礼
PrintScreeさん、ありがとうございました。 この質問は、もっと勉強が進んでからでした。 お手数をお掛けしました。
お礼
bnosuke-xさん、ありがとうございます。 素人では、かなり難解でちょっと理解不能です。申し訳ありません。 でも、勉強が進めば理解出来てくるのでしょうか。 頑張ります。 大変お手数お掛けしまして、心より御礼申し上げます。