0

New to C++ and following the beginner's tutorial here. Refer to the section titled Random Numbers in C++. Using exactly the code given:

#include <iostream>
#include <ctime>
#include <cstdlib>

using namespace std;

int main () {
   int i,j;

   // set the seed
   srand( (unsigned)time( NULL ) );

   /* generate 10  random numbers. */
   for( i = 0; i < 10; i++ ) {
      // generate actual random number
      j = rand();
      cout <<" Random Number : " << j << endl;
   }

   return 0;
}

I'm seeding srand() with time() (compiled with g++) and so the generated result should be completely random. However, here's the result I'm getting:

$ ./a.out
 Random Number : 1028986599
 Random Number : 491960102
 Random Number : 561393364
 Random Number : 1442607477
 Random Number : 813491309
 Random Number : 1467533561
 Random Number : 986873932
 Random Number : 1373969343
 Random Number : 411091610
 Random Number : 761796871
$ ./a.out
 Random Number : 1029003406
 Random Number : 774435351
 Random Number : 36559790
 Random Number : 280067488
 Random Number : 1957600239
 Random Number : 1937744833
 Random Number : 1087901476
 Random Number : 684336574
 Random Number : 1869869533
 Random Number : 621550933
$ ./a.out
 Random Number : 1029020213
 Random Number : 1056910600
 Random Number : 1659209863
 Random Number : 1265011146
 Random Number : 954225522
 Random Number : 260472458
 Random Number : 1188929020
 Random Number : 2142187452
 Random Number : 1181163809
 Random Number : 481304995

As you can see from the first number generated on each ./a.out execution, the first number in the 10-loop is increasing on each execution. And it seems to always be about 1.02 million. Further testing suggests this pattern always holds and it's not a coincidence.

I can only assume that it's increasing due to the seed time(), which is always increasing. But that suggests the rand() function isn't truly random and is predictable.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
bli00
  • 2,215
  • 2
  • 19
  • 46
  • 3
    `rand()` is garbage. There are no requirements on it's randomness, it could very well just increment and be compliant. Use the new features in [``](https://en.cppreference.com/w/cpp/numeric/random) instead. – François Andrieux Oct 16 '18 at 22:24
  • 1
    Why does every C++ tutorial teach C with stdout? You should be using `` instead. – Sailanarmo Oct 16 '18 at 22:26
  • Note that conventional forms of random number generation are pseudo random and are predictable if you know the initial state and algorithm. – François Andrieux Oct 16 '18 at 22:26
  • @François Andrieux, but it's seeded. – bli00 Oct 16 '18 at 22:27
  • @thestateofmay I'm not sure which *"it"* you are referring to. But all conventional forms of pseudo number generation are seeded. – François Andrieux Oct 16 '18 at 22:28
  • 1
    @FrançoisAndrieux I think you meant to respond to thestateofmay – Sailanarmo Oct 16 '18 at 22:29
  • @François Andrieux the tutorial specifically says "the first is rand(), this function will only return a pseudo random number. The way to fix this is to first call the srand() function." Which it did in the code example provided. I can only assume either `srand()` needs to be called on every loop or that this tutorial is garbage... – bli00 Oct 16 '18 at 22:31
  • 1
    @thestateofmay Calling `srand` every loop is absolutely incorrect. Notably, the resolution of `time` is so low you will likely call `srand` with the same seed. You'll get the same numbers every iteration. You are using `srand` and `rand` correctly, they are just not very good functions and should be avoided. If a tutorial suggests them, it's either very outdated or not very good. Edit : Unfortunately, most c++ tutorial either fall in that category or are teaching c with a sprinkling of c++ features. – François Andrieux Oct 16 '18 at 22:32
  • @thestateofmay `rand()` always return a pseudo-random number, because computers cannot produce true randomness. "pseudo-random" doesn't mean "bad randomness". – Etienne de Martel Oct 16 '18 at 22:36
  • @EtiennedeMartel Computers can produce true randomness. For example, you can extract the phase offset between the CPU clock and the network interface clock which depends on microscopic zone temperature variations in the quartz crystals that are believed to be truly random quantum effects. There are several other known methods. – David Schwartz Oct 16 '18 at 22:37
  • see: https://stackoverflow.com/questions/52451998/why-do-i-get-this-particular-color-pattern-when-using-rand – zzxyz Oct 16 '18 at 22:38
  • @thestateofmay I will tell you right now. That webpage you are following is also garbage and misleading. You should pick up a C++ book which we have a recommended list for. – Sailanarmo Oct 16 '18 at 22:38
  • Possible duplicate of [rand() with srand() is giving strangely similar results. The return from rand() is very similar](https://stackoverflow.com/questions/45066246/rand-with-srand-is-giving-strangely-similar-results-the-return-from-rand) – ShadowRanger Oct 16 '18 at 22:41
  • 1
    @zzxyz: [That question](https://stackoverflow.com/q/52451998/364696) has little to do with the raw `rand` output, as the accepted answer on it indicates; they *used* the outputs in a way that triggered the pattern, no improvement in the PRNG would have meaningfully changed the result. – ShadowRanger Oct 16 '18 at 22:43
  • @ShadowRanger - ah. I had not looked at the answers since the day that was posted. I had thought the usage exacerbated the issue, not completely caused it. Thanks. – zzxyz Oct 16 '18 at 22:47
  • 1
    Possible duplicate of [rand() function in C is not random even when seeded](https://stackoverflow.com/q/42380224/608639), [Why are my 'randomly' generated numbers are increasing every time I run the program?](https://stackoverflow.com/q/39540859/608639) and [srand(time(NULL)) generating similar results](https://stackoverflow.com/q/6668282/608639) – jww Oct 17 '18 at 01:10

1 Answers1

5

But that suggests the rand() function isn't truly random and is predictable.

Yes, that's absolutely correct. Typically, rand is implement with a very simple pseudo-random number generator. The use of rand is not appropriate when numbers that are truly random or unpredictable are required.

Under the hood, your implementation probably uses a Linear congruential generator and your three examples are all inside the same linear interval, at least for the first output.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • the tutorial specifically says "the first is rand(), this function will only return a pseudo random number. The way to fix this is to first call the srand() function." Which it did in the code example provided. I can only assume either srand() needs to be called on every loop or that this tutorial is wrong. – bli00 Oct 16 '18 at 22:32
  • 3
    @thestateofmay The tutorial is misleading. If you don't call `srand`, you'll get the very same sequence every time. If you call `srand`, you will start the sequence from a different point each time, but what that means depends on your platform's `rand` implementation. – David Schwartz Oct 16 '18 at 22:34