ウィキペディア ( http://en.wikipedia.org/wiki/Binary_GCD_algorithm ) によると、bignum (最大 5000 桁) のバイナリ GCD を作成しようとしていました。
私のGCD自体は次のようになります。
bitset<N> gcd(bitset<N> u, bitset<N> v) {
bitset<N> one (string("1"));
bitset<N> zero (string("0"));
int shift;
if (u == 0) return v;
if (v == 0) return u;
for (shift = 0; ((u | v) & one) == zero; ++shift) {
u >>= 1;
v >>= 1;
}
while ((u & one) == zero) u >>= 1;
do {
while ((v & one) == zero) v >>= 1;
if (u.to_string() > v.to_string()) {
bitset<N> t = v;
v = u;
u = t;
}
bitsetSubtract(v,u);
} while (v != 0);
return u << shift;
}
私は独自のビットセット減算関数も使用しています:
void bitsetSubtract(bitset<N> &x, const bitset<N> &y) {
bool borrow = false;
for (int i = 0; i < N; i++) {
if (borrow) {
if (x[i]) {
x[i] = y[i];
borrow = y[i];
} else {
x[i] = !y[i];
borrow = true;
}
} else {
if (x[i]) {
x[i] = !y[i];
borrow = false;
} else {
x[i] = y[i];
borrow = y[i];
}
}
}
}
このアルゴリズムの速度を改善する場所は見当たりません (バイナリ GCD 自体は高速です) が、プログラムが遅すぎるというフィードバックが寄せられています。