在C语言中,有没有一种方法将mpz_t变量转换为unsigned long long?反过来呢,从ull转换为mpz_t?由于ull是C99的一部分,gmp库不支持这个功能。
我找到了这个,但它是用c++编写的,而我不知道如何使用c ++。谢谢提前。
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);
}
gmp_snprintf
始终会提供有效的输出。;-) - C. K. Youngmpz_export
和mpz_import
。(这次我甚至测试过它们!)注意:如果数字太大而无法容纳,则mpz2ull
将破坏您的堆栈。这是一种特性(尽管具有未定义的行为,为了保持代码简单),而不是错误。;-) - C. K. Young这些函数应该可以将mpz_t类型和有符号/无符号的long long类型相互转换。它们应该是相当快速的,因为它们避免了字符串处理:
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_
样式的函数。