This question already has answers here:
What common algorithms are used for C's rand()?
(3 answers)
Closed 2 years ago.
My question is straightforward. I know abour srand and rand, I know how to seed my random generator and so on. I am specifically interested in the mathematics behind srand. How does the computer use let's say 3333 as a seed and calculates a "random" number?
The c standard library's and therefore the c++ standard library's std::rand implementation is up to the library implementation. It is not mandated by the standard. The following function
(source: https://xkcd.com/221/)
would be a perfectly valid implementation for it.
That is the reason why it should under no circumstances be used any more. Instead defer to the well-defined, implementation independent and portable mersenne twister.
It depends on the library implementation but in general it would be enough to calculate a well mixed hash of the argument.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Whenever we want to pick a random number from a vector we use a method called rand(). I want to know how it works from the backend.
rand has a seed value - e.g. setting it to the current time...
srand( time(NULL ) ); // second good enough
Then there is some math such as this....
unsigned int seed; // set by srand
unsigned int rand() {
seed = seed * number + offset;
return seed;
}
The number and offset are chosen, so the whole of the range of `unsigned int are covered. This generally means some form of prime number.
As mentioned in the comments, this is a very complex area.
If srand is not called, then seed has an initial value, which means that (ignoring thread timing issues), your program will get the same results each time it is run.
Getting the same results is handy for re-running tests, but problematic if it is say a game logic.
There is no "back-end" involved for rand.
BTW, in C++ you'll better use <random> standard header and related utilities, which are in the C++ standard library.
The rand function is part of the C standard library. It is unrelated to C++ vectors.
They (both the rand function and utilities from <random>) are based upon pseudo-random number generators, a quite complex field. You can still get a PhD by inventing better PRNGs.
If you want to understand how rand is (or can be) implemented, you'll better study the source code of some existing free software C standard library (like e.g. GNU glibc or musl-libc).
If you want to understand how <random> is implemented, study the source code of your C++ standard library. If you use the GCC compiler (e.g. compiling with the g++ program), it is provided by it.
This question already has answers here:
How to eliminate all sources of randomness so that program always gives identical answers?
(4 answers)
Closed 6 years ago.
I would like to know if I will get the same random numbers on all computers using the same srand() seed.
If not, how can I achieve that.
No. rand implementation is not standartized and different compiler vedors can and will use different algorithms.
You can use generators from C++11 <random> header which are standard and completely determenistic: mt19937 with same seed should give same sequence on all platforms, for example.
This question already has an answer here:
stl random distributions and portability
(1 answer)
Closed 8 years ago.
I'm generating a sequence of random numbers with std::mt19937_64. I've noticed that, when run with GCC and Clang on the same platform with the same seed, I obtain a different sequence. I've run the program through Valgrind and found no uninitialized memory.
Is there any guarantee to reproducibility across compilers or across platforms with std::mt19937_64?
Edit: Running with std::normal_distribution
The numbers that engines generate are guaranteed to be reproducible across implementations, but the distributions are not. (source: rand() considered harmful).
The N3337 standard draft says this about normal_distribution (26.5.8.5.1):
A normal_distribution random number distribution produces random numbers x distributed according to the probability density function
The distribution parameters µ and σ are also known as this distribution’s mean and standard deviation
And... that's it. It doesn't specify the order of the generated numbers, nor algorithm, nor example outputs.
The standard is very elaborate about mersenne_twister_engine (26.5.3.2), it specifies the state transition function, initial seeding algorithm and so on.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I've used
#include<stdlib>
#include<time>
using namespace std;
srand((unsigned)time(0));
int n=(rand()>>8)%4;
but what other random functions are there, or what other function could be used as random number generators?
EDIT: I don't really have a particular reason for asking this question, I just wanted to know if C++ had any other random functions.
Boost Random Number Library offers a broad range of generators (quality vs performance) and some typical random distributions. Everything rather nice and straightforward to use.
If you want some other methods/libraries - then google for cryptographic random numbers, also you can use this document as a reference.
Don't invent your own solutions unless you are an expert/researcher in the field/etc, take advantage of already existing solutions which were usually written by Smart People, and thoroughly examined by other Smart People.
The rand() and srand() functions are all the C++ Standard specifies. And if it comes to writing your own, be aware of what John von Neumann said:
"Anyone who considers arithmetical
methods of producing random digits is
of course in a state of sin"
This code is pretty efficient. Although users may begin to notice a pattern after a few iterations.
int FastRandom()
{
return 10;
}
Not strictly C++, but Windows specific:
CryptGenRandom
I'm sure all operating systems have their equivalent cryptographically secure random generator functions.
int unixrand()
{
int x;
int f = open("/dev/random", O_RDONLY);
if (f < 0) return -1; /* Error */
if (sizeof(x) != read(f, &x, sizeof(x))) {
close(f);
return -1;
}
close(f);
if (x < 0) x = ~x;
return x;
}
(Cross-posting from an answer I just wrote to a similar question)
Have a look at ISAAC (Indirection, Shift, Accumulate, Add, and Count). Its uniformly distributed and has an average cycle length of 2^8295.
It's fast too, since it doesnt involve multiplication or modulus.
Bruce Schneier and John Kelsey wrote a random number generator you may be interested in. Rather, it's a seed generator. Even though Yarrow is no longer supported, you may be interested in how it gathers entropy.
OpenSSL has an API that is relatively easy to access and pretty portable. And Mozilla comes with a decent API that wraps whatever the OS offers.
Personally, though, I generally use Boost.Random, which was already suggested.
Random gives you a good random number at uniform distribution and does a pretty good job at that.
Anything else would mean that you want to actually skew the distribution.
For example, using Microsoft's GUIDs generator would give you a random id that is less likely to be repeated and takes into account things like time and computer.
Time is usually the most random operation that is also cheap to perform, but it's still possible to predict.
If you want true randomness, using some kind of external input is your only solution.
Quantum Random Bit Generator is one service that provides such data.
I want to supply a number, and then receive a set of random numbers. However, I want those numbers to be the same regardless of which computer I run it on (assuming I supply the same seed).
Basically my question is: in C++, if I make use of rand(), but supply srand() with a user-defined seed rather than the current time, will I be able to generate the same random number stream on any computer?
There are dozens of PRNGs available as libraries. Pick one. I tend to use Mersenne Twister.
By using an externally supplied library, you bypass the risk of a weird or buggy implementation of your language's library rand(). As long as your platforms all conform to the same mathematical semantics, you'll get consistent results.
MT is a favorite of mine because I'm a physicist, and I use these things for Monte Carlo, where the guarantee of equal-distribution to high dimensions is important. But don't use MT as a cryptographic PRNG!
srand() & rand() are not part of the STL. They're actually part of the C runtime.
Yes, they will produce the same results as long as it's the same implementation of srand()/rand().
Depending on your needs, you might want to consider using Boost.Random. It provides several high-quality random number generators.
Assuming the implementations of rand() are the same, yes.
The easiest way to ensure this is to include a known rand() implementation with your program - either included in your project's source code or in the form of a library you can manage.
No, the ANSI C standard only specifies that rand() must produce a stream of random integers between 0 and RAND_MAX, which must be at least 32767 (source). This stream must be deterministic only in that, for a given implementation on a given machine, it must produce the same integer stream given the same seed.
You want a portable PRNG. Mersenne Twister (many implementations linked at the bottom) is pretty portable, as is Ben Pfaff's homegrown C99-compliant PRNG. Boost.Random should be fine too; as you're writing your code in C++, using Boost doesn't limit your choice of platforms much (although some "lesser" (i.e. non-compliant) compilers may have trouble with its heavy use of template metaprogramming). This is only really a problem for low-volume embedded platforms and perhaps novel research architectures, so if by "any computer" you mean "any x86/PPC/ARM/SPARC/Alpha/etc. platform that GCC targets", any of the above should do just fine.
Write your own pseudorandom number routine. There are a lot of algorithms documented on the internet, and they have a number of applications where rand isn't good enough (e.g. Perlin Noise).
Try these links for starters:
http://en.wikipedia.org/wiki/Linear_congruential_generator
http://en.wikipedia.org/wiki/Pseudorandom_number_generator
I believe if you supply with srand with the same seed, you will get the same results. That's pretty much the definition of a seed in terms of pseudo random number generators.
Yes. For a given seed (starting value), the sequence of numbers that rand() returns will always be the same.