第25講 n進数の演算---その1 加法と減法
第5話 足し算の考え方
まず、
簡単な方から説明しましょう。
右揃えにするには、
void f(int* x,,int n){
int i,j=0;
while(j==0){ //桁数が0になることの禁則処理
j=rand()%10;
}
for(i=0;i<j;i++){
x[i]=rand()%n;
if(i==j-1)if(x[i]==0)i--; //最後の桁が0にならないようにする禁則処理
}
x[j]=n; //終わりの印の代入
}
をvoid型からint型に変更して、
印のついている添え字jを返すようにします。
そして、2つの整数型変数j1,j2を用意して、
j1=f(a,n);
j2=f(b,n);
返された値を受け取っておくのです。
j1とj2の差だけcout<<" ";によって空白行を用意します。
ただし、
のように足し算の結果大きいn進数より和の方が、
位が大きくなる場合がありますから、
両方に最初に空白を1つ入れておく必要があります。
問題は、足し算をどのように実行するかです。
下の5進数の場合の足し算を例にして考えてみましょう。
32014
+ 1204
最後に、終わり記号5が入っていますから
532014
+ 51204
です。
しかし、終わりの記号5
(5進数では0から4までの数字しか入りませんから5が入ることがないので、
終わり記号の意味を持たせることが出来ます。)
は表示のときに、威力を発揮したわけですが、
足し算などの加減乗除では、いろいろいたずらをしますので、
別の配列
int d[10000],e[10000];
を用意して、始めはすべての要素を0にしておいた後で、
必要な分だけ、下のように代入しておきます。
32014
+01204
こうする利点は終わり記号5に邪魔されないだけでなく、
どちらの桁数の方が大きいのかをいちいち考えなくて済むことになります。
01204
+32014
でも全く問題ないわけです。
さて、
32014
+01204
に戻して説明を続けましょう。
まず、1の位の和はc[0]=a[0]+b[0]の計算から、
c[0]には8が入ります。
5進数の場合、最大は4までですから
4(5)+4(5)=13(5)
です。つまり、繰り上がりが発生します。
c[0]には3を入れて、c[1]には1繰り上げるにはどうしたらよいか、
を解決すれば、足し算は出来ます。
c[0]に3を入れる方は皆さんお分かりですね。
c[0]=(a[0]+b[0])%5;
で問題は解決します。
では、1の繰り上げはどうでしょうか
c[1]+=(a[0]+b[0])/5;
で一応問題は解決します。
8を5で割ったときの商は1ですから。
8/5=1ですね。
なぜなら、int型整数同士の割り算もint型になるのでしたね。
ところが、2番目以降の場合には問題があります。
それは、繰り上げを組み込まなければならないからです。
ですから、
for(i=0;i<j;i++){
c[i]=(a[i]+b[i])%n;
c[i+1]+=(a[i]+b[i])/n;
}
ではだめなわけです。
これが正しいのはi=0のときのみです。
ですが、これを改良すれば加法プログラムは完成します。
これ以上書くとヒントの領域を越えてしまいますので、
ここまでにします。
では皆さん、プログラムを組んでみることにしましょう。