二进制 GCD - 算法太慢
Binary GCD - too slow algorithm
根据维基百科(http://en.wikipedia.org/wiki/Binary_GCD_algorithm),我试图为bignums(最多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 本身就很快),但我得到的反馈是我的程序太慢了。
您已将 bignum 表示为以 2 为基数(二进制)数字的数组。
真正的 bignum 库不使用 2 的基数。 它们使用更大的基数,因为 CPU 具有一次在多个位上运行的指令。 通常,如果您的目标是最大速度和最小大小,则使用基数为 256 (28)、65536 (216)、4294967296 (232) 或 18446744073709551616 (264),如果必须存储精确的小数部分,则使用基数为 100(
每个数字一个字节)、10000(每个数字两个字节)、100000000(每个数字四个字节)或 1000000000000000000(每个数字 8 个字节)。您需要使用 vector<uint32_t>
或 vector<uint64_t>
之类的东西作为 bignum,并且一次操作 32 或 64 位,而不是一次只处理 1 位。
相关文章:
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 算法问题:查找从堆栈中弹出的所有序列
- 下面是排序算法O(n)吗
- KMP算法和LPS表构造的运行时间
- 为什么我的排序算法会更改数组值
- 求最大元素位置的分治算法
- 具有非整数边容量的最大流量的Dinic算法
- 到连接组件算法的问题(递归)
- NTRUEncrypt:使用开源标准算法中的描述无法正确找到两个多项式的GCD,无法定义是否存在多边形的逆
- 二进制 GCD - 算法太慢
- GCD 算法不正确
- 使用欧几里得算法找到GCF(GCD)
- 扩展GCD算法
- 使用欧几里得算法识别两个值的最大公约数 (GCD)