C++ GMP Generating Random Number

6.6k views Asked by At

I'm trying to generate a huge random number in C++ using the GMP library but am having issues figuring out the syntax. This is slightly different from other examples I've found because I need to set a floor and ceiling for the random number to be between. This is kinda what I need to do:

mpz_class high, low;

low  = pow(2,199);
high = pow(2,210);

// code to use the high and low numbers to generate the random number

I know this isn't much to go on, but again, I'm not sure what the syntax would even be at this point, I've tried several things but nothing I've found enables me to tell GMP to use a high and low range for the number generation.

Thoughts?

2

There are 2 answers

5
Les On BEST ANSWER

From Gmp Lib Documentation

Function: void mpz_urandomb (mpz_t rop, gmp_randstate_t state, mp_bitcnt_t n)

Generate a uniformly distributed random integer in the range 0 to 2^nāˆ’1, inclusive

So, take 210 - 199, and use that as n, generate a random number and add the result to pow(2,199).

If you want something more granular than a power of 2 upper limit, this won't work for you. You could try the unsigned int sized random function using the same technique above:

ā€” Function: unsigned long gmp_urandomm_ui (gmp_randstate_t state, unsigned long n)

Return a uniformly distributed random number in the range 0 to n-1, inclusive.

Here, you would find your granular range and use that for n. Then add the random number to your lower value. The limitation is n must be less than MAXUINT, usually 2^32 -1

1
sadmicrowave On

Using the logic presented by @Less, I wrote the following to solve my problem:

void 
makeprime ()
{
    // *********************** VARIABLE DECLARATION *********************** //
    // initilize the variables as gmp class instances
    mpz_t l, rand;
    unsigned long seed;
    // perform inits to create variable pointers with 0 value
    mpz_inits(l, rand);
    //mpz_init(rand);

    // calculate the random number floor
    mpz_ui_pow_ui(l, 2, 199);

    // initilze the state object for the random generator functions
    gmp_randstate_t rstate;
    // initialize state for a Mersenne Twister algorithm. This algorithm is fast and has good randomness properties.
    gmp_randinit_mt(rstate);

    // create the generator seed for the random engine to reference 
    gmp_randseed_ui(rstate, seed);

    /*
    Function:
    int mpz_probab_prime_p (const mpz_t n, int reps)

    Determine whether n is prime. Return 2 if n is definitely prime, return 1 if n is probably prime (without being certain), 
    or return 0 if n is definitely composite.
    */
    do {
        // return a uniformly distributed random number in the range 0 to n-1, inclusive.
        mpz_urandomb(rand, rstate, 310);

        // add the random number to the low number, which will make sure the random number is between the low and high ranges
        mpz_add(rand, rand, l);

        gmp_printf("randomly generated number: %Zd\n", rand);

    } while ( !(mpz_probab_prime_p(rand, 25)) );        

    // *********************** GARBAGE COLLECTION *********************** //
    // empty the memory location for the random generator state
    gmp_randclear(rstate);
    // clear the memory locations for the variables used to avoid leaks
    mpz_clear(l);
    mpz_clear(rand);
}

Thanks @Less for your logic and help!