如何将此C ++函数从使用long转换为其他类型?

时间:2010-02-13 22:44:48

标签: c++ gmp

我有一个名为“s”的原始C ++函数:

long s(long n) {
  long sum = 0;
  long m;

  m = (long) sqrt(n);
  for (long i = 2; i < m; i++)
    if ((n % i) == 0) sum += (i + (n/i));
  if (n>1) sum += 1;
  if ((m*m) == n) sum += m;
  return sum;
}

我一直在努力将此功能转换为使用GMP的mpz类型,因此它将允许任意长整数。

这是我的尝试:

void s(mpz_t n, mpz_t *final)
{
    mpz_t sum;
    mpz_t m;
    mpz_t temp;

    mpz_init (sum);
    mpz_init (m);
    mpz_init (temp);

    mpz_set_str (sum, "0", 10);

    mpz_sqrt(m, n);
    for (mpz_t i, mpz_init(i), mpz_set_str(i, "2", 10); mpz_cmp(i,m)< 0; mpz_add_ui(i, i, 1))
    {
        mpz_mod(temp, n, i);
        if (mpz_cmp_si(temp, 0) == 0)
        {
            // use divexact since we know they are divisable
            mpz_divexact(temp, n, i);
            mpz_add(temp, temp, i);
            mpz_add(sum, sum, temp);
        }
    }

    if (mpz_cmp_si(n, 1) > 0) mpz_add_ui(sum, sum, 1);

    mpz_mul(temp, m, m);
    if (mpz_cmp(temp, n) == 0) mpz_add(sum, sum, m);
    final = sum;
}

可以在此处找到整个原始程序:http://pastebin.com/mf751592

我做错了什么?我似乎最初遇到麻烦,因为我无法返回类型mpz_t。所以相反,我传入了一个指向我希望函数返回的指针。

尽管如此,我仍然在努力。有人能指出我正确的方向吗?

这一行: for (mpz_t i, mpz_init(i), mpz_set_str(i, "2", 10); mpz_cmp(i,m)< 0; mpz_add_ui(i, i, 1))
给出此错误:23:错误:无法使用此语法初始化数组

5 个答案:

答案 0 :(得分:3)

你大部分时间都在正确的轨道上。但是,两个函数参数都应该是mpz_t类型。所以标题就像:

void s(mpz_t n, mpz_t final)

最后你不需要final = sum。相反,只要在使用总和的任何地方使用final。另外,请执行:

mpz_t i;
for (mpz_init_set_ui(i, 2); mpz_cmp(i,m) < 0; mpz_add_ui(i, i, 1))

for for循环。通话就像:

mpz_t final, n;
mpz_init(final);
mpz_init_set_ui(n, 5);
s(n, final);

编辑:正如Steve314所说,你应该为每个mpz_init做一个mpz_clear。因为你可以让调用者通过一个初始的final,这样可以清理m,temp和i。

答案 1 :(得分:1)

你的最后一行应该是* final = sum;否则,您可以更改指针指向的地址。

或者改为使用引用:)

答案 2 :(得分:1)

只需在for循环之前声明并初始化i ..

mpz_t i;
mpz_init(i);
mpz_set_str(i, "2", 10);

for (; mpz_cmp(i,m)< 0; mpz_add_ui(i, i, 1)) {
   ...
}

答案 3 :(得分:1)

gmp是一个纯粹的C库,IIRC。

关注的领域包括缺少mpz_t变量的清理(C中没有析构函数),以及在最后一行使用赋值运算符(C中没有重载运算符 - 这实际上是POD memcpy)。 IIRC,mpz_clear是整数清理函数。

使用mpz_set或mpz_swap替换该分配 - 如果您要删除临时数据,则交换效率更高,因为它可以避免复制基础数据结构。

但是,所有这些都可以解释为内存泄漏。

我怀疑的下一个领域是将同一个变量用作输入和输出的调用。我不知道gmp,但是很多库在传递指针时都不喜欢这样 - 输入参数在被使用时会被更改(因为它也是输出),导致损坏。可能需要一些额外的临时工具。

答案 4 :(得分:0)

尝试使用模板

template <class myType>
myType s(myTypen) {
myType sum = 0;
myType m;

m = (myType) sqrt(n);
for (myType i = 2; i < m; i++)
  if ((n % i) == 0) sum += (i + (n/i));
 if (n>1) sum += 1;
if ((m*m) == n) sum += m;
return sum;
}