What's the Right Way to use the rand() Function in C++? - c++

I'm doing a book exercise that says to write a program that generates psuedorandom numbers. I started off simple with.
#include "std_lib_facilities.h"
int randint()
{
int random = 0;
random = rand();
return random;
}
int main()
{
char input = 0;
cout << "Press any character and enter to generate a random number." << endl;
while (cin >> input)
cout << randint() << endl;
keep_window_open();
}
I noticed that each time the program was run, there would be the same "random" output. So I looked into random number generators and decided to try seeding by including this first in randint().
srand(5355);
Which just generated the same number over and over (I feel stupid now for implementing it.)
So I thought I'd be clever and implement the seed like this.
srand(rand());
This basically just did the same as the program did in the first place but outputted a different set of numbers (which makes sense since the first number generated by rand() is always 41.)
The only thing I could think of to make this more random is to:
Have the user input a number and set that as the seed (which would be easy to implement, but this is a last resort)
OR
Somehow have the seed be set to the computer clock or some other constantly changing number.
Am I in over my head and should I stop now? Is option 2 difficult to implement? Any other ideas?
Thanks in advance.

Option 2 isn't difficult, here you go:
srand(time(NULL));
you'll need to include stdlib.h for srand() and time.h for time().

srand() should only be used once:
int randint()
{
int random = rand();
return random;
}
int main()
{
// To get a unique sequence the random number generator should only be
// seeded once during the life of the application.
// As long as you don't try and start the application mulitple times a second
// you can use time() to get a ever changing seed point that only repeats every
// 60 or so years (assuming 32 bit clock).
srand(time(NULL));
// Comment the above line out if you need to debug with deterministic behavior.
char input = 0;
cout << "Press any character and enter to generate a random number." << endl;
while (cin >> input)
{
cout << randint() << endl;
}
keep_window_open();
}

It is common to seed the random number generator with the current time. Try:
srand(time(NULL));

The problem is that if you don't seed the generator it will seed itself with 0 (as if srand(0) were called). PRNGs are designed to generate the same sequence when seeded the same (due to the fact that PNRGs are not really random, they're deterministic algorithms and maybe a bit because it's quite useful for testing).
When you're trying to seed it with a random number using
srand(rand());
you're in effect doing:
srand(0);
x = rand(); // x will always be the same.
srand(x);
As FigBug mentioned, using the time to seed the generator is commonly used.

I think that the point of these articles is to have a go at implementing the algorithm that is in rand() not how to seed it effectively.
producing (pseudo) random numbers is non trivial and is worth investigating different techniques of generating them. I don't think that simply using rand() is what the authors had in mind.

Related

C++ Password Generator Generates Same Password [duplicate]

In this rather basic C++ code snippet involving random number generation:
include <iostream>
using namespace std;
int main() {
cout << (rand() % 100);
return 0;
}
Why am I always getting an output of 41? I'm trying to get it to output some random number between 0 and 100. Maybe I'm not understanding something about how the rand function works?
You need to change the seed.
int main() {
srand(time(NULL));
cout << (rand() % 101);
return 0;
}
This srand thing also works for C.
See also:
http://xkcd.com/221/
For what its worth you are also only generating numbers between 0 and 99 (inclusive). If you wanted to generate values between 0 and 100 you would need.
rand() % 101
in addition to calling srand() as mentioned by others.
srand() seeds the random number generator. Without a seed, the generator is unable to generate the numbers you are looking for. As long as one's need for random numbers is not security-critical (e.g. any sort of cryptography), common practice is to use the system time as a seed by using the time() function from the <ctime> library as such: srand(time(0)). This will seed the random number generator with the system time expressed as a Unix timestamp (i.e. the number of seconds since the date 1/1/1970). You can then use rand() to generate a pseudo-random number.
Here is a quote from a duplicate question:
The reason is that a random number generated from the rand() function isn't
actually random. It simply is a transformation. Wikipedia gives a better
explanation of the meaning of pseudorandom number generator: deterministic
random bit generator. Every time you call rand() it takes the seed and/or the
last random number(s) generated (the C standard doesn't specify the algorithm
used, though C++11 has facilities for specifying some popular algorithms), runs
a mathematical operation on those numbers, and returns the result. So if the
seed state is the same each time (as it is if you don't call srand with a truly
random number), then you will always get the same 'random' numbers out.
If you want to know more, you can read the following:
http://www.dreamincode.net/forums/topic/24225-random-number-generation-102/
http://www.dreamincode.net/forums/topic/29294-making-pseudo-random-number-generators-more-random/
You are not seeding the number.
Use This:
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
srand(static_cast<unsigned int>(time(0)));
cout << (rand() % 100) << endl;
return 0;
}
You only need to seed it once though. Basically don't seed it every random number.
random functions like borland complier
using namespace std;
int sys_random(int min, int max) {
return (rand() % (max - min+1) + min);
}
void sys_randomize() {
srand(time(0));
}
"srand(time(NULL));" as 1st line at "main()" won't help you if you're using "rand()" at static init. somewhere. You better create "struct rnd_init { rnd_init() { srand (time (nullptr)); } }" named whatever suits you, as a static var at the scope where "rand()" is being used: at some constructor, or whatever.

Clarification on calling srand [duplicate]

This question already has answers here:
How often should I call srand() in a C++ application?
(4 answers)
What does 'seeding' mean?
(4 answers)
Closed 3 years ago.
I'm wondering why it's advantageous to seed srand at the beginning of the program, instead of where I use it.
I generate pseudo-random numbers when seeding srand at the beginning of my program but I get the numbers all the same when I seed srand inside the function I call to generate the numbers
#include <iostream>
#include <ctime>
using namespace std;
int rng()
{
const int SIZE = 10;
int rng[10];
srand(time(NULL));
for (int i = 0; i < 10; i++)
{
rng[i] = rand() % 128 + 1;
return rng[i];
}
}
int main()
{
int array;
//srand(time(NULL)); If i put it here i get actual random numbers
cout << "Welcome to the program";
cout << "\nthis is your rng\n";
for (int i = 0; i < 10; i++)
{
array = rng();
cout << array << endl;
}
return 0;
}
When I run the program all of the numbers are the same, but when I delete the seeding from in the rng function and uncomment the srand in the main module the numbers are pseudo-random which is what I want. Im wondering why though. I've looked into it and heard that im seeding srand with a time and when I run that function the loop iterates so fast that all of the numbers are generated with the same seed value so they're all the same, but I'm wondering what's the difference from that and having srand(time(NULL)) in main because either way doesn't the function generate the numbers so fast they'll be at the same seed value anyway? It doesn't appear that way because of the different output but im curious, why?
time returns number of seconds since 1.1.1970 so calling it repeatedly during one second will indeed return same values. It doesn't matter exactly where you put srand as long as it's before all rand calls and it should only be called once per program as it's global and obviously resets the random sequence. So if you use it only where you need it, you risk that when some other part of the code will need it too and calls srand again, it will interfere with your rand calls. It's not necessary to call it at all but then the seed will always be the same. It's good for debugging to have an option to set the seed deterministicly.
That said, don't use it, just don't.
As you observed time is not a good seed generator and rand is not even good random number generator, certainly not for floats and x mod n. Use <random> library. It has std::random_device which can generate true random numbers = good seeds. Sadly it's not required to. std::mt19937 is go-to RNG which together with std::XX_YY_distributions should be more than enough for everything but the most extreme need for randomness. It's also thread-safe because you control access to the generator and how it's used.

How to output text from a random number

I am extremely new to c++, and I was wondering how I might output text from a random number generator.
I am creating a text game. You occasionally fight things and I wish for whether you win or lose be random. For instance, if the random number is 2 (the only choices it would have would be one or two) then it would say: " You lost!". Please keep answers simple as I am very new and explaining your solution would be perfect.
Thanks in advance.
#include <cstdlib>
#include <iostream>
#include <ctime>
int main()
{
std::srand(std::time(0)); // use current time as seed for random generator
int random_variable = std::rand();
std::cout << "Random value on [0 " << RAND_MAX << "]: "
<< random_variable << '\n';
}
Source: http://en.cppreference.com/w/cpp/numeric/random/rand
Than, you can just compare it with your constant variable and do any action, ex.:
if (random_variable > 2)
doSomething();
else
doSomethingElse();
Since so many usages of rand have been proposed here, let's do it a bit more robust:
We will seed with std::random_device do ease into how <random> works. (You could use time(0) here, it does not really matter.)
Our actual PRNG (the thing that makes numbers) will be [std::mt19937_64](http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine], which is accepted as one of the better random number generators.
We will not simply inspect one bit, but tell C++ that we want a number in the range [0,1].
We will combine this into a single object that you just need to call.
A simple comparision will let us decide whether the player won or lost.
So, starting with number 1:
#include <random>
#include <functional>
#include <iostream>
int main() {
using namespace std; // because I am lazy today
random_device seeder; // call this to get a number
// more to do here
}
Now, while seeder() gives a random number, it is usually expected that you will just use this to seed your own PRNG (unless you do crypto, in which case it becomes much more complicated). So, let's do it:
mt19937_64 prng(seeder());
Well, that was easy. Now, let's make a distribution:
uniform_int_distribution<int> distribution(0, 1);
Now, to get an int that is either 0 or 1, we could just toss the prng to the distribution, as in:
int one_or_zero = distribution(prng);
But, that is cumbersome. So instead of the previous steps, we just combine everything:
auto dist = bind(uniform_int_distribution<int>(0, 1), mt19937_64(seeder()));
You can read this as "Make me a function-like variable named dist which holds a uniform distribution (every value is as likely as any other) of the range [0, 1] that is powered by an Mersenne Twister 64 PRNG.
All we now need to do is:
int one_or_zero = dist();
Ok, we just need to wrap a little if around a call to dist - sounds easy:
if(dist() == 0) {
cout << "You won!\n";
} else {
cout << "Sorry, you lost.\n";
}
You can see the result in action here, but be aware that the result is cached, so you'll need to fork it and run it yourself to see it change.
P.S.: Please note that it results in exactly two lines with the semantics similar to (swap it around a bit and you get exactly the same semantics) srand/rand -- except that it avoids a whole bunch of problems associated with those functions.
#include<iostream>
using namespace std;
int main()
{int ran_num=0;
srand((unsigned)time(0));
while(ran_num !=2) //You can add options here.
{ran_num=rand() % 100;//You can change the max number.
cout<<ran_num<<" "<<endl;
}
cout<<"You lost!";}
Since your random out has only two states, you can think about it as flipping a coin, so you can take a random function and perform a modular division by 2, like this example (just look for 'coin toss' and you will get tons of samples):
http://www.c-program-example.com/2012/05/c-program-to-toss-coin-using-random.html
int toss = rand() % 2;
you can use toss to manage your chooses.
If there are only two options, the fastest way is to be interested only in value of the least significant bit.
if(randomNumber & 1) // equals 1 if the LSB is set.
cout << "You won!" << endl;
else
cout << "You lost!" << endl;

random_shuffle produces same results every time

Im trying to shuffle a deck of cards but random_shuffle produces the same result every time
void
Deck::shuffle() {
cout << "SHUFFLING CARDS!!!\n\n";
srand(time(0));
random_shuffle(cards.begin(), cards.end());
displayCards();
}
That's because you seed pseudo-random number generator to the same value each time:
srand(time(0));
The granularity of time are seconds, if I'm not mistaken. If you pause the execution for some time between calls to Deck::shuffle() you should see different results.
Remove that line from the function and call it once at the start of your program.
I think that the problem is because you are putting srand(...) inside of your function.
Try to move it outside (so that it will be executed only once)
You are reseeding the random number generator each time you call shuffle.
You should only seed the random number generator once per application (typically in your application initialization):
int main()
{
// other initialization
srand(time(NULL)); // seed the number generator
// ...
}
It is important to know that to be able to receive a "random" number you have to seed the generator. Also it should be seeded outside the function.
srand(time(NULL));
The use of the time function will help ensure that you will receive a random number.
time.h does need to be included for it to work. For more reference on srand, click here.
I'm not familiar with random_shuffle, but here's a function that does a perfect shuffle - in other words, each 52! permutations of the deck has to be equally likely.
This is from Gayle Laakmann's Cracking the Coding Interview (Question 20.2)
void Deck::shuffle() {
int temp, index;
for (int i = 0; i < cards.size(); i++){
index = (int) (rand() %(cards.size() - i)) + i;
temp = cards[i];
cards[i] = cards[index];
cards[index] = temp;
}
}

A random number generator that can get different numbers in < a second

I'm in need of a C++ (pseudo, i don't care) random number generator that can get me different numbers every time I call the function. This could be simply the way I seed it, maybe there's a better method, but every random generator I've got doesn't generate a new number every time it's called. I've got a need to get several random numbers per second on occasion, and any RNG i plug in tends to get the same number several times in a row.
Of course, I know why, because it's seeded by the second, so it only generates a new number every second, but I need to, somehow, get a new number on every call. Can anyone point me in the right direction?
Sounds like you do it like this:
int get_rand() {
srand(time(0));
return rand();
}
Which would explain why you get the same number within one second. But you have to do it like this:
int get_rand() {
return rand();
}
And call srand once at program startup.
You only need to seed the generator once with srand() when you start, after that just call the rand() function. If you seed the generator twice with the same seed, you'll get the same value back each time.
You should only seed the PRNG once.
Boost.Random has a variety of pretty good random number generators.
If you're generating a large number of random numbers, you could try an XORShift generator. For longs (8 bit):
// initial setup
unsigned long x = ... init from time etc ...
// each time we want a random number in 'x':
x ^= x << 21;
x ^= x >> 35;
x ^= x << 4;
This code generates a unique random number only once.
#include <ctime>
# include <iostream>
using namespace std;
int main()
{
int size=100;
int random_once[100];
srand(time(0));
for (int i=0;i<size;i++) // generate unique random number only once
{
random_once[i]=rand() % size;
for(int j=0;j<i;j++) if (random_once[j]==random_once[i]) i--;
}
for ( i=0;i<size;i++) cout<<" "<<random_once[i]<<"\t";
return 0;