我完全坚持这个问题,所以我正在寻求任何帮助。
我认为每个人都知道基本的GCD计算算法,如二进制或欧几里德GCD。实现这种方法来计算两个单精度数不是问题。实际上,这只是几招。
我需要为多精度数字(超过10 ^ 5位)实现此方法(在C语言中)。有几个GNU库可用(GNU MP,MPFR,MPIR),它们有定义多精度数字并对它们进行操作的方法。它看起来像一个多精度数字存储在内存中,作为一对单精度部分又名“肢体”。
实现了一些用于查找gcd(a,b)的方法,但实际上它们很难满足我的需求。用于GCD计算的二进制方法仅在a和b恰好包含两个肢体时使用。当min(a,b)包含多于(即630)肢体等时使用的HGCD方法。 我发现很难弄清楚,如何使用任何长度的a和b来扩展这些方法中的任何一种。我还发现不同版本的GNU库包含不同的GCD算法版本和方法。
问题:我想知道是否有可能使二进制GCD算法在“肢体”方面使用任意长度的多精度整数,如果可能的话 - 得到任何帮助或想法如何在C中实现它。有没有人有任何想法或代码部分如何实现它?
我想考虑任何建议或任何其他解决方案来解决这个问题。
如果有人看一下,这是GNU MP二进制GCD方法的一部分(a = b = 2个肢体):
/* Use binary algorithm to compute G <-- GCD (U, V) for usize, vsize == 2.
Both U and V must be odd. */
static inline mp_size_t
gcd_2 (mp_ptr gp, mp_srcptr up, mp_srcptr vp)
{
printf("gcd_2 invoked\n");
mp_limb_t u0, u1, v0, v1;
mp_size_t gn;
u0 = up[0];
u1 = up[1];
v0 = vp[0];
v1 = vp[1];
ASSERT (u0 & 1);
ASSERT (v0 & 1);
/* Check for u0 != v0 needed to ensure that argument to
* count_trailing_zeros is non-zero. */
while (u1 != v1 && u0 != v0)
{
unsigned long int r;
if (u1 > v1)
{
sub_ddmmss (u1, u0, u1, u0, v1, v0);
count_trailing_zeros (r, u0);
u0 = ((u1 << (GMP_NUMB_BITS - r)) & GMP_NUMB_MASK) | (u0 >> r);
u1 >>= r;
}
else /* u1 < v1. */
{
sub_ddmmss (v1, v0, v1, v0, u1, u0);
count_trailing_zeros (r, v0);
v0 = ((v1 << (GMP_NUMB_BITS - r)) & GMP_NUMB_MASK) | (v0 >> r);
v1 >>= r;
}
}
gp[0] = u0, gp[1] = u1, gn = 1 + (u1 != 0);
/* If U == V == GCD, done. Otherwise, compute GCD (V, |U - V|). */
if (u1 == v1 && u0 == v0)
return gn;
v0 = (u0 == v0) ? ((u1 > v1) ? u1-v1 : v1-u1) : ((u0 > v0) ? u0-v0 : v0-u0);
gp[0] = mpn_gcd_1 (gp, gn, v0);
return 1;
}
答案 0 :(得分:3)
只针对此问题专门推出自己的代码,为什么不呢? (10^9)^2
符合64位int,因此您可以使用 base - (10^9)
位数,每个都保存在64位int中。要表示2^(10^5)
- 位值2^(10^5) ~= 10^30103
,即具有~30103十进制数字的值,您只需要30103/9 ~= 3350
个整数,这是内存中~27 kB的数组,对于每个涉及的数字。
According to WP, for binary GCD algorithm您只需要minus
和/2
,这可以通过将每个数字减半来实现,偶尔将5*10^8
传送到较低位(94 / 2 = 47 = {4,5+2})
。最终乘以 2 k 可以使用朴素算法完成,因为它只需要完成一次。
在基地打印 - 10
将是微不足道的。如果您不打算打印最终结果,那么您将不需要最终的乘法(或者如果您将结果报告为2^k*x
),那么您可以使用基础 - 10^18
数字,将要使用的位数减半。
您只需要通常的C整数运算来处理数字。