Cでmpz_t変数をunsignedlonglongに変換する方法はありますか?ullからmpz_tへの逆の方法はどうですか?ullはC99の一部であるため、gmpライブラリはこれをサポートしていません。私はこれを見つけましたが、それはc ++にあり、c++でコーディングする方法がわかりません。よろしくお願いします。
質問する
4748 次
2 に答える
8
unsigned long long
との間を変換するためのいくつかの関数を次に示しますmpz_t
。mpz2ull
数が大きすぎて:に収まらない場合は、スタックが壊れるunsigned long long
ことに注意してください。
unsigned long long mpz2ull(mpz_t z)
{
unsigned long long result = 0;
mpz_export(&result, 0, -1, sizeof result, 0, 0, z);
return result;
}
void ull2mpz(mpz_t z, unsigned long long ull)
{
mpz_import(z, 1, -1, sizeof ull, 0, 0, &ull);
}
于 2011-06-06T07:25:56.097 に答える
4
これらの関数は、mpz_tとsigned / unsignedlonglongの間で変換するために機能するはずです。文字列処理を行う必要がないため、適度に高速である必要があります。
void mpz_set_sll(mpz_t n, long long sll)
{
mpz_set_si(n, (int)(sll >> 32)); /* n = (int)sll >> 32 */
mpz_mul_2exp(n, n, 32 ); /* n <<= 32 */
mpz_add_ui(n, n, (unsigned int)sll); /* n += (unsigned int)sll */
}
void mpz_set_ull(mpz_t n, unsigned long long ull)
{
mpz_set_ui(n, (unsigned int)(ull >> 32)); /* n = (unsigned int)(ull >> 32) */
mpz_mul_2exp(n, n, 32); /* n <<= 32 */
mpz_add_ui(n, n, (unsigned int)ull); /* n += (unsigned int)ull */
}
unsigned long long mpz_get_ull(mpz_t n)
{
unsigned int lo, hi;
mpz_t tmp;
mpz_init( tmp );
mpz_mod_2exp( tmp, n, 64 ); /* tmp = (lower 64 bits of n) */
lo = mpz_get_ui( tmp ); /* lo = tmp & 0xffffffff */
mpz_div_2exp( tmp, tmp, 32 ); /* tmp >>= 32 */
hi = mpz_get_ui( tmp ); /* hi = tmp & 0xffffffff */
mpz_clear( tmp );
return (((unsigned long long)hi) << 32) + lo;
}
long long mpz_get_sll(mpz_t n)
{
return (long long)mpz_get_ull(n); /* just use unsigned version */
}
関数シグネチャは、ネイティブGMP関数のように見えるはずです。他のgmpz_set_
関数と同様に、これらは渡された変数がすでに初期化されていることを前提としていますが、gmp_init_set_
スタイル関数に変更するのは簡単です。
于 2013-01-27T03:57:46.257 に答える