[C++] How to generate random number?

Status
Not open for further replies.
Level 25
Joined
May 11, 2007
Messages
4,650
http://www.cplusplus.com/reference/cstdlib/rand/
"v1 = rand() % 100; // v1 in the range 0 to 99
v2 = rand() % 100 + 1; // v2 in the range 1 to 100
v3 = rand() % 30 + 1985; // v3 in the range 1985-2014"

/* rand example: guess the number */
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */

int main ()
{
int iSecret, iGuess;

/* initialize random seed: */
srand (time(NULL));

/* generate secret number between 1 and 10: */
iSecret = rand() % 10 + 1;

do {
printf ("Guess the number (1 to 10): ");
scanf ("%d",&iGuess);
if (iSecret<iGuess) puts ("The secret number is lower");
else if (iSecret>iGuess) puts ("The secret number is higher");
} while (iSecret!=iGuess);

puts ("Congratulations!");
return 0;
}

Maybe you forgot to seed it or gave it a too low number input?
 

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
srand (time(NULL));
it causes compile error for me :/ it says time identifier not found..

EDIT:
I forgot to include time.h but it still returns same value each time I call it? :/

here is my function
Code:
int RandomPrime()
{
	srand(time(NULL));
	int i = rand() % upperBound;
	while (i < lowerBound)
		i = rand() % upperBound;
	while (!IsPrime(i))
	{
		i = rand() % upperBound;
		while (i < lowerBound)
			i = rand() % upperBound;
	}
	return i;
}

please help D:
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
Don't call srand each time, call it once when the program starts.

To remove those ugly loops, use:
C++:
i = lowerBound + rand() % (upperBound - lowerBound + 1);

As to the function in general, what are the values of upper and lower bounds? how does IsPrime work?

And if what you want is a prime, a much better way would probably be to generate an array of primes once, and select a random index every time you want one.
 

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
Don't call srand each time, call it once when the program starts.
okay, I will try it.

To remove those ugly loops, use:
check

As to the function in general, what are the values of upper and lower bounds? how does IsPrime work?
upperbound is 800 lower bound is 100. IsPrime works correctly, here is the code ;)
Code:
bool IsPrime(int n)
{
	for(int i = 2; i < n; i++)
		if (n%i == 0)
			return false;
	return true;
}

And if what you want is a prime, a much better way would probably be to generate an array of primes once, and select a random index every time you want one.
you are right sir! but I only need random prime twice, again it's problem about memory wise or speed wise :p


Oh my, it's working correctly now, but why the result is not so randomized? first call always return 103, and the second call always return 101. And it always happen in the next tests too :/ any solution for this? For better idea, I'm working on RSA encrypting, so I need 2 prime, is that better use random prime or what? thanks!
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
Pseudo random generators (like rand) will always return the same sequence of values given the same seed. If you indeed get the same values on every run, then the seed never changes.
You set the seed with srand, and people generally use time(NULL) as the seed since that returns an integer representation of the current computer time, which keeps changing.
You can start to debug this by printf'ing your seed.
Also possibly show us your current source.

And yes, you need to select random numbers by definition for RSA (of course a real world code would use primes quite a big bigger, but you already know that).
 
Generate primes with the Sieve of Eratosthenes and select a random one.

srand and rand are okay for simple programs like these, but if you need better tools, you should look into C++11's <random> library. rand is not thread-safe, so in a multi-threaded environment, you're going to fuck yourself up.

BUT, I doubt you're doing anything that uses multiple threads, so you'll be fine for now.

It's still a good thing to look into, because the <random> library provides support for things like Bernoulli distributions, Poisson distributions, you know, that sort of shit. It also gives you access to several different classes of random number generation algorithms. The most popular one is std::mt19937 (Mersenne Twister).

It's designed in terms of 3 things:

  • Random number generators (std::random_device)
  • Random number engines (std::mt19937 is a popular example)
  • Distributions (std::uniform_real_distribution, std::exponential_distribution, std::binomial_distribution, etc...)

The random number generators are layers of abstraction used for the purpose of things like hardware random number generators. These things rely on quantum events like radioactive decay to generate random numbers. In most implementations, you're just going to find dead code that returns something silly like 32. The only real purpose these things serve for most software is generating the seed for an engine. They were made to "generate a pseudo or real random number from an external source".

The engines are random number generators that work with distributions. These things generate a sequence of numbers to satisfy a distribution.

A distribution has an interval. A uniform distribution represents, you guessed it, a uniform distribution. You can use it in conjunction with a seeded engine to have it generating numbers uniformly across an interval.

Here's an example:

C++:
int random_int_between_zero_and_ten() {
    std::random_device device;
    std::mt19937 engine(device()); // seeding the engine.
    std::uniform_int_distribution<int> dist(0, 10); // define a uniform distribution for numbers between 0 and 10
    return dist(engine); // Passing the engine to the distribution's operator() will generate your number.
}
 
Last edited:
Status
Not open for further replies.
Top