Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent of this Python random number generator in C++?

Tags:

c++

python

random

Just switch from Python to C++ and I begin to re-write my Python tools in C++ for better understanding, but can't solve this one...

This function will generate range of random numbers, for example "randomRange(12)" may return range of 12 numbers like "823547896545"

Python:

  def randomRange(n):
        range_start = 10**(n-1)
        range_end = (10**n)-1
        return randint(range_start, range_end)

  number = randomRange(12)

C++:

  int n;
  int randomRange(n){
        int range_start = ?
        int range_end = ?
        int result = ?(range_start, range_end);
        return (result);
  };

  int number = randomRange(12);

I can't find equivalent for question marks " ? "

like image 877
NEX Avatar asked Sep 06 '11 18:09

NEX


3 Answers

You'll have trouble getting good randomness with high values of n, but:

#include <math.h>         // for pow()
#include <stdlib.h>       // for drand48()

long randomRange(int n)
{
    // our method needs start and size of the range rather 
    // than start and end.
    long range_start = pow(10,n-1);
    long range_size = pow(10,n)-range_start;
    // we expect the rand48 functions to offer more randomness
    // than the more-well-known rand() function. drand48()
    // gives you a double-precision float in 0.0-1.0, so we 
    // scale up by range_size and and to the start of the range.
    return range_start + long(drand48() * range_size);
};

Here's another approach. On 32-bit platforms, you can only do 9 digits in an int, so we'll make the function return a double, and generate a string of ASCII digits then convert:

#include <math.h>         // for pow()
#include <stdlib.h>       // for atof()

// arbitrary limit
const int MAX_DIGITS = 24;

double randomRange(int n)
{
    char bigNumString[ MAX_DIGITS+1 ];
    if (n > MAX_DIGITS)
    {
        return 0;
    }
    // first digit is 1-9
    bigNumString[0] = "123456789"[rand()%9];
    for (int i = 1; i < n; i++)
    {
        // subsequent digits can be zero
        bigNumString[i] = "0123456789"[rand()%10];
    }
    // terminate the string
    bigNumString[i] = 0;
    // convert it to float
    return atof(bigNumString);
};
like image 105
Russell Borogove Avatar answered Sep 22 '22 19:09

Russell Borogove


You should have a look at the facilities in boost:

http://www.boost.org/doc/libs/1_47_0/doc/html/boost_random/tutorial.html#boost_random.tutorial.generating_integers_in_a_range

There are also similar features in C++11:

http://en.cppreference.com/w/cpp/numeric/random

int randomRange(n)
{
    int range_start = (int)pow(10, n-1);
    int range_end = (int)pow(10, n) - 1;
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dist(range_start, range_end);
    return dist(gen);
}

Note that you can get much better performance by moving all but the dist(gen) into an initialization function which is only called once.

like image 31
Mark Ransom Avatar answered Sep 25 '22 19:09

Mark Ransom


You basically have just rand which you can bend to your will:

int result = (rand() % (range_end - range_start)) + range_start;

To explain, rand() generates a random number across a subset of the integer values. You can use modulo lo limit the range of the numbers, then use your start value to provide an offset.

(Also be sure to seed the random number generator)

Note Rand apparently is a pretty lousy random number generator (I had no idea). See the comments.

like image 40
Doug T. Avatar answered Sep 22 '22 19:09

Doug T.