2進数の四則演算のプログラムを作りたいと思い、2進数を表示するところまではできたのですが、加算になると繰り上がりという壁にぶつかってしまいました。繰り上がりや桁上げなどがよく分からないので、お教えください。(下のソースコードが繰り上がりのない加算をするまでのものです)
#include <stdio.h>
int main(void)
{
int a,b,i,j,x[8],y[8],z[8];
do{
puts("二つの符号なし整数を入力してください。(ただしa>bとし、bはのべき乗の値とする)");
printf("a="); scanf("%d",&a);
printf("b="); scanf("%d",&b);
if(a < = b)
puts("入力した値がa>bになっていません。\a");
}while(a < = b);
for( i = 0; i < = 7; i + +){
x[i] = a % 2;
a = a / 2;
y[i] = b % 2;
b = b / 2;
}
puts("aとbをそれぞれ二進数で表すと");
printf("a=");
for( i = 7; i > = 0; i - -){
printf("%d",x[i]);
}
puts("");
printf("b=");
for( i = 7; i > = 0; i - -){
printf("%d",y[i]);
}
printf("となります。\n\n");
printf("<加算>\n");
printf("c=a+b=");
for( j = 7; j > = 0; j - -){
z[j]=x[j]^y[j];
printf("%d",z[j]);
}
return(0);
}
No.1ベストアンサー
- 回答日時:
桁上がり変数 carry を使って、
:
(前略)
:
main(void)
{
int a,b,i,j,x[8],y[8],z[8], carry=0;
:
(中略)
:
for(j=0; j<8; j++) {
z[j]=x[j]^y[j]^carry;
carry = (x[j] & y[j]) | (x[j] & carry) | (y[j] & carry);
}
if (carry != 0) printf("%d", carry);
for(j=7; j>=0; j--) {
printf("%d",z[j]);
}
:
(後略)
:
とすれば良いのではないでしょうか。
※ (a + b) を 2進数表示すれば同じ結果が得られますが、これではいけませんか。
No.2
- 回答日時:
a > bという制約条件を設ける必要はないと思います。
今は1 + 1の計算もできない状態です。それよりはむしろ、aとbを二進法で表現したときのビット数が最大8という条件が
ありますので、0 <= a <= 255(bも同じ)という条件を付けるべきでしょう。
足し算の結果は9ビットになる場合があります。z[8]では足りません。
右側の桁から足し算を行なうのはよいですが、^ 演算子はさすがにまずいですね。
ある桁どうしを普通に足し算して、1+1=2のときにどうすればよいかを
考えてみてください。
No.4
- 回答日時:
仕様がまだはっきり固まってないようです。
オーバーフローの処理をどうするか、マイナスの数をどうするか、
マイナスを許容する際には、1の補数か2の補数かなど。
繰り上がり、繰り下がりはプログラミングの問題ではなく、
手計算(筆算)でマスターしてください。
No.5
- 回答日時:
★2進数の加算のおさらい
・0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 0 ←ここで桁上がり
となりますよね。
・という事は a=1、b=1 の時に carry ビットを 1 として用意すればよい。
そして carry ビットも a、b に足しこむようにすれば良い。
下にサンプルを載せます。なお、XOR を使っていません。
サンプル:
int carry; ←宣言に追加
// 計算
for ( carry = i = 0 ; i < 8 ; i++ ){ ←下位ビットから計算
switch ( x[i] + y[i] + carry ){ ←carry を足しこむ
case 0: z[ i ] = 0; carry = 0; break;
case 1: z[ i ] = 1; carry = 0; break;
case 2: z[ i ] = 0; carry = 1; break; ←桁上がり
case 3: z[ i ] = 1; carry = 1; break; ←桁上がり
default: // エラー表示など
}
}
// 結果表示
printf( "<加算>\n" );
printf( "c=a+b=" );
printf( "%d ", carry ); ←桁上がりも表示
for ( i = 7 ; i >= 0 ; i-- ){
printf( "%d", z[i] );
}
printf( "\n" );
その他:
・z[] 配列は 9 にして z[8] に最終的な桁上がりが格納されるようにするのもいいかも。
つまり
int i, x[ 8 ], y[ 8 ], z[ 9 ]; ←サイズを 9 に
for ( z[1] = i = 0 ; i < 8 ; i++ ){ ←下位ビットから計算
switch ( x[i] + y[i] + z[i + 1] ){ ←z[i+1] が carry です
case 0: z[ i ] = 0; z[i + 1] = 0; break;
case 1: z[ i ] = 1; z[i + 1] = 0; break;
case 2: z[ i ] = 0; z[i + 1] = 1; break; ←桁上がり
case 3: z[ i ] = 1; z[i + 1] = 1; break; ←桁上がり
default: // エラー表示など
}
}
または
int i, carry, x[ 8 ], y[ 8 ], z[ 9 ]; ←サイズを 9 に
for ( carry = i = 0 ; i < 8 ; i++ ){
if ( (z[i] = x[i] + y[i] + carry) >= 2 ){
z[ i ] -= 2; // z[i] &= 1; でも良い。
carry = 0;
}
else{
carry = 1;
}
}
z[ i ] = carry; ←最終的な桁上がりをセット
↑
こんな感じでも良いかな。
・以上。
No.6
- 回答日時:
*** はじめまして ***
6行で記述すると次のようになります
int temp; ←追加
for(i = 0, ans[0] = 0; i < 5; i++){
temp = a[i] + b[i] + ans[i];
ans[i] = temp % 2;
ans[i + 1] = temp / 2;
}
一応分かりやすく書きましたが、ビットを表す配列が多大な場合、このプログラムは遅いです。
なぜなら、%演算子、/演算子は他の演算子に比べて非常に遅いためです。 tempをわざわざ用意したのは配列の参照回数を減らし、少しでも速度を向上するためですw
%や/演算子を省いたものを使用したいならば、他の方の回答を参考にしてください。力不足で申し訳ないです。
No.7
- 回答日時:
申し訳ありません。
回答の修正です。変数 i の範囲を8にして、ansをzの配列にし、zの配列を9つ用意してください。 自分で試したプログラムをそのまま写してしまいました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# c言語でユーザ関数を利用して複素数のべき乗と絶対値の数列を計算するプログラムが作りたいです。 3 2023/01/29 22:13
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
printf で二進表示を行いたい。
-
10個出力で改行したいのですが...
-
コマンドラインに出力した文字...
-
ブラックジャック
-
C言語で、「自然数nを入力し、n...
-
error C2143: 構文エラー : ';'...
-
scanfに文字が入力されたときに...
-
4の倍数を論理演算で表す。。
-
縦の棒グラフ
-
パスカルの三角形についてのCプ...
-
(C言語)めちゃくちゃな値にな...
-
ピラミッド表示プログラム。
-
C言語 ツェラーの公式を使った...
-
CTRL+Dでループを抜けるには
-
勝率をプログラムに
-
Visual Sutdio 2017 でのC言語...
-
%P と %X の違い
-
printf( " %2d", p * q );
-
C言語 プログラミング ごめんな...
-
printf()文の書式
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
10個出力で改行したいのですが...
-
既約分数の表示プログラム
-
printf で二進表示を行いたい。
-
8人分のテストの点数を入力し、...
-
printf( " %2d", p * q );
-
strcmp
-
CTRL+Dでループを抜けるには
-
4の倍数を論理演算で表す。。
-
%P と %X の違い
-
【C言語教えてください】sin波...
-
c言語でAからZまでを表示する...
-
cshの文字列操作(0埋め)
-
万年カレンダーのC言語プログラ...
-
コマンドラインに出力した文字...
-
scanfに文字が入力されたときに...
-
コンパイルエラーについて
-
ホームページをC言語で作りたい...
-
改行について 1行に何個かづ...
-
台形の面積を求めるプログラム
-
なぜgccはstdio.hをインクルー...
おすすめ情報