どのように私は、この他の型に長く使用してからこのC ++関数で変換することができますか?
質問
私は "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;
}