どのように私は、この他の型に長く使用してからこのC ++関数で変換することができますか?

StackOverflow https://stackoverflow.com/questions/2259395

  •  20-09-2019
  •  | 
  •  

質問

私は "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:エラー:この構文を使用して配列を初期化することはできません。

役に立ちましたか?

解決

あなたは、ほとんどが正しい軌道に乗っていました。しかし、両方の関数のパラメータはタイプmpz_tでなければなりません。だから、ヘッダーのように:

void s(mpz_t n, mpz_t final)

あなたは終わり、最終的=合計を必要としません。あなたは合計を使用して、どこでも代わりに、ちょうど最終使用。また、実行します:

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

のためのforループ。呼び出しは次のようである。

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

EDIT:Steve314で述べたように、あなたはすべてのmpz_initためmpz_clearを行う必要があります。あなたは、呼び出し元がinitted最終的に合格することができますので、それをm、温度、およびIを掃除残します。

他のヒント

あなたの最後の行は、*最終=合計する必要があります。そうしないと、へのポインタポイントアドレスを変更します。

またはその代わりに参照を使用します)。

ただ、forループの代わりに、前に私を宣言して初期化..

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

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

GMPはIIRC、純粋なCライブラリです。

気になる部分はmpz_t変数の清掃の欠如(Cでないデストラクタ)、そして最後の行に代入演算子の使用を含む(Cでないオーバーロードされた演算子を - これは有効なPODのmemcpyです)。 IIRC、mpz_clearは整数クリーンアップ関数である。

mpz_setまたはmpz_swapのいずれかでassigmentを交換してください - 。スワップは、より効率的であるあなたはそれが基礎となるデータ構造のコピーを避けるよう、一時的に削除しようとしている場合は、

それでも、本当に説明するだろうそのすべてがメモリリークです。

疑いの私の次の領域は、同じ変数が両方の入力および出力として使用されるコールであろう。私はGMPについては知らないが、ポインタを渡すときのライブラリの多くは、これを好きではない - 入力パラメータを使用している間、変更されます(これは、出力であるため)、破損の原因となります。いくつかの余分な一時が必要になることがあります。

タグのテンプレートを使用してみてください
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;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top