15#include "../uint256/uint256.hpp"
23inline std::vector<uint64_t>
slice_input(
const uint256_t& input,
const uint64_t base,
const size_t num_slices)
27 std::vector<uint64_t> slices;
29 for (
size_t i = 0; i < num_slices; ++i) {
30 slices.push_back((target % base).
data[0]);
35 slices.push_back((target % base).
data[0]);
47 const std::vector<uint64_t>& bases)
50 std::vector<uint64_t> slices;
51 for (
size_t i = 0; i < bases.size(); ++i) {
53 if (target >= bases[i] && i == bases.size() - 1) {
56 slices.push_back((target % bases[i]).
data[0]);
69 for (
size_t i = 1; i < num_slices; ++i) {
70 output[i] = output[i - 1] * base;
83 auto converted = input;
85 constexpr auto base_powers = get_base_powers<base, 32>();
86 for (
size_t i = 0; i < 32; ++i) {
87 uint64_t sparse_bit = ((converted >> i) & 1U);
89 out += base_powers[i];
105 constexpr auto bases = get_base_powers<base, 32>();
107 for (uint64_t i = 0; i < 32; ++i) {
108 const auto& base_power = bases[
static_cast<size_t>(31 - i)];
110 for (uint64_t j = 1; j < base + 1; ++j) {
111 const auto threshold = prev_threshold + base_power;
112 if (target < threshold) {
113 bool bit = ((j - 1) & 1);
115 output += (1ULL << (31ULL - i));
118 target -= (prev_threshold);
122 prev_threshold = threshold;
140 for (
size_t i = 0; i < num_bits; ++i) {
141 const uint64_t bit = (input >> i) & 1U;
156 for (
size_t i = 0; i < num_bits - 1; ++i) {
157 result.
limbs[i] += other.limbs[i];
158 if (result.
limbs[i] >= base) {
159 result.
limbs[i] -= base;
160 ++result.
limbs[i + 1];
166 result.
limbs[num_bits - 1] += other.limbs[num_bits - 1];
167 result.
limbs[num_bits - 1] %= base;
168 result.
value += other.value;
174 *
this = *
this + other;
183 for (
size_t i = num_bits - 1; i < num_bits; --i) {
193 std::array<uint64_t, num_bits>
limbs;
#define BB_ASSERT(expression,...)
Integer type that stores each bit as a separate digit in the given base. Supports addition with singl...
sparse_int & operator=(sparse_int &&other) noexcept=default
sparse_int & operator=(const sparse_int &other) noexcept=default
std::array< uint64_t, num_bits > limbs
sparse_int(const sparse_int &other) noexcept=default
uint64_t get_sparse_value() const
sparse_int(sparse_int &&other) noexcept=default
const std::array< uint64_t, num_bits > & get_limbs() const
uint64_t get_value() const
~sparse_int() noexcept=default
sparse_int(const uint64_t input=0)
sparse_int operator+=(const sparse_int &other)
std::string format(Args... args)
const std::vector< MemoryValue > data
constexpr uint64_t map_from_sparse_form(const uint256_t &input)
Decode a sparse-form uint256_t back to a 32-bit value. Extracts the base-adic digits from most-signif...
constexpr uint256_t map_into_sparse_form(const uint64_t input)
Encode a 32-bit value into sparse form: each binary bit of input becomes a digit in the given base....
std::vector< uint64_t > slice_input(const uint256_t &input, const uint64_t base, const size_t num_slices)
Decompose a uint256_t into digits in the given base (least-significant digit first)....
constexpr std::array< uint256_t, num_slices > get_base_powers()
Compute [1, base, base^2, ..., base^(num_slices-1)] as uint256_t values.
std::vector< uint64_t > slice_input_using_variable_bases(const uint256_t &input, const std::vector< uint64_t > &bases)
Decompose a uint256_t using a different base for each digit position (least-significant first)....
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
void throw_or_abort(std::string const &err)