提问人:Daniel S. 提问时间:8/22/2022 最后编辑:Daniel S. 更新时间:9/15/2022 访问量:248
将“__int128”添加到GMP库的“mpz_class”或“mpz_t”的更快方法?
Faster way to add an `__int128` to an `mpz_class` or `mpz_t` of the GMP library?
问:
我想使用 g++ 和 GMP(或):mpz_class
mpz_t
typedef unsigned __int128 tw_limb_t;
mpz_class a = "1234567890123456789012345678901234567890";
tw_limb_t b = ...;
a += b;
我可以执行以下操作,但是首先将其转换为:__int128
mpz_t
typedef unsigned __int128 tw_limb_t;
inline mpz_class& operator+=(mpz_class &lhs, const tw_limb_t &rhs) {
if (sizeof(tw_limb_t) != 2 * sizeof(mp_limb_t)) {
throw std::runtime_error("sizeof(tw_limb_t) is not twice 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;
}
如何从中获得更高的性能?
答:
1赞
Daniel S.
8/24/2022
#1
这是我目前使用的最佳解决方案,正如 Marc Glisse 所建议的那样。mpz_roinit_n
typedef unsigned __int128 tw_limb_t;
inline mpz_class& operator+=(mpz_class &lhs, const tw_limb_t &rhs) {
if (sizeof(tw_limb_t) != 2 * sizeof(mp_limb_t)) {
throw std::runtime_error("sizeof(tw_limb_t) is not twice 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 tw_limb_t &rhs) {
lhs += rhs;
return lhs;
}
评论