can rand() be used to generate predictable data?

2019-03-06 07:00发布

问题:

My goal is generate 2D or 3D geometry without having to store it on disk, so my goal is to have any sort of function than generate the same values according to a small seed. I don't mean to seek random values, but if the same "random" garbage data is returned when given the same seed, that's something I'm looking for.

If I give srand() the same integer, I get the same sequence out of rand(). Is that an intended feature ? If not, are there known standard functions designed to do the same thing ?

Although I tried this on ideone and on my computer and I get different results, I can understand that those function's implementations are not described, so that explains it.

回答1:

If I give srand() the same integer, I get the same sequence out of rand(). Is that an intended feature?

Yes, see 7.20.2.2:

7.20.2.2 The srand function

[...] Description

The srand function uses the argument as a seed for a new sequence of pseudo-random numbers to be returned by subsequent calls to rand. If srand is then called with the same seed value, the sequence of pseudo-random numbers shall be repeated.

However, that's only true for the same implementation of srand/rand. Another implementation might not use the same algorithm, and therefor won't produce the same sequence.

If not, are there known standard functions designed to do the same thing ?

Well, the functions are standard, but only in their behaviors, not the actual values (see implementation remark above). You're better off by using a specific generator from the C++11 predefined random number generators, since they're standardized.



回答2:

"If I give srand() the same integer, I get the same sequence out of rand(). Is that an intended feature ?"

Yes.

If you seed the same random number generator with the same seed, it will produce the same result.

Standard library rand and all it's variants are usually implemented as Linear congruential generators. They are not truly random, and perhaps better referred to as psuedo-random.

You probably saw different results on different machines because either they were using different psuedo-random number generation algorithms or you weren't supplying a fixed seed in which case the current system time is often the default seed.

If you need a fixed set of psuedo-random data, then generate it once and store it.



回答3:

The answer is yes, you get a repeatable sequence, if you always use the same implementation and the same seed, though it might be ill-advised due to possibly poor quality of rand().
Better use the C++ random number framework in <random> though. It not only allows reproducible sequences across implementations, it also supplies all you need to reliably get the distribution you really want.

Now to the details:

The requirements on rand are:

  • Generates pseudo-random numbers.
  • Range is 0 to RAND_MAX (minimum of 32767).
  • The seed set by srand() determines the sequence of pseudo-random numbers returned.

There is no requirement on what PRNG is implemented, so every implementation can have its own, though Linear Congrueantial Generators are a favorite.

A conforming (though arguably useless) implementation is presented in this dilbert strip:

http://dilbert.com/strips/comic/2001-10-25/

Or for those who like XKCD (It's a perfect drop-in for any C or C++ library ;-)):

For completeness, the standard quotes:

7.22.2.1 The rand function

The rand function computes a sequence of pseudo-random integers in the range 0 to RAND_MAX.
[...]
The value of the RAND_MAX macro shall be at least 32767.

7.22.2.2 The srand function

The srand function uses the argument as a seed for a new sequence of pseudo-random numbers to be returned by subsequent calls to rand. If srand is then called with the same seed value, the sequence of pseudo-random numbers shall be repeated. If rand is called before any calls to srand have been made, the same sequence shall be generated as when srand is first called with a seed value of 1.



回答4:

If you seed the random number generator with the same value, it will produce the same result. You saw different results on different machines because they were (probably) using different random number generation algorithms.