How to correctly import / export int64_t to / from GMP?
Here is a similar question, but the accepted answer seems to contain a bug.
Here is my implementation:
static void mpz_set_i64 (mpz_t rop, int64_t op)
{
bool neg = false;
bool flag = false;
if (op < 0)
{
if (op == INT64_MIN)
{
++op;
flag = true;
}
op = -op;
neg = true;
}
mpz_import(rop, 1, 1, sizeof(op), 0, 0, &op);
if (neg)
{
mpz_neg(rop, rop);
if (flag)
{
mpz_sub_ui(rop, rop, 1);
}
}
}
// note: mpz_zero is pre-defined zero (leads to better perf.), initialized as mpz_init_set_si(mpz_zero, 0);
static int64_t mpz_get_i64 (mpz_t op)
{
uint64_t u64;
int64_t i64;
size_t countp = 0;
bool neg = mpz_sgn(op) < 0;
if (mpz_cmp(op, mpz_zero) == 0)
{
return 0;
}
if (neg)
{
mpz_neg(op, op);
}
mpz_export(&u64, &countp, 1, sizeof u64, 0, 0, op);
assert(countp == 1);
if (neg)
{
assert(u64 <= 1ull-(INT64_MIN+1));
i64 = -(int64_t)u64;
}
else
{
assert(u64 <= INT64_MAX);
i64 = (int64_t)u64;
}
return i64;
}
Is this implementation correct and optimal?
Here is the documentation for mpz_import and mpz_export.
Here is the live demo.