-1

I need to generate a large number of random multiprecision ints (boost mpx_int) of various bits. My current approach is based on these two examples: boost multiprecision random, constexpr array. To generate a random number this way I need the number of bits as a constexpr. I can generate an array of constexpr ints, but then I get stuck because I cannot access them from within a for loop.

Code example:

#include <boost/multiprecision/cpp_int.hpp>
#include <boost/random.hpp>
#include <iostream>

using namespace std;
using namespace boost::multiprecision;
using namespace boost::random;

template <int bit_limit>
struct N_bit_nums
{
    constexpr N_bit_nums() : bits{}
    {
        for (int i = 0; i < bit_limit; ++i)
        {
            bits[i] = i + 1;
        }
    }

    int bits[bit_limit];
};

int main()
{
    constexpr int bit_limit = 3; // this will actually be on the order of 10^6
    constexpr N_bit_nums<bit_limit> n_bit_nums{};

    for (int i = 0; i < bit_limit; ++i)
    {
        independent_bits_engine<mt19937, n_bit_nums.bits[i], cpp_int> generator; // error: the value of ‘i’ is not usable in a constant expression
        cpp_int rand_num = generator();
        cout << rand_num << "\n"; // just to see what is going on while testing
    }

    return 0;
}
ryn1x
  • 1,052
  • 2
  • 8
  • 19
  • why do you go through the hassle of templating this. Just get it to work first. And remember, there will be one version of the templated code per bit_limit. Do you really want a million copies of your code ? – Jeffrey Aug 19 '20 at 02:37
  • Using template was a way I found to create an array of constexpr ints based on https://stackoverflow.com/questions/19019252/create-n-element-constexpr-array-in-c11. I am here to learn how I can solve this problem in any way, not necessarily the approach I am attempting at the moment. – ryn1x Aug 19 '20 at 03:01
  • Why do you need the number of bits as a constexpr? – Jeffrey Aug 19 '20 at 03:02
  • it is required by boost::random::independent_bits_engine – ryn1x Aug 19 '20 at 03:08
  • example from boost docs: https://www.boost.org/doc/libs/1_73_0/libs/multiprecision/doc/html/boost_multiprecision/tut/random.html – ryn1x Aug 19 '20 at 03:22
  • Why do you need 10^6 different random number generators? – n. m. could be an AI Aug 19 '20 at 05:37
  • Is there another way to change the bit size of the randomly generated number? Maybe I should always generate numbers at the largest bit size I need and then grab the needed number of bits from that? – ryn1x Aug 19 '20 at 14:58
  • the number of bits in independent_bits_engine is fixed at compile time and cannot be changed. Engines with different number of bits are different objects of different types. Perhaps you want a uniform_int_distribution instead. – n. m. could be an AI Aug 19 '20 at 15:43

1 Answers1

0

I was able to accomplish this by fixing the independent_bits_engine to the largest amount of bits needed and then masking to the number of bits required.

Example:

#include <boost/multiprecision/cpp_int.hpp>
#include <boost/random.hpp>
#include <iostream>

using namespace std;
using namespace boost::multiprecision;
using namespace boost::random;

int main()
{
    constexpr int bit_limit = 100;
    independent_bits_engine<mt19937, bit_limit, cpp_int> generator;

    // prints random numbers of bit sizes from 1 to bit_limit
    for (int n = 1; n <= bit_limit; n++)
    {
        cpp_int rand_num = generator();              // next random value
        cpp_int n_bit_mask = pow(cpp_int{2}, n) - 1; // n bits mask
        cpp_int n_bit_num = rand_num & n_bit_mask;   // take n lsb
        cout << n_bit_num << "\n";                   // print the n bit random number
    }

    return 0;
}
ryn1x
  • 1,052
  • 2
  • 8
  • 19