srand(time(NULL)) generating similar results [duplicate] - c++

This question already has answers here:
rand() function in C is not random even when seeded
(2 answers)
Closed 6 years ago.
I don't understand why srand() generates so similar random numbers between runs!
I am trying to run the following code
srand ( time(NULL) );
int x = rand();
cout << x << endl;
However instead of a proper random number I always end up with almost the same number, which is growing slowly as the time goes. So I get numbers like: 11669, 11685, 11701, 11714, 11731.
What am I doing wrong?
I am using Visual Studio 2010 SP1.
OK, is srand() really that simple? I mean how would anyone call it a random function?
srand(1) => rand() = 41
srand(2) => rand() = 45
srand(3) => rand() = 48
srand(4) => rand() = 51
....

First, srand() isn't a random function; it sets up the starting point
of a pseudo-random sequence. And somewhat surprisingly, your
implementation of rand() seems to be returning a value based on the
previous state, and not on the newly calculated state, so that the first
value after a call to srand() depends very much on the value passed to
srand(). If you were to write:
srand( time( NULL ) );
rand();
std::cout << rand() << std::endl;
, I'm sure you'll see a lot more difference.
FWIW: I tried the following on both Windows and Linux:
int
main()
{
srand( time( NULL ) );
int r1 = rand();
std::cout << r1 << ' ' << rand() << std::endl;
return 0;
}
Invoked 10 times at a one second interval, I got:
16391 14979
16394 25727
16397 3708
16404 25205
16407 3185
16410 13933
16417 2662
16420 13411
16427 2139
with VC++ under Windows—you'll note the very low variance of the
first call to rand()—and
1256800221 286343522
955907524 101665620
1731118607 991002476
1428701871 807009391
44395298 1688573463
817243457 1506183315
507034261 1310184381
1278902902 54648487
2049484769 942368151
1749966544 1833343137
with g++ under Windows; in this case, even the first value read is
relatively random.
If you need a good random generator, you'll probably have to use one
from Boost; the standard doesn't say much about what algorithm should be
used, and implementations have varied enormously in quality.

Make sure you're doing
srand ( time(NULL) );
while(condition) {
int x = rand();
cout << x << endl;
}
and not
while(condition) {
srand ( time(NULL) );
int x = rand();
cout << x << endl;
}
The first way the seed is changed every iteration. The second way you are performing the random function on a very similar seed each iteration (because time doesn't change much).

If you are trying to run the program quickly in succession and get different random numbers each time, initializing with the current time is the wrong approach. What you need is a source of entropy; this question might get you started. Replacing time(NULL) with QueryPerformanceCounter() might be a good start, since it updates much more rapidly, but it's still somewhat predicatble - I don't know if that's important to you or not.

Since you have Visual Studio 2010, you can use the portable random device interface from modern C++ instead of time() to seed srand():
#include <iostream>
#include <random>
#include <cstdlib>
int main()
{
std::random_device rd;
std::srand(rd());
std::cout << std::rand() << '\n';
}
Now running the program repeatedly will still produce different values. The same code will work with GNU g++ on Linux or any other modern compiler.

OK, all credits go for Mark Ransom for his answer for explaining actually what is happening. I did not find source code in his linked question, so I googled it and found this, what is perfectly working on Windows. So for srand on windows, here is the source code to generate better srand() seed.
#include <windows.h>
int main()
{
LARGE_INTEGER cicles;
QueryPerformanceCounter(&cicles);
srand (cicles.QuadPart);
return 0;
}

I just had the same problem. The seeds were too similar even after tens of seconds. Since I get my numbers in this fashion:
int FlRandomInt(int LowerLimit, int UpperLimit)
{
int Result;
Result = rand();
Result=LowerLimit+Result*(UpperLimit-LowerLimit)/RAND_MAX;
return Result;
}
which I know is not the best way to go for integers, but I use the same procedure to generate random floats and doubles, so it's good to verify if those are significantly different, instead of just at the last decimals.
Anyway just wanted to post a solution that works fine for me. It's simply multiplying the time seed by 100:
srand(( unsigned )time( 0 ) * 100 );
Hope it helps, even if I'm sure there are more elegant ways around the problem.

From #James Kanze's test it seems that it is a peculiarity of VC++'s C runtime (though I am certain other libraries suffer in the same way). This library also suffers from having a minimum allowable RAND_MAX, but that's another issue.
The solution to the low variance of the initial value is simply to discard it:
void seed_rand( unsigned int seed )
{
srand( seed ) ;
(void)rand() ;
}
int main()
{
seed_rand( time( NULL ) );
int r1 = rand();
std::cout << r1 << ' ' << rand() << std::endl;
return 0;
}

#include"stdio.h" //rmv coding for randam number access using c++
#include"conio.h"
#include"time.h"
void main()
{
time_t t;
int i;
srand(time(null));
for(i=1;i<=10;i++)
cout<<(unsigned)rand()%100-90<<"\t";
for(i=1;i<=10;i++)
cout<<(char)rand()%100-90<<"\t";
getch();
}

Related

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.

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

I have an array with 7 elements and I'm trying to get a random number between 0 - 6 so I can select an element in the array at random.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
class Color{
public:
Color(){
colors[0] = "red";
colors[1] = "orange";
colors[2] = "yellow";
colors[3] = "green";
colors[4] = "blue";
colors[5] = "indigo";
colors[6] = "violet";
}
void printColors()
{
for (int i = 0; i<sizeof(colors)/sizeof(colors[0]); ++i)
{
cout << colors[i] << endl;
}
}
void printRandomColor()
{
int random_integer = rand() % 7;
cout << random_integer << endl;
}
private:
string colors[7];
};
int main(int argc, const char * argv[]) {
srand( static_cast<unsigned int>(time(0)));
Color colorObject;
colorObject.printRandomColor();
return 0;
}
When I do rand() % 7 I keep getting 6, but if I do rand() % 6 I end up getting random numbers. What gives?
I call srand( static_cast<unsigned int>(time(0))); in my main()
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.
rand() is terrible. rand() % range is worse. Don't use it. Use arc4random_uniform().
#include <iostream>
#include <cstdlib> // Needed for arc4random_uniform()
int main(int argc, char *argv[]) {
// Random number between 0 and 6.
std::cout << arc4random_uniform(7) << std::endl;
}
So in your case:
void printRandomColor()
{
int random_integer = arc4random_uniform(7);
cout << random_integer << endl;
}
If portability is desired, then here is a C++ standard example. To me, it's needlessly more complicated and runs slower, but hey… it's the C++ standard.
#include <iostream>
#include <random> // For std::random_device and std::uniform_int_distribution
int main() {
std::random_device randomizer;
std::uniform_int_distribution<int> distribution(0, 6);
// Random number between 0 and 6.
int random_integer = distribution(randomizer);
std::cout << random_integer << std::endl;
}
I would like to point out, that you are using a Random (Rand) operator, then trying to find out if the result has a Remainder (%), the Result will be the Remainder, which is where your strange math comes from. This is known as the Modulo Operator or Modulus Operator if you desire to Google it, although you should know that it actually has a slightly different name in C#, there is a Post in StackTrace about it Here:
What does the '%' operator mean?
If you open the Calc.exe Windows Program it is listed in Scientific Mode (Alt+2) as Mod.
Specifically, the way % operates is ((x - (x / y)) * y)
The above URL is a direct link to my answer where I point out specifically HOW it differs from standard / complete with a long drawn out example simulating all of the math step by step, the result returns a 0 for % and a 1 for / since the / Operand does roundUp() whilst % does roundDown() from what I've understood in the other Answers in that Post.
Update
I would at least like to have this answer here to provide reference for the Modulo Operator which is mentioned in the title of this question.
I didn't post this specifically as an answer per se, but more as reference material to avoid spam posts in the future.
If this is in fact a discovered bug, then this question is going to be picked apart letter by letter, symbol by symbol, and it's going to assist everybody involved to have this reference material here.
If I didn't know already it was named Modulo/Modulus in most languages, I would wonder what he meant by "Modulo" as he never explains anywhere that the % is named exactly that.
This answer addresses the fact that % uses roundDown() whereas / uses roundUp() complete with a referenced compile-able example written painstakingly in expanded step-by-step longhand which I then converted to C#.
I also would like to reiterate, as I mentioned in the comments, I have zero knowledge about xCode, I am somewhat familiar with C# and have provided this information in the C# context which this question is tagged with.

First random number is always smaller than rest

I happen to notice that in C++ the first random number being called with the std rand() method is most of the time significant smaller than the second one. Concerning the Qt implementation the first one is nearly always several magnitudes smaller.
qsrand(QTime::currentTime().msec());
qDebug() << "qt1: " << qrand();
qDebug() << "qt2: " << qrand();
srand((unsigned int) time(0));
std::cout << "std1: " << rand() << std::endl;
std::cout << "std2: " << rand() << std::endl;
output:
qt1: 7109361
qt2: 1375429742
std1: 871649082
std2: 1820164987
Is this intended, due to error in seeding or a bug?
Also while the qrand() output varies strongly the first rand() output seems to change linearly with time. Just wonder why.
I'm not sure that could be classified as a bug, but it has an explanation. Let's examine the situation:
Look at rand's implementation. You'll see it's just a calculation using the last generated value.
You're seeding using QTime::currentTime().msec(), which is by nature bounded by the small range of values 0..999, but qsrand accepts an uint variable, on the range 0..4294967295.
By combining those two factors, you have a pattern.
Just out of curiosity: try seeding with QTime::currentTime().msec() + 100000000
Now the first value will probably be bigger than the second most of the time.
I wouldn't worry too much. This "pattern" seems to happen only on the first two generated values. After that, everything seems to go back to normal.
EDIT:
To make things more clear, try running the code below. It'll compare the first two generated values to see which one is smaller, using all possible millisecond values (range: 0..999) as the seed:
int totalCalls, leftIsSmaller = 0;
for (totalCalls = 0; totalCalls < 1000; totalCalls++)
{
qsrand(totalCalls);
if (qrand() < qrand())
leftIsSmaller++;
}
qDebug() << (100.0 * leftIsSmaller) / totalCalls;
It will print 94.8, which means 94.8% of the time the first value will be smaller than the second.
Conclusion: when using the current millisecond to seed, you'll see that pattern for the first two values. I did some tests here and the pattern seems to disappear after the second value is generated. My advice: find a "good" value to call qsrand (which should obviously be called only once, at the beginning of your program). A good value should span the whole range of the uint class. Take a look at this other question for some ideas:
Recommended way to initialize srand?
Also, take a look at this:
PCG: A Family of Better Random Number Generators
Neither current Qt nor C standard run-time have a quality randomizer and your test shows. Qt seems to use C run-time for that (this is easy to check but why). If C++ 11 is available in your project, use much better and way more reliable method:
#include <random>
#include <chrono>
auto seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator(seed);
std::uniform_int_distribution<uint> distribution;
uint randomUint = distribution(generator);
There is good video that covers the topic. As noted by commenter user2357112 we can apply different random engines and then different distributions but for my specific use the above worked really well.
Keeping in mind that making judgments about a statistical phenomena based on a small number of samples might be misleading, I decided to run a small experiment. I run the following code:
int main()
{
int i = 0;
int j = 0;
while (i < RAND_MAX)
{
srand(time(NULL));
int r1 = rand();
int r2 = rand();
if (r1 < r2)
++j;
++i;
if (i%10000 == 0) {
printf("%g\n", (float)j / (float)i);
}
}
}
which basically printed the percentage of times the first generated number was smaller than the second. Below you see the plot of that ratio:
and as you can see it actually approaches 0.5 after less than 50 actual new seeds.
As suggested in the comment, we could modify the code to use consecutive seeds every iteration and speed up the convergence:
int main()
{
int i = 0;
int j = 0;
int t = time(NULL);
while (i < RAND_MAX)
{
srand(t);
int r1 = rand();
int r2 = rand();
if (r1 < r2)
++j;
++i;
if (i%10000 == 0) {
printf("%g\n", (float)j / (float)i);
}
++t;
}
}
This gives us:
which stays pretty close to 0.5 as well.
While rand is certainly not the best pseudo random number generator, the claim that it often generates a smaller number during the first run does not seem to be warranted.

error when i give sleep(1000), to make srand() work, in visual C++

i have following program:
srand((unsigned) time(NULL));
for (int w = 0; w < 10; w++) {
int ran_x;
ran_x = rand() % 255;
cout << "nRandom X = " << ran_x << endl;
//some more lines of code
Sleep(1000);
}
I am running it on visual c++ 2008, When I run this program, it doesnt show any errors or warnings. But when I run it, some of the times it runs fine, and some of the times it stops in the middle and gives this error "This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information."
What shall I do? Is it possible to do it with out using Sleep() function and still get randomly generated values. Because if I remove Sleep(1000), it doesnt give any error but it doesnt gives random values either
Obviously you shouldn't have to sleep. Code looks sane to me, as long as you only call srand() once. If you call this entire block of code multiple times intra-second, then time(NULL) will be returning the same second value and srand() will start the pseudo-random number generation at the same number, selecting the same set of 10 subsequent numbers....
Works without any problems with gcc
#include <iostream>
#include <cstdlib>
int main (int argc, char *argv[])
{
srand( time(0) );
for (int w = 0; w < 10; w++)
{
int ran_x = rand() % 255;
std::cout<<"\nRandom X = " << ran_x << std::endl;
sleep(1);
}
return 0;
}
Seems to me your program should work perfectly without the sleep call. In fact seems to work for me on VS2008 perfectly. I believe your problems must be in code that you have removed thinking it irrelevant.
The code snippet you posted is hardly responsible for your application terminating, Sleep or not.
Because if I remove Sleep(1000), it
doesnt give any error but it doesnt
gives random values either.
Well, rand() certainly gives you pseudo-random numbers, although the PRNG implementation might not return random values evenly distributed along the bits of the returned value, i.e. in many implementations, the higher bits are changing more often than the lower bits, which is why your code is a poor choice for selecting a random value between 0 and 255.
In general, I'd recommend switching from your standard library's rand/srand to an implementation like boost's mersenne twister (boost::random), or at least see
http://c-faq.com/lib/randrange.html
What's the content of "some more lines of code"?
<psychic debugging>I bet you have code that there that, directly or indirectly, depends on the random value you generated earlier. This code will likely be a division, or involve setting the length of some container, and borks when the generated random number is 0.</psychic debugging>

What's the Right Way to use the rand() Function in 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.