C++ rand function

So when I called rand() % 4 a hundred times, I got 3 1 3 1 3 1 3 1... all the way. That isn't very random. But when I called rand() % 3, I got truly randomized numbers (3 1 3 2 1 3...). Any help or suggestions will be greatly appreciated.
r u seeding?
> So when I called rand() % 4 a hundred times, I got 3 1 3 1 3 1 3 1... all the way. That isn't very random

rand() % 4 gives the value of the the least significant two bits of the number that was generated; for a linear congruential generator, this is not going to be very random. In almost every implementation of the C library, where the multiplier is a power of two, this is not going to be random at all.

A further problem of LCGs is that the lower-order bits of the generated sequence have a far shorter period than the sequence as a whole if m is set to a power of 2. ... The low-order bits of LCGs when m is a power of 2 should never be relied on for any degree of randomness whatsoever...
http://en.wikipedia.org/wiki/Linear_congruential_generator#Advantages_and_disadvantages_of_LCGs

In short, do not rely on std::rand()%N to yield pseudo random values in the range 1 to N-1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <random>
#include <ctime>

// generate a pseudo random int uniformly distributed in the inclusive range 0 - (n-1)
int random_1998( int n ) // invariant: std::srand() has been called
{
    int r = n ;
    do  r = ( std::rand() / double(RAND_MAX) ) * n ; while( r == n ) ;
    return r ;
}

// generate a pseudo random int uniformly distributed in the inclusive range 0 - (n-1)
int random_2011( int n )
{
    static std::mt19937 generator( std::time(0) ) ;
    std::uniform_int_distribution<> distribution( 0, n-1 ) ;
    return distribution(generator) ;
}
Last edited on
Here is the randomization code that I use (assuming that you are using namespace std;):

1
2
srand(time(NULL));      //Gives rand() a seed....  In a way.
rand() % 100 + 1; 


- Kyle
In almost every implementation of the C library, where the multiplier is a power of two, this is not going to be random at all.


Huh? Why would a rng use a multiple of 2 for it's multiplier. That doesn't make any sense. You're supposed to use primes.


EDIT: unless I misunderstood what you meant by multiplier.

EDIT2:

Anyway if you want a simple and decent rng that isn't rand... this is one I use every once in a while:

1
2
3
4
5
6
7
8
9
10
11
12
uint32_t state = (uint32_t)time(nullptr);

void my_srand(uint32_t seed)
{
  state = seed;
}

uint32_t my_rand()
{
  state = (69069*state) + 362437;
  return state;
}
Last edited on
> Why would a rng use a multiple of 2 for it's multiplier
> unless I misunderstood what you meant by multiplier.


My mistake - I was the one who misunderstood. Mixed up the modulus with the multiplier. Thanks.
Last edited on
Topic archived. No new replies allowed.