How to correctly import / export int64_t to / from GMP?

49 views Asked by At

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.

0

There are 0 answers