This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Filling an array with random numbers from 1 to 10^10 in C or C++
Hello,
Simple question; I am looking for a way to get a higher random value than rand() gives me. rand() gives 32767 max. (http://msdn.microsoft.com/en-us/library/398ax69y%28v=vs.80%29.aspx)
I've tried redefining RAND_MAX, but I guess the compiler dosn't accept redefining, because it's within the same boundary as default.
I basically want a random value that fits in an unsigned integer (generating a SSRC number in an RTP packet). I really don't want collisions!
Is there any better win32 function than rand()?
Thanks in advance
Yes -- RAND_MAX is just telling you the maximum that's designed into the generator. Changing it doesn't affect how the generator works.
The easiest way to get a 32-bit value from it is probably to call rand() twice in a row, and and put the two values together:
unsigned SSRC = rand() | rand << 16;
One typical way of seeding rand() is with time:
srand((unsigned)time(NULL));
For an SSRC, you do not want to do this -- time typically only has one-second granularity, so this would (almost) guarantee that any two processes started close to the same time would cause collisions.
In reality, randomness doesn't matter nearly as much as uniqueness. Another possibility would be (for example) to take your machine's IP address, the process ID, and the time and XOR the three together. The result isn't particularly random at all, but is sufficiently unique for this kind of task.
Use Boost.Random (which is also available as <random> if you have VC++ 2010). Note that this will become a built-in part of the C++ Standard in the near future.
There are some good examples on the Boost site, including Generating integers in a range.
How about rand()<<15 + rand() ? It can be as big as you want.
Changing RAND_MAX is not going to change the behavior of the rand() function, which is defined in the C runtime; it's just a convenient macro for you to know the range of output produced by rand().
If you want high-quality random numbers suitable for use with cryptography, use CryptGenRandom; see the full example at the bottom under Community Content for how to use it.
Related
In my CPP system whenever I generate a random number using rand() I always get a value between 0-32k while in some online videos and codes it is generating a value between 0-INT_MAX. I know it is dependent on RAND_MAX. So it there some way to change this value such that generated random number are of the range 0-INT_MAX
Thanks in advance for the help :)
#include<bits/stdc++.h>
using namespace std;
int main(){
srand(time(NULL));
for(int i=1;i<=10;i++){
cout << rand() << endl;
}
}
I used this code and the random number generated are
5594
27457
5076
5621
31096
14572
1415
25601
3110
22442
While the same code on online compiler gives
928364519
654230200
161024542
1580424748
35757021
1053491036
1968560769
1149314029
524600584
2043083516
Yes. Don't use rand(). There are many reasons to not use rand(), not the least of which is that it is one of the two worst random number generators ever widely distributed. (The other is RANDU.) Don't use rand(). Ever.
Look for random() and arc4random() on your system. If you don't find those, then use the PCG source code here.
rand() is a very old function, going back to the earliest days of C. In those early days, an INT_MAX of 32k was common and well justified. Surely it's easy to see that RAND_MAX > INT_MAX doesn't make any sense.
As for why some compilers have updated their RAND_MAX in the intervening years and some have not, I would guess that it's down to a commitment to backwards compatibility. I know that I've been personally bitten by the 32k limit in Microsoft's compiler. But Microsoft has long been a champion of backwards compatibility, so I'll forgive them on this one.
Since C++11 there's a bunch of new random number functions that have been introduced. They're better than the old rand() in almost every way, except perhaps for ease of use.
I'm implementing an algorithm. Because calculations takes time, and I need to repeat them multiple times, I'm saving to output file seed values as well. The idea was that I could repeat same instance of a program if I'll need to get more info about what was happening (like additional values, some percentage, anything that will not mess in the algorithm itself).
Unfortunately, even though I thought everything worked as intended, about 20% of the seeded instances gave different values in at least one of the outputted values.
My question is - what type of changes in the code affects how srand() / rand() works in C++? Each class is compiled separately and all are linked together at the end. Can I implement functions and everything will be fine? Does it break only when I change the size of any class in the program by adding/removing class fields? Is it connected with heap/stack allocation?
Until now, I thought that if I seed srand() I will have same order of rand() values no matter what (eg. for srand(123) I'll always get first rand() == 5, second rand() == 8 etc.). And I can break it only when I'll put more rand() calls in between.
I hope you could find where I'm thinking wrong, or you could link something that will help me.
Cheers
mrozo
Your understanding about srand is correct: seeding with a specific value should be enough to generate a reproducible sequence of random numbers. You should debug your application to discover why it behaves in a non-reproducible way.
One reason for such behavior is a race condition on the hidden RNG state. Quoting from the C++ rand wiki:
It is implementation-defined whether rand() is thread-safe.
...
It is recommended to use C++11's random number generation facilities to replace rand().
my rand number is rand()%6+1 aka dice rolling, when its based on "time", is it possible to make a console app that foresees the future numbers in the time I want to? for example predict a number on time 14:40:32 on a certain day in future?
Yes provided that you use the same implementation of rand i.e. link with the same version of the standard library. All you need is to get the time_t value for the time you are interested in pass it to srand and call rand to get the value.
For example, if time_t holds the number of seconds since the epoch (which is the case for most implementations), then you can do the following to get the value returned by rand with a 10-second-in-the-future seed:
std::srand(std::time(nullptr) + 10);
std::cout << std::rand();
(Leaving aside the questions of whether it's a good idea to use rand at all.)
... for example predict a number on time 14:40:32 on a certain day in future?
It's possible when knowing how exactly rand() generates the pseudo random number on a certain seed (which is available for most compilers open source code implementation).
You have a certain seed number given from your date and time, thus you can just inspect the sequence of random numbers generated consecutively.
Yes and no. If you have a value of time_t, then just run the same library version of srand() on that value, and rand() will definitely yield the same sequence.
But you need to be sure that
the random libraries in the two applications use the same implementation (I think it's Mersenne Twister, but I'd need to check)
the clock of the two applications is synchronised. If you think that the master application's clock is 14:30:17, but it's really 14:30:18, then entering 14:30:17 in the monitor application will (of course) get different values.
the sequence of calls to rand() in both applications is the same, i.e., the number of calls between the srand() and the rand() you are interested in is known by you.
The last point might be a showstopper.
Say that you know that the app was initialised with srand(T) and you know T. Now yes, you know all the future extractions of its rand(). But you still need to know at which point in the sequence you are.
The number extracted at 19:30:17 GMT will not depend on the '19:30:17 GMT', but on how many numbers have been extracted before since the call to srand().
TL;DR if you know the value that time(0) passed to srand(), you cannot predict the output of the rand() call at a given time. You can predict the output of the n-th call to rand() for any given n.
my rand number is rand()%6+1 aka dice rolling, when its based on "time", is it possible to make a console app that foresees the future numbers in the time I want to? for example predict a number on time 14:40:32 on a certain day in future?
Yes provided that you use the same implementation of rand i.e. link with the same version of the standard library. All you need is to get the time_t value for the time you are interested in pass it to srand and call rand to get the value.
For example, if time_t holds the number of seconds since the epoch (which is the case for most implementations), then you can do the following to get the value returned by rand with a 10-second-in-the-future seed:
std::srand(std::time(nullptr) + 10);
std::cout << std::rand();
(Leaving aside the questions of whether it's a good idea to use rand at all.)
... for example predict a number on time 14:40:32 on a certain day in future?
It's possible when knowing how exactly rand() generates the pseudo random number on a certain seed (which is available for most compilers open source code implementation).
You have a certain seed number given from your date and time, thus you can just inspect the sequence of random numbers generated consecutively.
Yes and no. If you have a value of time_t, then just run the same library version of srand() on that value, and rand() will definitely yield the same sequence.
But you need to be sure that
the random libraries in the two applications use the same implementation (I think it's Mersenne Twister, but I'd need to check)
the clock of the two applications is synchronised. If you think that the master application's clock is 14:30:17, but it's really 14:30:18, then entering 14:30:17 in the monitor application will (of course) get different values.
the sequence of calls to rand() in both applications is the same, i.e., the number of calls between the srand() and the rand() you are interested in is known by you.
The last point might be a showstopper.
Say that you know that the app was initialised with srand(T) and you know T. Now yes, you know all the future extractions of its rand(). But you still need to know at which point in the sequence you are.
The number extracted at 19:30:17 GMT will not depend on the '19:30:17 GMT', but on how many numbers have been extracted before since the call to srand().
TL;DR if you know the value that time(0) passed to srand(), you cannot predict the output of the rand() call at a given time. You can predict the output of the n-th call to rand() for any given n.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What’s the Right Way to use the rand() Function in C++?
When I run the below program I always get the same values each time. Is rand not a true random function?
int main()
{
while(1)
{
getch();
cout<<rand()<<endl;
}
}
In each run I am getting the below values.
41
18467
6334
26500
19169
15724
......
Yes and no. rand() is a pseudo random number generator that will always return the same sequence of numbers given the same seed value. Typically one 'seeds' the random number generator with some random data and then uses rand() to return a sequence of seemingly random numbers. If your random data isn't needed for something requiring 'true' randomness (such as cryptography based security) just using the current system time is sufficient. However, if you are using it for security purposes, look into obtaining more truly random data from entropy gathering utilities and use that to seed the random number generator.
As aa mentioned, the seed function is referenced here
What is a true random function? Last I checked, computers couldn't do that :)
As to why you are getting the same set of numbers each time, it's because you need to seed the built in number generator with some starting 'random' value. There are many places to get this, but some tend to look good, but turn out bad. In our games, we generally seed with tic time from game bootup until the first or second user input. User input will always vary across many tics and can therefore be used as a decent starting point.
If you are using a Microsoft compiler, you can use rand_s, which generates very good random numbers (as good as you can get with only a computer): http://msdn.microsoft.com/en-us/library/sxtz2fa8%28VS.80%29.aspx
You can also use /dev/urandom on Linux and CryptGenRandom() on Windows to get quality random numbers.
or put srand() at the beginning of the function.
Just to follow on from the disucussion on "True" random numbers. As already, stated any generator that has a seed has a predictable period - I believe it can be 2^48.
If that level of randomness you can use the following:
long randomLong(unsigned int x)
{
x ^= (x << 21); // x is a non zero seed value
x ^= (x >> 35);
x ^= (x << 4);
return x;
}
This is taken from the following paper:
http://www.jstatsoft.org/v08/i14/paper
Which is a really interesting paper describing some low cost random number generators