アプリ版:「スタンプのみでお礼する」機能のリリースについて

C言語初学者です。
タイトル通り、2進数の足し算をするプログラムを作っていますが、行き詰ってしまいました。
特に、桁上げをどうするか悩んでいます。
今の自分の考えでは、入力された数値を10で割り、その余りを足していけばできると思っていたのですが、やはり桁上げや繰り上がりに悩んでいます。
全然できてませんが以下ソースです。

#include <stdio.h>

int main(void)
{
int a, b, i;

do {
printf("8桁以下の非負の2進数を入力してください(1つ目): ");
scanf("%d" ,&a);
if (a < 0)
puts("負の数を入力しないでください。");
} while (a < 0);

do {
printf("8桁以下の非負の2進数を入力してください(2つ目): ");
scanf("%d" ,&b);
if (b < 0)
puts("負の数を入力しないでください。");
} while (b < 0);

a = a % 10;
b = b % 10;

よろしくお願いします。

A 回答 (5件)

ちょっと質問者の意図とは違うかもしれないですが…




論理回路をそのままプログラムに直したような感じではどうでしょう。

2進数数値を入力してもらうときに、文字列配列へ入力してもらいます。
// scanf("%s", A) など
2つの値をそれぞれ A B として、各ビット(要素)について、加算器と同様の演算をします。
#参考URLを参照してください


例として4ビットでやってみると…
要素:3 2 1 0
-------------
 A:0 0 1 1
 B:1 0 0 1

0番目の要素 A[0]:1 B[0]:1 について、足し算の結果 S と繰り上げのフラグ C という配列に
S[0] = 1 + 1 = 0
C[0] = 1(桁上げあり)
と格納します。
#Sは2値のExOR、Cは2値のANDです。

次の桁では、C の値を考慮し…
S[1] = A[1]:1 + B[1]:0 + C[0]:1 = 0
C[1] = 1(桁上げあり)
#C[1] は A[1],B[1],C[0]のうち2つ以上が 1 なら 1

S[2] = A[2]:1 + B[2]:0 + C[1]:1 = 1
C[2] = 0(桁上げなし)
 :
 :
これを各桁についてすべて行うと、結果がでるはず。

(これを2進数のまま表示するなら、S 配列を出力すればいいですし、10進にするなら…変換が必要です。)


どうしても、int型の値を使い1つの変数で表したい場合は、10で割って余りを求めていくしかないですね。
でも、基本的に演算内容は論理回路と似てるはずなので、参考にしてください。


Wikipedia - 加算器

参考URL:http://ja.wikipedia.org/wiki/%E5%8A%A0%E7%AE%97% …

この回答への補足

ご回答ありがとうございます。
まだまだ始めたばかりの素人なので自分にはちょっと難しいかなと思います。
10で割って余りを求めていくものも、繰り上がりがなかなか思いつきません。
丁寧な回答ありがとうございました。

補足日時:2006/09/24 13:45
    • good
    • 0

#3です。



10で割った余りを用いても計算できますが、結果的に2進数の足し算を行うには全加算器の論理回路or論理式がわからないとできません。
まずは、全加算器の動作からがんばってみてください。

一応、プログラムの一部を乗っけておきます。
ただしコメントは一切書きませんのであしからず。

int a, b, i, x, y;
int carry[9] = {0};
int sum[8] = {0};

for(i = 1; i <= 8; ++i)
{
 x = a % 10;
 y = b % 10;

 sum[i] = x ^ y ^ carry[i-1];
 carry[i] = (x && y) || (y && carry[i-1]) || (x && carry[i-1]);

 a = a / 10;
 b = b / 10;
}

printf("答え:");
for(i = 8; i > 0; --i)
{
 printf("%d", sum[i]);
}

この回答への補足

二度も回答いただきありがとうございます。
とりあえず、プログラムは何とか完成しました(かなり無理矢理ですが)。
次は、全加算器の動作を作ってみようと思います。
本当にありがとうございました。

補足日時:2006/09/25 17:18
    • good
    • 0

2進数の足し算ということですが、


まず、
1.2進数をどうプログラムの中に表現するか?
2.どうやって足し算を行うか?
3.どうやって結果を表示するか?
という3点に絞られると思います。

はじめに、プログラムを拝見すると非負の8桁以内の2進数ということですので
10進数で0-255までの値ということになりますね。
一番簡単な2進数の表し方ですが、
int bin[8];
などとして、8個の箱にそれぞれ0か1が入るようにすればよいのではないでしょうか?
また、ほかの方の回答のように直接文字列で"1","0"で入力してもよいのではないでしょうか?

それでは、次にどうやって足し算を行うかについて考えてみたいと思います。
最下位bitから計算してきましょう。結果をR 桁上がりをCとして考えます。
A[0] B[0] R[0] C[1]
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1
となります。
これは、一般化して
A[n] B[n] C[n] R[n] C[n+1]
0 0 0 0 0
0 1 0 1 0
1 0 0 1 0
1 1 0 0 1
0 0 1 1 0
0 1 1 0 1
1 0 1 0 1
1 1 1 1 1
となります。
int A[8];
int B[8];
int C[9];
int R[9];
として下位ビットからCとRを求めていけばよいでしょう。

結果の表示なのですが、
2進数でそのまま表示しても、10進数で表示してもかまわないと思います。
たぶん、10進に変換した方が勉強になると思います。

BinNum = 1;
Result = 0;
for(i = 0;i < 9; i++){
Result = Result + R[i] * BinNum;
BinNum = BinNum*2;
}

とでもすればよいと思います。

この回答への補足

ご回答ありがとうございます。
自分はまだビットというものを把握できていないので、難しいような気がします。
これから地道に学習していこうと思います。
丁寧な回答ありがとうございます。

補足日時:2006/09/25 17:10
    • good
    • 1

strtol または、strtoul を使えば2進数文字列をlong または、unsigned long に変換できるので、


その上で計算し、結果をまた2進数表示に直して表示すればいいかと思います。

2進の計算じたいをやりたいということであれば、
char の配列で適当に桁を揃えてやれば、
筆算の要領でできると思います。

この回答への補足

ご回答ありがとうございます。
strtolやstrtoulはまだ使い方がわかりません。
いろいろ調べてみようと思います。

補足日時:2006/09/24 13:44
    • good
    • 0

ちょっと,トリッキーな作り方な気がしますが.



a1 = a % 10;
とすればa1にaを2進数だとおもったときの,1の位の数字(0or1)が得られるはずです.
もし,これが2~9だったら入力された数字が2進数(0と1のみでできている)でなかったってことです.

つぎの2の位の数ですが,
a = a / 10;
a2 = a % 10;
とすれば得られます.同様に,4の位はさらに
a = a / 10;
a4 = a % 10;
とすれば得られます.

これをよく考えてループにすればいいでしょう.

この回答への補足

ご回答ありがとうございます。
ループは何とか作れましたが、足し算がなかなかできません。
特に、桁上げがわからないです。
桁ごとに数値を見て2以上ならば次の桁に1を足す、というIF文を作ろうと思いますが、なかなか考え付きません。
もっと良いやり方はありますでしょうか?

補足日時:2006/09/24 13:34
    • good
    • 2

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!