第25講 n進数の演算---その1 加法
第3話 n進数の加法その2
201012(3)+1202101(3)
の答え
0+0=0
0+1=1
0+2=2
1+0=1
1+1=2
1+2=10
2+0=0
2+1=10
2+2=11
以外の規則を使っていないことが分かります。
加法の仕組みが理解できたところで、
いよいよ加法のプログラムを組んでみることにしましょう。
mainの冒頭に
int n;
を宣言しておいて、
int t=0;
while(1){
cout<<"何進数の演算を考えますか?"<<endl;
t=1;
}
if(t==1)scanf("%d",&n)
としておけば、何進数を扱うのかをキーボードから、
決まることが出来ます。
n進数を納めるには、
整数型の1次元配列
int a[10000],b[10000];
等を用意しておくとよいでしょう。
データはn進数をランダムに2つ発生させて、
表示するプログラムを考えてください。
尚、ランダムデータは最初は10桁以内にしましょう。
それから、データの終わりには終わりの印として、
a[最後]=n;
のようにnを代入しましょう。
nをどうしてデータの終わりの印として使えるかと申しますと、
例えば、5進法(数)で考える場合、
4203
のように5未満の数字が並びます。
ですから、5が入ることがないのです。
それで、
54203
となります。
ではなぜ、終わりの印を入れる必要があるのでしょうか。
int a[10000],b[10000];
とりあえず、最初の方は10桁以内で考えますが、
将来的には、10000桁まで扱えるように、
配列の要素数を10000までしてあります。
変数や配列は、初期化しておかないと適当な値が入っていたりして、
エラーの原因になりますので、
すべて0に初期化しておいた方がよいのです。
C++やC以外では、
変数を宣言した時点で、
0に初期化される言語が多いのですが、
ポインタも扱うC言語、C++ではアドレスが入っていたりして、
0には初期化されません。
ですから、0を代入して意図的に初期化しておかなければなりません。
0に初期化しておきますので、
終わりの印を入れないと
000~0004203
のようになります。0が9996個並ぶことになります。
a[0]=3,a[1]=0,a[2]=2,a[3]=4,a[5]=0,a[6]=0,・・・・
と並んでいますから、for文で表示する場合終わりの印を入れておかないと、
終了場所が分からず、
毎回1万個も数字が並ぶことになります。
ですが、
000~0054203
すなわち、
a[0]=3,a[1]=0,a[2]=2,a[3]=4,a[5]=5(終わり記号),a[6]=0,・・・・
となっていれば、
for(i=0;;i++){
if(a[i]==n)break;
cout<<a[i];
・・・
・・・
}
と終わりの印nの直前までを表示して、
4203
と4個の数字の羅列で終了することが出来ます。
つまり、for文を5回のループで終了することが出来るのです。
nを
10とすると10進数の10万桁の巨大整数を、
100とすると10進数の100万桁の巨大整数を、
1000とすると10進数の1000万桁の巨大整数を、
処理すること出来ます。
将来的には、
78203698402697125026987003591206981111
(この例とて、たったの50桁です。
1000万桁が途方もなく大きいことが分かります。)
のような巨大な整数を考え、
その整数の因数分解や
素数判定などを扱うことを
目標にしていますので、
配列の要素数を多めの1万にとってあるのです。
巨大素数生成などでは、
コンピュータに多大な負担を与えます。
毎回、for文で1万回もループさせていたのでは、
さすがのコンピュータでも、
50桁程度の素数でさえ、
作り出すことは大変困難です。
巨大整数演算では、
無駄なループはさせないことが、
絶対的な要件となります。
不必要なループをさせないために、
終わりの印を入れるのです。
終わりの印はn以上であればよいので、
n+1などでも結構です。
この辺は、プログラマーが決めればよいことなのです。
上の2進数の例では、1つ目の2進数の桁数が4桁で
a[3]=1,a[2]=0,a[1]=1,a[0]=0
2つ目の桁数が8桁となっており、
b[7]=1,b[6]=0,b[5]=1,b[4]=1,b[3]=0,b[2]=0,b[1]=0,b[0]=0
となっています。
それぞれの桁数も10桁以内のランダムな桁数としてください。
最後にnを代入する理由は、
aとbの配列はそれぞれ要素数1万の配列です。
以下の説明は、前に説明したことを再度繰り返しています。
表示させるときに、もし4桁であれば、
for(i=9999;i>=0;i--)
のようにするのは時間の無駄です。
for(i=4;i>=0;i--)
で十分です。
最後が何であるか印を付けておけば、
始める場所が確定します。
それから、4桁のn進数の場合、
4桁目(a[3]ですよ。添え字が0から始まることを忘れないでください。)
が0であってはいけませんね。
0010
なら2桁になってしまいます。
ですから、印しであるnが入っている一つ前の添え字のときには、
0の代入を禁じなければなりません。
桁数も0桁ではいけませんから、
禁則処理が必要になります。
以上のことを考慮に入れると、
ランダムデータを作り、表示させるだけのプログラムでも結構難しいということが、
お分かりかと思います。
ですが、ここまでついてきた優秀な皆さんなら、
必ず成功しますよ。
頑張りましょう。