• 締切済み

C言語で2進数の減算

プログラミング初心者なのですが 「2つの2進数の差を求めるプログラム」が作成できません。 全加算器とかを使うらしいのですがわからなくて困っています。 どなたか助けてくれるとありがたいです

みんなの回答

  • siffon9
  • ベストアンサー率64% (136/211)
回答No.6

プログラムで加算器を作るって面白い発想ですね。 > 「2つの2進数の差を求めるプログラム」が作成できません。 a - b というのは a + (bの2の補数) になります。 (bの2の補数)は、(bの1の補数)+ 1 です。 (bの1の補数)は、bの各ビットの1と0を反転したものになります。 ですから、最初に(bの1の補数)を計算して、次にそこから(bの2の補数)を計算します。 その結果とaを加算すればaとbの差を求めることができます。 (bの1の補数)を求めるために、まずnot関数  int not(int M) が必要になります。動作は引数で1が与えられたら0を返し、0が与えられたら1を返します。 これを使用して(bの1の補数)であるpを求めます。  p0 = not(b0)  略  p7 = not(b7) 次にpを使って(bの2の補数)であるqを求めます。  q = p + 1 ですから既にある全加算器full_adderを使用して求めることができます。  full_adder(p0, 1, 0, &q0, &c0);  full_adder(p1, 0, c0, &q1, &c1);  略  full_adder(p7, 0, c6, &q7, &c7); (bの2の補数)であるqが求められたわけですから最初に書いたとおりaにqを加算すればaとbの差が求まります。  a - b = a + q これも全加算器full_adderを使用して求めることができますよね。

noname#133770
質問者

お礼

丁寧な回答ありがとうございます。 なんか出来そうな気がするので組んでみます。 本当にありがとうございます

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

がんばれ.

参考URL:
http://focus.tij.co.jp/jp/lit/ds/symlink/sn74as181a.pdf
すると、全ての回答が全文表示されます。
  • Willyt
  • ベストアンサー率25% (2858/11131)
回答No.4

Cを使おうと、どんなコンパイラを使おうと、それは翻訳されて二進数の演算になってしまっていますよ。ですから二進数の演算のプログラムというのは演習でやるのはともかく、無意味です。 そこで演習のためにやるのであれば次のように行ないます。 二つの数を二進数、つjまり1とゼロだけで表わします。これはできますよね。そして引かれる数はそのままにしておいて、引く数の補数を求めます。これは1とゼロを交換した後、1を加えます。たとえば2は10ですからこれの補数は01+1= 10 となりますね。その補数を引かれる数に加えればいいのです。そうすると加算だけのプログラムを組めばいいことになります。 加算のアルゴリズムはお分かりでしょうが、1+1 は10に桁上がりします。なお、引き算のときに最上桁が桁上がりしたときはその数は捨てますよ。

noname#133770
質問者

補足

理屈はわかるのですが前述したソースリストに、どの場所にどのようなプログラムを記述すればいいかいまいちわかりません・・・

すると、全ての回答が全文表示されます。
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

全加算器自体はわかりますか? わからなければ、まずは半加算器を作り、それを2個組み合わせるようにしてください。 全加算器ができれば、何ビットの計算か知りませんが、それを組み合わせれば加算が可能になります。 加算までできれば、ほとんどできたようなもので、一方の入力をビット反転させ、末尾桁への桁上がりに1を入力するようにすれば(加算の場合は0を入力します)減算になります。

noname#133770
質問者

補足

整数の和が255までの2進数の可算のプログラムですが #include <stdio.h> //論理和 int or(int M, int N) { if ((M == 1)||(N == 1)) return 1; else return 0; } //論理積 int and(int M, int N) { if((M == 1)&&(N == 1)) return 1; else return 0; } //排他的論理和 int xor(int M, int N) { if(M != N) return 1; else return 0; } //全加算器の実装 void full_adder(int M, int N, int cin, int *s, int *cout) { *s = xor(xor(M,N),cin); /*和を求める論理式*/ *cout = or(and(M,N),and(xor(M,N),cin)); /*上位への桁上げを求める論理式*/ } //入力された2進数を10進数に変換 int bin_to_int(int a7, int a6, int a5, int a4, int a3, int a2, int a1, int a0) { int M; M = a7*128 + a6*64 + a5*32 + a4*16 + a3*8 + a2*4 + a1*2+ a0; return M; } //同上 int bim_to_int(int b7, int b6, int b5, int b4, int b3, int b2, int b1, int b0) { int N; N = b7*128 + b6*64 + b5*32 + b4*16 + b3*8 + b2*4 + b1*2+ b0; return N; } int main(void) { int M, N, MN; int a7, a6, a5, a4, a3, a2, a1, a0; int b7, b6, b5, b4, b3, b2, b1, b0; int s7, s6, s5, s4, s3, s2, s1, s0; int c7, c6, c5, c4, c3, c2, c1, c0; //2進数の入力 printf("8桁以下の2進数を入力してください(1つめ)\n"); scanf("%d %d %d %d %d %d %d %d", &a7, &a6, &a5, &a4, &a3, &a2, &a1, &a0); printf("8桁以下の2進数を入力してください(2つめ)\n"); scanf("%d %d %d %d %d %d %d %d", &b7, &b6, &b5, &b4, &b3, &b2, &b1, &b0); M = bin_to_int(a7, a6, a5, a4, a3, a2, a1, a0); N = bim_to_int(b7, b6, b5, b4, b3, b2, b1, b0); full_adder(a0, b0, 0, &s0, &c0); full_adder(a1, b1, c0, &s1, &c1); full_adder(a2, b2, c1, &s2, &c2); full_adder(a3, b3, c2, &s3, &c3); full_adder(a4, b4, c3, &s4, &c4); full_adder(a5, b5, c4, &s5, &c5); full_adder(a6, b6, c5, &s6, &c6); full_adder(a7, b7, c6, &s7, &c7); MN = M + N; printf("結果は\n"); printf("%d %d %d %d %d %d %d %d (%d) + %d %d %d %d %d %d %d %d (%d) = ", a7, a6, a5, a4, a3, a2, a1, a0, M, b7, b6, b5, b4, b3, b2, b1, b0, N); printf("%d %d %d %d %d %d %d %d (%d)\n", s7, s6, s5, s4, s3, s2, s1, s0, MN); return 0; } 変数名などは違いますがこんな感じで組みました。 頂いたアドバイスで「末尾桁の桁上がりに1を入力」というのはfull_adder(a0, b0, 0, &s0, &c0);をfull_adder(a0, b0, 1, &s0, &c0);ということでよいのでしょうか? あと「一方の入力をビット反転]させるやり方がわかりません・・・

すると、全ての回答が全文表示されます。
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

「全加算器」などと言われると、論理回路(ハードウェア)の問題のように思えるのですが。 プログラムの問題だとしても ・「2つの2進数」とは、どんなものを指しているのでしょう? 例えば、 a=97 ; 等と10進数で書いても、内部では2進数で記憶されます。この内部でのことなのか、それとも、外から2進数に相当するなにかを入れるのか? ・「差」は引き算すれば求められます。 普通のプログラミング言語なら、-演算子で簡単に求められるはずです。(a-bのように) それとも、「全加算器」とあるように、論理回路をエミュレートするようなプログラムなのでしょうか? もしかしたら、Verilog等を使った論理合成の問題ですか?

noname#133770
質問者

補足

・scanf関数で2進数を入力します。 桁数の指定はありませんが「0 0 0 0 1 0 1 1」のように入力していきます ・先に2進数の加算のプログラムを作成したのですがその内容が「論理和、論理積、排他的論理和を求める関数を作成し、全加算器の機能を関数で実現する」という内容でしたので、それを使わないと減算も出来ないのかな、と思ったんです。 ・C言語でプログラム内で-演算子だけで2進数の減算できるんですか? ホント始めたばかりでわからなくて・・・

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

a-b でいいじゃん.

すると、全ての回答が全文表示されます。

関連するQ&A