36 using limb_t = uint64_t;
38 using limb_t = uint32_t;
42 static constexpr size_t kBytes = 8 * W64;
43 static constexpr size_t kBits = 64 * W64;
44 static constexpr size_t kLimbs = kBytes /
sizeof(limb_t);
45 static constexpr size_t kU64 = W64;
46 static constexpr size_t kBitsPerLimb = 8 *
sizeof(limb_t);
49 static_assert(kLimbs *
sizeof(limb_t) == kBytes);
54 explicit Limb(uint64_t x) : limb_{} { assign(limb_, 1, &x); }
56 explicit Limb(
const std::array<uint64_t, kU64>& a) : limb_{} {
57 assign(limb_, kU64, &a[0]);
60 std::array<uint64_t, kU64> u64()
const {
61 std::array<uint64_t, kU64> a;
62 unassign(limb_, kU64, &a[0]);
66 void to_bytes(uint8_t a[])
const {
67 for (
size_t i = 0; i < kLimbs; ++i) {
68 a = to_bytes(&limb_[i], a);
72 bool operator==(
const T& other)
const {
73 for (
size_t i = 0; i < kLimbs; ++i) {
74 if (limb_[i] != other.limb_[i]) {
80 bool operator!=(
const T& other)
const {
return !(operator==(other)); }
84 limb_t shiftr(
size_t z) {
86 for (
size_t i = kLimbs; i-- > 0;) {
88 limb_[i] = c | (d >> z);
89 c = d << (kBitsPerLimb - z);
95 limb_t bit(
size_t pos)
const {
96 size_t ind = pos / kBitsPerLimb;
98 size_t off = pos % kBitsPerLimb;
99 return (limb_[ind] >> off) & 0x1u;
105 static void assign(uint64_t d[],
size_t ns,
const uint64_t s[]) {
106 for (
size_t i = 0; i < ns; ++i) {
111 static void assign(uint32_t d[],
size_t ns,
const uint64_t s[]) {
112 for (
size_t i = 0; i < ns; ++i) {
113 d[2 * i] =
static_cast<uint32_t
>(s[i]);
114 d[2 * i + 1] =
static_cast<uint32_t
>(s[i] >> 32);
118 static void unassign(
const uint64_t d[],
size_t ns, uint64_t s[]) {
119 for (
size_t i = 0; i < ns; ++i) {
124 static void unassign(
const uint32_t d[],
size_t ns, uint64_t s[]) {
125 for (
size_t i = 0; i < ns; ++i) {
126 s[i] = d[2 * i] | (
static_cast<uint64_t
>(d[2 * i + 1]) << 32);
130 static const uint8_t* of_bytes(uint64_t* r,
const uint8_t* a) {
134 static const uint8_t* of_bytes(uint32_t* r,
const uint8_t* a) {
139 static uint8_t* to_bytes(
const uint64_t* r, uint8_t* a) {
143 static uint8_t* to_bytes(
const uint32_t* r, uint8_t* a) {