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.
Related
I like to learn by screwing around with code, recently I copied and pasted a random number generator code. Then I removed all the lines of code that were not "necessary" to make the executable work to generate a random number. The final straw was me deleting "time" from srand.
srand((unsigned) time(0));
What is the point of "time(0)" here?
Does it use the time that the program is opened to generate the seed for the random number? Is that why removing it (time) makes it not work? Because then it doesn't have a seed?
Also...
include <stdlib.h>
include <stdio.h>
include <time.h>
int main()
{
srand((unsigned) time(0));
printf("Your dice has been rolled! You got:");
int result = 1 + (rand() % 20);
printf("%d", result);
}
that's the whole code and I noticed it used the "rand" result for output. Does the "rand" pull the seed from "srand"?
If you don’t “seed” the random number generator (or if you use the same seed value), you’ll get the same set of pseudorandom numbers.
Using the current time is an easy way to get a different seed every time.
The effect of srand cannot cross threads, so the random number seed should be set once on each thread. #Buddy said that using time(0) is the most convenient way to do this, and each call will get a different seed.Of course you can use an atomic variable .
std::atomic<int> seek(2374213); //init whatever you like
void thread1fun()
{
srand(++seek);
//...
int rand_num = rand();
}
void thread2fun()
{
srand(++seek);
//...
int rand_num = rand();
}
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.
This question already has answers here:
C++ generating random numbers
(11 answers)
Closed 8 years ago.
I'm sorry if this is kind of a dumb question, but I'm new to c++, and honestly can't find the answer;
When I use rand(), of course I have to first use srand().
At first i'd just import <ctime> and do srand(time()), and this worked. But if I called rand() more than once a second - how often time() changes - then I'd get the same answer. So for instance;
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
bool x = true;
while(x == true)
{
int num = 1;
srand(time(NULL));
num = rand();
cout<<num%10<<endl;
}
}
Might produce something like, 6666666666777777777700000000003333333333
Which is no good for my purposes - I'd prefer something like 163509284749301935766.
You should only seed the random number generator once. Right now you are seeding it in the loop and using time(NULL) just means the seed changes once per second which gives you the bad output you have described.
DO this instead:
int main()
{
bool x = true;
int num = 1;
srand(time(NULL));
while(x == true)
{
num = rand();
cout<<num%10<<endl;
}
}
And if you really care about the random numbers generated you might want to use something other than rand(). The reason is that rand() has poor statistical properties for pseudo random number generation, it is often implemented as a Linear congruential generator. If you need high quality randomness then you should prefer something else such as the new c++ random number generators http://en.cppreference.com/w/cpp/numeric/random.
In fact there's even a report on depreciating the old rand() to try to push people to use the newer c++ standard library random functions.
In this particular case you take a modulus which causes a few subtle problems:
num = rand();
cout<<num%10<<endl;
Even if rand() was perfect if the modulus here isn't a divisor of the maximum value returned by rand() you will get a non-uniform distribution as a result. Here's a quick explanation, say rand() returned values in the range of [0,25] then taking the modulus would do the following.
before after modulus
[0-9] [0-9]
[10-19] [0-9]
[20-25] [0-5]
You'll see that you are more likely to get [0-5] than [6-9] which means you now no longer have a uniform number being generated. Note that this small range is for educational purposes only, the maximum value of rand() is mandated by the standard to be at least 32767. However it illustrates an important point, the larger the maximum generated number the better.
This uniformity of distribution problem aside the modulus has the particularly insidious effect of decreasing the quality of the pseudo-randomness even further for some implementations.
Using std::uniform_int_distribution avoids many problems so I would recommend changing your existing code to use the new library. Doing so would look like this:
#include <iostream>
#include <random>
using namespace std;
int main()
{
std::default_random_engine generator;
generator.seed( /* your seed for the RNG goes here */ );
std::uniform_int_distribution<int> distribution(0,9);//note the min and max parameters are inclusive here
while(true)
{
cout << distribution(generator) << endl;
}
}
A function f() that would generate random numbers in range [low,high] can be easily, robustly and safely defined with c++11 library facilities :
#include <random>
#include <iostream>
int f(int low, int high)
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(low, high);
return dis(gen);
}
std::uniform_int_distribution will give you a random number in your range (eg (0,9) ) this way
On the rationale behind refraining from using the old rand you can check this
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.
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;