Why Is Rand() Not Producing Random Numbers

rand() not generating random numbers after modulo operation

You need to realize that rand() is a pseudorandom number generator, and it is specifically engineered to return the same sequence of numbers for a given seed. The seed is set with the srand() function.

srand(0);
printf("the first rand() with seed 0 is %d\n", rand());
srand(1);
printf("the first rand() with seed 1 is %d\n", rand());
srand(0);
printf("the first rand() with seed 0 is still %d\n", rand());

So, the way to make it less predictable is generally to re-seed it from something a bit more random, or at least from something that is not the same every time you run the program:

srand(time(NULL));

C rand() function is not generating random numbers

You need to "seed" the random number generator.
Try calling

srand(time(NULL));

once at the top of your program.

(There are better ways, but this should get you started.)

rand() not generating random numbers even after srand(time(NULL))

You must call srand() once, whereas you call it on every entry into generateWeight(). Since nowadays computers are fast and time() returns the time in seconds, this mostly restarts the random number generator from the same seed.

rand() function not generating enough random

This has no business being in this function:

srand(time(0));

This should be called once at the beginning of your program (a good place is just inside main()); and most-certainly not in your display routine. Once the seed is set, you should never do it again for your process unless you want to repeat a prior sequence (which by the looks of it, you don't).

That said, I would strongly advise using the functionality in <random> that comes with your C++11 standard library. With it you can establish distributions (ex: uniform_int_distribution<>) that will do much of your modulo work for you, and correctly account for the problems such things can encounter (Andon pointed out one regarding likeliness of certain numbers based on the modulus).

Spend some time with <random>. Its worth it. An example that uses the three ranges you're using:

#include <iostream>
#include <random>
using namespace std;

int main()
{
std::random_device rd;
std::default_random_engine rng(rd());

// our distributions.
std::uniform_int_distribution<> dist1(50,60);
std::uniform_int_distribution<> dist2(200,300);
std::uniform_int_distribution<> dist3(0,100);

for (int i=0;i<10;++i)
std::cout << dist1(rng) << ',' << dist2(rng) << ',' << dist3(rng) << std::endl;

return EXIT_SUCCESS;
}

Output (obviously varies).

58,292,70
56,233,41
57,273,98
52,204,8
50,284,43
51,292,48
53,220,42
54,281,64
50,290,51
53,220,7

Yeah, it really is just that simple. Like I said, that library is this cat's pajamas. There are many more things it offers, including random normal distributions, different engine backends, etc. I highly encourage you to check into it.

srand doesn't help me creating random numbers

You are likely having a problem with the call to srand.
Your program runs the shuffle_cards function more than once within one second.
This means that the timestamp you feed to srand in srand(time(NULL)); is the same on more than one call.

Two different initializations with the same seed will generate the same succession of results in subsequent calls to rand.

Thus both times the rand() call will generate the same index1 and index2 numbers as in the first call of the shuffle_cards function.

The solution is to not call srand or to call it once, for example when the program starts, or to call it less often.

rand() not giving me a random number (even when srand() is used)

That is what you get for using deprecated random number generation.

rand produces a fixed sequence of numbers (which by itself is fine), and does that very, very badly.

You tell rand via srand where in the sequence to start. Since your "starting point" (called seed btw) depends on the number of seconds since 1.1.1970 0:00:00 UTC, your output is obviously time depended.

The correct way to do what you want to do is using the C++11 <random> library. In your concrete example, this would look somewhat like this:

std::mt19937 rng (std::random_device{}());
std::uniform_int_distribution<> dist (0, 409);

auto random_number = dist(rng);

For more information on the evils of rand and the advantages of <random> have a look at this.

As a last remark, seeding std::mt19937 like I did above is not quite optimal because the MT's state space is much larger than the 32 bit you get out of a single call to std::random_device{}(). This is not a problem for toy programs and your standard school assignments, but for reference: Here is my take at seeding the MT's entire state space, plus some helpful suggestions in the answers.

C rand() is not really random

rand generates a pseudo-random number, yes. But you can set the seed.

srand(time(NULL));
int rand_num = rand() % 100;

Set the seed only once.

Or you can use one of the methods from <random>.

Why is RAND() not producing random numbers?

RAND (Transact SQL):

Returns a pseudo-random float value from 0 through 1, exclusive.

And:

Repetitive calls of RAND() with the same seed value return the same results.

(emphasis mine)

rand() not giving random numbers depending on modulo in xcode

I noticed the same behavior with the code shown in the question:

rand() % 7    // always shows 6
rand() % 14 // always shows 6 or 13
rand() % 21 // always shows 6, 13, or 20

The problem is peculiar and there seems to be a pattern involved. Based on the comments that some aren't able to reproduce it, I decided to compile the code, with gcc on a Linux based machine and clang on macOS; Linux seems to behave normally from what I can tell, however macOS does not. I even tried completely different code just make sure it wasn't something else, yet got the same result.

#include <cstdlib>
#include <iostream>
#include <ctime>

int main()
{
int min = 1;
int max = 7;

std::srand(std::time(0)); // use current time as seed for random generator
// int random_variable = std::rand() % max; // always returns 6
// int random_variable = std::rand() % (max - min) + min; // produces 'predictable' numbers based on the time.
int random_variable = RAND_MAX % std::rand() % (max-min) + min; // also returns predicate results based on the timing, except in reverse.

std::cout << "Random value on [0 " << RAND_MAX << "]: "
<< random_variable << '\n';
}

The only way I was able to get seemingly random results from rand() was to do:

RAND_MAX % std::rand() % (max-min) + min; // predictable based on timing

The issue is odd, and might be a bug with Clang; I'm at a loss at to what exactly is at play here. I would probably recommend using something other than rand() such as the <random> library mentioned in the comments perhaps.

EDIT: After reporting this bug to Apple this was the response:

Apple Developer Relations July 27 2017, 11:27 AM

There are no plans to address this based on the following:

std::rand directly uses rand from the C library. rand is known and
documented to be broken (and is not going to change since people
depend on its specific behavior).

From the man page: RAND(3) BSD Library Functions Manual

NAME
rand, rand_r, srand, sranddev -- bad random number generator

DESCRIPTION
These interfaces are obsoleted by arc4random(3).

For good pseudorandom numbers in C++, look at from C++11.
E.g.: http://en.cppreference.com/w/cpp/numeric/random

Based on this information RAND() is broken and won't be fixed — use an alternative random number generator.



Related Topics



Leave a reply



Submit