Help: Random number generator keeps generating same sequence of numbers???

Foxhound5366

Honorary Master
Joined
Oct 23, 2014
Messages
11,245
Reaction score
4,970
Location
Big Smoke
Ok, so I thought I'd try rekindle the fun I had at University taking one year in Computer Science, so played around with learning C++ one evening.

Only one snag: my very first C++ program runs like a charm, but it doesn't work like it should! I decided to create a small program to generate six random lottery numbers ... only problem is I ran it three times in a row now, and each time it returned the exact same set of six numbers in the same order!

Can any real programmer here please explain to me in laymans terms what I'm doing wrong with this code? Even better, if you can show me exactly what to do to fix it, that'd be best.

Please don't laugh (too much) at this, I know it's probably messy as hell, but please bear in mind it was my very first program in years (and previously I had been taught Java at University):

Coded and run with 'Start without debugging' in Microsoft Visual Studio Community 2013 Update 4, on a Windows 8.1 laptop.

Code:
#include <iostream>
#include <string>

using namespace std;

int main() 
{
	//Programmed on 16 February 2015 as my second real C++ programme (after 'Hello World' of course!)

	int lottoNums[6];
	string userRequest;

	cout << "WELCOME TO MY SUPER-HONEST LOTTERY" << endl;
	cout << "V1.0 February 2015" << endl;
	cout << endl;
	string userName;
	cout << "Wow, you're looking lucky already! What is your name?" << endl;
	getline(cin, userName);
	while(userName == "") {
		cout << "Come now, don't be so shy, give us a name!" << endl;
		getline(cin, userName);
	}
	cout << endl;
	cout << "Why hello there, " << userName << ", here's to the six numbers that will change your life!" << endl;
	cout << endl;
	cout << "Instructions: Press [ENTER] to draw next ball; type 'exit' to exit." << endl;
	cout << endl;
	for (int i = 0; i < 6; i++)
	{
	
		cout << "And now, for lucky ball number " << i + 1 << "... *drum roll* " << endl;
		lottoNums[i] = (rand() % 48) + 1;
		cout << "Ball result: " << lottoNums[i] << endl;
		if (i == 5) break;
		getline(cin, userRequest);
		if (userRequest == "exit") break;
	}
	if (userRequest == "exit") {
		cout << endl;
		cout << "Sorry to see you go so soon, " << userName << ", better luck next time!" << endl;
	}
	else {
		cout << endl;
		cout << "THAT'S IT! " << userName << ", you're all done." << endl;
		cout << "Send some to me if you win big!" << endl;
		cout << endl;
		cout << "Your final lucky numbers are: | ";
		for (int winningBalls = 0; winningBalls < 6; winningBalls++) {
			cout << lottoNums[winningBalls] << " | ";
		}
	}
	cout << endl;
	cout << endl;
	cout << "Press [ENTER] one last time to exit." << endl;
	cout << endl;
	getline(cin, userRequest);
	return 0;
}



The 'interactive' bits I just built in for some fun, while figuring out how to use the commands in the first place.

Update: It's still repeating exactly the same set of numbers :( Am I using the wrong kind of random number generator??
 
What's usually called a random number generator is actually a pseudo-random number generator. This typically means that you can generate the same random sequence if you provide the "key" to that sequence, referred to as the "seed".

In c++ you have to "seed the random number generator" once, by calling the srand function:

srand(time(NULL));
 
What's usually called a random number generator is actually a pseudo-random number generator. This typically means that you can generate the same random sequence if you provide the "key" to that sequence, referred to as the "seed".

In c++ you have to "seed the random number generator" once, by calling the srand function:

srand(time(NULL));

What he said ^

There are also other ways of creating the seed, but it should be as random as possible.
 
I once used a temperature sensor with 0.1 degree Celcius resolution as my seed for a pseudo-random number generator. The idea being that the temperature should differ by at least 0.1 degree every time you measure it using the temp sensor. This then gives a different seed value every time to the PR-number generator. Worked like a charm to implement encryption algorithms.
 
I once used a temperature sensor with 0.1 degree Celcius resolution as my seed for a pseudo-random number generator. The idea being that the temperature should differ by at least 0.1 degree every time you measure it using the temp sensor. This then gives a different seed value every time to the PR-number generator. Worked like a charm to implement encryption algorithms.

I would think that the chance of hitting the same seed again would be relatively high, no? (1 in 10ish?)
 
What's usually called a random number generator is actually a pseudo-random number generator. This typically means that you can generate the same random sequence if you provide the "key" to that sequence, referred to as the "seed".

In c++ you have to "seed the random number generator" once, by calling the srand function:

srand(time(NULL));

This
 
Thanks for the help guys, but there are two concerns.

1: The first was just for anybody else trying to use the suggested method above, I discovered you need to include this or it won't compile:
#include <time.h>
2: The second bigger issue for me is that while random numbers ARE now consistently generated, they don't appear to be 'truly' random at all ... it looks like the second counter of the internal clock? In other words, it's a bit pointless for a lottery number generator, because all the results for me were in sequential order, and if I generated them quickly enough (because I've currently got my program set up to generate a new number each time the user presses Enter) they'd be in an extremely narrow range (e.g. four consecutive numbers).

Is there really no alternative random number generator (without getting super complicated like the hardware suggestion above)?

If I really had to, I could write something myself but it'd be a serious pain and probably unnecessary. My guess is you'd need some way of storing different kinds of mathematical operations (+ - * and /), then combining those in a sequential way with the seed time generated, and grabbing the last two digits of whatever number is generated. That sounds awfully like re-working the wheel though.

Am I still just implementing this incorrectly?
#include <time.h>
int lottoNums[6];
srand(time(NULL));
lottoNums = (rand() % 48) + 1;


All I want is something that will generate numbers in both directions, up and down the number range, not just sequentially grabbing a few. It feels a bit more random that way, so each selection needs to be a fresh one (with a check I'd write to see if that number has been picked already and then discarding it).
 
Last edited:
Thanks for the help guys, but there are two concerns.

1: The first was just for anybody else trying to use the suggested method above, I discovered you need to include this or it won't compile:

2: The second bigger issue for me is that while random numbers ARE now consistently generated, they don't appear to be 'truly' random at all ... it looks like the second counter of the internal clock? In other words, it's a bit pointless for a lottery number generator, because all the results for me were in sequential order, and if I generated them quickly enough (because I've currently got my program set up to generate a new number each time the user presses Enter) they'd be in an extremely narrow range (e.g. four consecutive numbers).

Is there really no alternative random number generator (without getting super complicated like the hardware suggestion above)?

If I really had to, I could write something myself but it'd be a serious pain and probably unnecessary. My guess is you'd need some way of storing different kinds of mathematical operations (+ - * and /), then combining those in a sequential way with the seed time generated, and grabbing the last two digits of whatever number is generated. That sounds awfully like re-working the wheel though.

Am I still just implementing this incorrectly?


All I want is something that will generate numbers in both directions, up and down the number range, not just sequentially grabbing a few. It feels a bit more random that way, so each selection needs to be a fresh one (with a check I'd write to see if that number has been picked already and then discarding it).

Tsk. Blaming your problem on the weak rand. :p

I think you should repost your full code again. Rand() shouldn't be giving you monotonic numbers (well not with a probability of more than 1 in 32 as an off the cuff estimate).
 
Last edited:
(with a check I'd write to see if that number has been picked already and then discarding it).

No, you can't do that, that introduces a bias and it would then not be random !

It is not easy to produce true random numbers, now you know why they use the balls for the lottery, it is not purely because of the visual effects.

You can always feed random number tables into the system
 
there is no check to avoid generating the same number multiple times in a draw. this is quite likely and I would loop first to populate the int-array with 6 numbers - i.e. generate the number and place it into a keyed set, if the set has 6 numbers you are done.
 
Tsk. Blaming your problem on the weak rand. :p

I think you should repost your full code again. Rand() shouldn't be giving you monotonic numbers (well not with a probability of more than 1 in 32 as an off the cuff estimate).

ROFL ... while chewing thoughtfully on a McDonalds chip, something I read about srand suddenly popped into my mind. The chip and the penny dropped, and I know what I did wrong!

As you can see from the full code example, I'm generating the random numbers in a loop. When I'd initially added srand to set the seed value, I'd placed this into the loop just above where I was generating the random numbers. The thinking at the time was that I'd be resetting the seed value each time, which would be a good thing, but then I remembered reading that one should only ever use srand a single time in a program.

I shifted it out of the loop, like this, and it now works like a charm!

Code:
srand(time(NULL));
	for (int i = 0; i < 6; i++)
	{
	
		cout << "And now, for lucky ball number " << i + 1 << "... *drum roll* " << endl;
		lottoNums[i] = (rand() % 48) + 1;
		cout << "Ball result: " << lottoNums[i] << endl;
		if (i == 5) break;
		getline(cin, userRequest);
		if (userRequest == "exit") break;
	}

I'm going to create a general C++ advice/discussion thread, so if any of you would like to mosey on over there to give your 2c, that'd be awesome :) Click here for the awesomeness
 
Last edited:
Yes, it is very important that you only generate the seed once outside the loop. As I read down the posts I became certain that you were doing it inside the loop and when I reached the bottom, I saw you have fixed it now. I agree, your code is now correct.

My opinion, the system timestamp is the best random seed for normal applications, like generating lotto numbers. It has a wide range and never repeats. But must be done outside any loops at the start of the program, because inside a loop, things are happening so fast that you get the same seed multiple times. For crypto grade randomness, however, you must use the operating system entropy or similar as your random seed/source. Ambient sounds as zippy mentioned, can also make a good entropy source, but in my opinion easiest is just to let the OS take care of that.
 
I did it.Passed and thank GOD I will never return to this headache!!! I am not a programmer!
 
I'm a bit late to the party. For a basic test app rand()/srand was the way to go, BUT as noted they're not really very random.
For the future, if you need better software randomness then look into Boost/Mersenne Twister.
 
Seed the function with the current time microseconds as its very hard to hit that same sequence of numbers.
 
timer = new QTimer(this);
timer->setInterval(100) //ms

They didn't say how fast you must generate the numbers.
If it generates a number based on time, putting any kind of delay in there would stop you from getting the same sequence.
 
timer = new QTimer(this);
timer->setInterval(100) //ms

They didn't say how fast you must generate the numbers.
If it generates a number based on time, putting any kind of delay in there would stop you from getting the same sequence.

This is not correct. You should only seed the random number generator once per application, using something that is very unique. The current timestamp close to the start of the application in microseconds or milliseconds is often pretty unique, so makes a good choice as stated by others. After that you should leave the seed alone. Messing with the seed makes it harder for the random number generator to generate good quality pseudo-random numbers for the duration of the application, since you might accidentally reset it to the same start point if you have a duplicate seed due to some coding bug or other artifact of your application. After you have set the seed, you can generate the numbers as fast as you like. Speed of generating them has no effect.
 
Top
Sign up to the MyBroadband newsletter
X