Q: Write a program to multiply 2 really long numbers
Answer:
I guess the trick is that the number could be over 16 byte
so first find out how many bytes we need, then multiply different parts seperately
その前に、
17 * 17 = 1 0010 0001
は二進数で
0001 0001
× 0001 0001
--------------------
1 0010 0001
である。
最初の 0001 0001 を a と b と見なし、
あとの 0001 0001 を c と d と見なすと、
結果の0001 0010 0001はそれぞれ、a*c, a*d+b*c, b*d に対応する。
同じ例をもう一つ
1568 * 1568 = 0010 0101 1000 0000 0000
は二進数で
0110 0010 0000
× 0110 0010 0000
--------------------------------------
0010 0101 1000 0000 0000
である。
最初の 0110 0010 0000 を a, b, c と見なし、
あとの 0110 0010 0000 を d, e, f と見なすと、
結果の0010 0010 0000 0000はそれぞれ、a*d, a*e+b*d, a*f+b*e+c*d, c*e+b*f, c*f に対応する。
以上の二つの例から導かれる法則を一般化すると、
int *a = (int *)malloc(sizeof(int)*10000); // a,b, c ...を入れる
int *b = (int *)malloc(sizeof(int)*10000); //d, e, f ...をいれる
long long *c = (long long*)calloc(10000, sizeof(long long)); // 8bytes整数型がないので llong で代用
long long AA = LLONG_MAX // 限界値
long long BB = LLONG_MAX // 限界値
int i=1, j=1;
// 例と違って8 ビットずつ a, b, c などとする
while ( AA/INT_MAX > 0 ) // 32 ビットシフトできる回数を数える
{
i++; // i 個の32ビット塊がある
}
while ( BB/INT_MAX > 0 ) // 32 ビットシフトできる回数を数える
{
j++; // j 個の32ビット塊がある
}
for (int m=i, n=0; m<0; m- -, n++)
a[n] = AA>>(32)*m; // AA の先頭から a[ ] に代入する。
for (int m=i, n=0; m<0; m- -, n++)
b[n] = BB>>(32)*m; // BB の先頭から b[ ] に代入する。
for (int m=0; m<i; m++)
for (int n=0; n<j; n++)
c[m+n] += a[m] * b[[n];
アルゴリズムの流れは上になります。まだ、compile してないのだが、考え方は上で大丈夫です。
あとは人の手で、c[0], c[1], ..... c[ ] を二進数としてつなぎ合わせてから10進数に変換すればよい。
ここでの、各最小ブロックは例のような4 bit ずつではなく、32 bit のなっている。
別解としては、10進数のまま行うこともできます。
例をもう一つ
123 * 123
は10進数で
123
× 123
--------------------------------------
15129
である。
最初の 123 を a, b, c と見なし、
あとの 123 を d, e, f と見なすと、
結果の1, 5, 1, 2, 9はそれぞれ、a*d, a*e+b*d, a*f+b*e+c*d, c*e+b*f, c*f に対応する。
これは2進数と同じ法則性である。
なので、まず大きい数AA, BB をstring に変えて一文字ずつ
a[ ] と b[ ] に入れていく。
で同じようにc[ ] を計算すれば同じ結果が得られます。ただし、1文字につき1配列分なのでmemory 消費は2進数の解法よりも激しいです。
[Quote]:
http://www.careercup.com/question/?q=8ee8f6ee-5c59-43b2-888f-eff52e552795