I want to do this with a 128 bit integer using g++ and GMP 's mpz_class
(or mpz_t
):
typedef unsigned __int128 dbl_limb_t;
mpz_class a = "1234567890123456789012345678901234567890";
dbl_limb_t b = ...;
a += b;
I can do the following, but it seems slow to first convert the __int128
to mpz_t
:
typedef unsigned __int128 dbl_limb_t;
inline mpz_class& operator+=(mpz_class &lhs, const dbl_limb_t &rhs) {
if (sizeof(dbl_limb_t) != 2 * sizeof(mp_limb_t)) {
throw std::runtime_error("sizeof(dbl_limb_t) is not double of sizeof(mp_limb_t)");
}
const int LIMB_BITLEN = sizeof(mp_limb_t) * 8;
mpz_class rhs_mpz = (mp_limb_t) (rhs >> LIMB_BITLEN);
rhs_mpz <<= LIMB_BITLEN;
rhs_mpz += (mp_limb_t) rhs;
lhs += rhs_mpz;
return lhs;
}
How to get more performance out of this?
This is my current best solution using mpz_roinit_n
as suggested by Marc Glisse.
typedef unsigned __int128 dbl_limb_t;
inline mpz_class& operator+=(mpz_class &lhs, const dbl_limb_t &rhs) {
if (sizeof(dbl_limb_t) != 2 * sizeof(mp_limb_t)) {
throw std::runtime_error("sizeof(dbl_limb_t) is not double of sizeof(mp_limb_t)");
}
mpz_t rhs_mpz;
mpz_roinit_n(rhs_mpz, reinterpret_cast<const mp_limb_t*>(&rhs), 2);
mpz_add(lhs.get_mpz_t(), lhs.get_mpz_t(), rhs_mpz);
return lhs;
}
inline mpz_class operator+(mpz_class lhs, const dbl_limb_t &rhs) {
lhs += rhs;
return lhs;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.