26

Once, my teacher taught me to use randomize() and random() function for generating pseudorandom numbers in C++ Builder. Now I prefer working in VS 2012, but when I tried to use these functions there it says that "identifier not found", even when I added #include <stdlib.h>. After some time of Googling I found that there are also rand() and srand() functions. What is the difference between them and which is it better to use?

Matthew
  • 306
  • 4
  • 17
Sunrise
  • 1,311
  • 3
  • 18
  • 28
  • 2
    you should use the [random header](http://en.cppreference.com/w/cpp/numeric/random) especially since [using rand() is considered harmful](http://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful) – Shafik Yaghmour Sep 10 '13 at 18:15
  • 3
    "considered harmful" is a subjective measure. It depends on what you are doing. It is just s pseudo-random generator, after all. – Zac Howland Sep 10 '13 at 18:24
  • 2
    It's a very crappy one, and it's not possible to prove any properties about the distribution (which is probably important if you're generating random numbers in the first place.) – bstamour Sep 10 '13 at 20:36

7 Answers7

42

randomize() and random() are not part of the standard library. Perhaps your teacher wrote functions with these names for use in your class, or maybe you really mean random() and srandom() which are part of POSIX and not available on Windows. rand() and srand() are part of the standard library and will be provided by any standard conforming implementation of C++.


You should avoid rand() and srand() and use the new C++11 <random> library. <random> was added as part of the C++11 standard (and VS2012 does provide it).

Video explaining why: rand() Considered Harmful

  • rand() is sometimes a low quality pRNG and not suitable for applications that need a reasonable level of unpredictability. <random> provides a variety of engines with different characteristics suitable for many different use cases.

  • Converting the results of rand() into a number you can use directly usually relies on code that is difficult to read and easy to get wrong, whereas using <random> distributions is easy and produces readable code.

  • The common methods of generating values in a given distribution using rand() further decrease the quality of the generated data. % generally biases the data and floating point division still produces non-uniform distributions. <random> distributions are higher quality as well as more readable.

  • rand() relies on a hidden global resource. Among other issues this causes rand() to not be thread safe. Some implementations make thread safety guarantees, but this is not required by the standard. Engines provided by <random> encapsulate pRNG state as objects with value semantics, allowing flexible control over the state.

  • srand() only permits a limited range of seeds. Engines in <random> can be initialized using seed sequences which permit the maximum possible seed data. seed_seq also implements a common pRNG warm-up.


example of using <random>:

#include <iostream>
#include <random>

int main() {
  // create source of randomness, and initialize it with non-deterministic seed
  std::random_device r;
  std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
  std::mt19937 eng{seed};

  // a distribution that takes randomness and produces values in specified range
  std::uniform_int_distribution<> dist(1,6);

  for (int i=0; i<100; ++i) {
    std::cout << dist(eng) << '\n';
  }
}
bames53
  • 86,085
  • 15
  • 179
  • 244
  • 9
    All things are relative, and depending on what you are doing, `rand()` may be largely sufficient. (Also, why all these presentations as videos? C++ is mainly used professionally, which means that we cannot activate the sound on our machines, and can't watch a video.) – James Kanze Sep 10 '13 at 18:34
  • Well, that presentation goes straight to the garbage bin for making such preposterous statements as "`rand()` considered harmful". False. `rand()` is not considered harmful and will never be. The issue here is simply choosing the right tool for the job. `rand()` is a perfectly usable function as long as you understand what it is. – AnT stands with Russia Sep 10 '13 at 18:44
  • 2
    @JamesKanze Headphones are handy in an office. There are probably also decent text resources but I don't know of any off hand. Even if quality and non-uniformity is not a concern one should still prefer `` simply for readability. – bames53 Sep 10 '13 at 18:44
  • 4
    @AndreyT There are no circumstances in which `` is available but `rand()` should be prefered. And you're incorrect that no one considers `rand()` harmful. `rand()` is simply too conducive to incorrect usage (not just in terms of quality, but also creating data races) and does not provide any benefits over alternatives. – bames53 Sep 10 '13 at 18:57
  • If someone asked me about the real problem with `rand()` I would say that it is the fact that it forces the user to rely on a *hidden* state (static/global variable). Of course, any deterministic generator will normally have a persistent state. But I would prefer to be able to manage it myself, i.e. declare the actual stateful object (or objects) where I want it, deciding the scope and lifetime by myself. C standard library does not offer me this opportunity. – AnT stands with Russia Sep 10 '13 at 19:02
  • @AndreyT Yep, I'm updating my answer with a list of issues with `rand()` and that global state is already on it. – bames53 Sep 10 '13 at 19:34
  • OK, I'm at home, and I've listened to the presentation. I'm singularly unimpressed; there was nothing in it I wasn't already thoroughly aware of, or that would make me change my mind. It's also very much pushing the C++ random generators---they are good, and a definite improvement, but... most people cannot use C++11 yet, and even for those who can, the simple, straightforeward use of `srand` and `rand` is sufficient for a lot of everyday use. (I've got custom code which is also much better than `rand()`, and much easier to use than the C++11 stuff, but I still often use `rand()`.) – James Kanze Sep 10 '13 at 21:27
  • 2
    @JamesKanze "there was nothing in it I wasn't already thoroughly aware of" And there was nothing in it I wasn't aware of either. I guess once one person knows something we should burn all copies of that information and never mention it? "most people cannot use C++11 yet" It might be the case that most people _don't_ use C++11, but often that's not because C++11 isn't available for their platform. Programmers, managers, etc. should be encouraged to move to C++11. Part of that is showing how it's better. – bames53 Sep 10 '13 at 21:40
  • 1
    "even for those who can, the simple, straightforeward use of `srand` and `rand` is sufficient" Being 'sufficient' is not a reason to prefer `rand`. If you want simple, straightforward code, I would say `` will typically do a better job of that. For example, `uniform_int_distribution<>(-10,10)` is simpler and more straightforward than `rand() % 21 - 10`. – bames53 Sep 10 '13 at 21:45
  • @bames53 I'm all in favor of the new ``; it's a great improvement. But realistically, it's not available in production code, except in exceptional instances, and just `rand() % n` _is_ often sufficient. It has its weaknesses, but they are well known, and not relevant for a lot of things. – James Kanze Sep 11 '13 at 08:15
  • @AndreyT The first couple of slides to give the impression that the presenter is a real idiot, just presenting marketing. After that, they're technically good; just a bit long winded and overly dogmatic when he's talking about `rand`. (It shouldn't be a religious argument, after all.) In the end, `srand()/rand()%n` does have a number of known weaknesses, but it's the simplest solution, and is adequate for a lot of casual uses. (Obviously, we don't use it for our Monte Carlo simulations, but that's a professional use which _does_ require quality.) – James Kanze Sep 11 '13 at 09:34
  • 2
    @JamesKanze "it's not available in production code, except in exceptional instances" Like I said, there are no circumstances in which `` is available but `rand()` should be prefered. I also think 'exceptional' is an underestimate of its availability. "but it's the simplest solution" If by 'simpler' you mean the same sort of thing as people who say C should be prefered to C++ because it's 'simpler'. In terms of most directly expressing the meaning of a program I find `` to be simpler. Getting the same level of abstraction out of `rand()` means implementing it oneself. – bames53 Sep 11 '13 at 15:32
  • I'd just like to note that it is not *required* to use a `seed_seq` for initialization. `std::mt19937 eng(r());` works too. – Yay295 Apr 26 '19 at 13:38
  • *rand() ... does not provide any benefits over alternatives.* Not that I am deep in the subject, but it seems to provide at least one big benefit: It is available in C. Not everybody uses C++, let alone C++ 11 or newer. – Binarus Aug 02 '22 at 06:32
  • The link to the video explaining why `rand()` is harmful is broken. Thanks, [link rot](https://en.wikipedia.org/wiki/Link_rot). – user16217248 Sep 28 '22 at 01:02
  • @user16217248 I've updated the link. – bames53 Sep 29 '22 at 03:52
10

Although there are (obviously, above) people who will assert with religious fervor that rand() is bad and random() is not, it turns out that your mileage may vary. Here's the gcc answer to the question of "What's the difference...", as supplied by the gcc version of stdlib.h (emphasis added):

/* These are the functions that actually do things.  The `random', `srandom',
   `initstate' and `setstate' functions are those from BSD Unices.
   The `rand' and `srand' functions are required by the ANSI standard.
   **We provide both interfaces to the same random number generator.**  */
/* Return a random long integer between 0 and RAND_MAX inclusive.  */
Guido
  • 2,571
  • 25
  • 37
Atlant
  • 101
  • 1
  • 2
9

Functions rand() and random() are either defined by POSIX since at least POSIX.1-2001 (and randomize() is not standardized).

On older rand() implementations, and on current implementations on different systems, the lower-order bits are much less random than the higher-order bits.

When available, random() does not suffer of this issue.

In add, modern version of rand() use the same random number generator as random(). So rand() may be correct, but it is not garanteed.

So, always use random() instead of rand(). If random() is not available on your operating system, ask to operating system developers to provide newer standards API implementation (2001 standard is now old enough to expect any system to provide it).

Jérôme Pouiller
  • 9,249
  • 5
  • 39
  • 47
3

srand() is the C Standard library implementation for seeding the (pseudo) random number generator. rand() is the (pseudo) random number generator in the C Standard Library.

C++ has implemented a newer (pseudo) random number generator in the <random> header file, which has a variety of different engines to use: http://en.cppreference.com/w/cpp/numeric/random

Zac Howland
  • 15,777
  • 1
  • 26
  • 42
2

It looks like you were using C-style functions, even though your question is labeled C++. Also, stdlib.h is a header file from C standard library. There's no such functions are random() and randomize() in C standard library. The C standard library has rand() and srand().

If you were using random() or something like that through stdlib.h, it must have been some non-standard library extension in Borland compiler package.

So, if you want to stick to C-style standard functions, that would be, again, rand() and srand(). But if you are writing in C++, you might have better (and more appropriate) options in C++ standard library.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
1

I am not familiar with randomize() and random() but they are not part of the standard library. You should avoid using rand() this video explains why using rand() is considered harmful.

You should be using the random header introduced in C++11, here is example using both std::uniform_real_distribution and std::uniform_int_distribution:

#include <iostream>
#include <random>

int main()
{
    std::random_device rd;

    std::mt19937 e2(rd());

    std::uniform_int_distribution<> dist(1, 6);
    std::uniform_real_distribution<> distReal(1, 6);

    for( int i = 0 ; i < 10; ++i )
    {
       std::cout << dist(e2) << ",";
    }
    std::cout << std::endl ;

    for( int i = 0 ; i < 10; ++i )
    {
       std::cout << distReal(e2) << ",";
    }
    std::cout << std::endl ;

    return 0 ;
}
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
-6

This is a work-around using random numbers form outside of c++.

This is the original program in C, copied from "http://www.programmingsimplified.com/" This program does not run because the " temp1 = 1 + random ( 588 );" "temp2 = 1 + random ( 380 );" statements do not work. 'random' is not a function of graphics.h, conio.h, or stdlib.h Nor, does it work if you include random.h. Below this listing is a work-around for the random function.

#include<graphics.h>
#include<conio.h>
#include<stdlib.h>
main()
{
   int gd = DETECT, gm, area, temp1, temp2, left = 25, top = 75;
   void *p;
   initgraph(&gd,&gm,"C:\\TC\\BGI");

   setcolor(YELLOW);
   circle(50,100,25);
   setfillstyle(SOLID_FILL,YELLOW);
   floodfill(50,100,YELLOW);

   setcolor(BLACK);
   setfillstyle(SOLID_FILL,BLACK);
   fillellipse(44,85,2,6);
   fillellipse(56,85,2,6);

   ellipse(50,100,205,335,20,9);
   ellipse(50,100,205,335,20,10);
   ellipse(50,100,205,335,20,11);

   area = imagesize(left, top, left + 50, top + 50);
   p = malloc(area);

   setcolor(WHITE);
   settextstyle(SANS_SERIF_FONT,HORIZ_DIR,2);
   outtextxy(155,451,"Smiling Face Animation");

   setcolor(BLUE);
   rectangle(0,0,639,449);

   while(!kbhit())
   {
      temp1 = 1 + random ( 588 );
      temp2 = 1 + random ( 380 );

      getimage(left, top, left + 50, top + 50, p);
      putimage(left, top, p, XOR_PUT);
      putimage(temp1 , temp2, p, XOR_PUT);
      delay(100);
      left = temp1;
      top = temp2;
   }

   getch();
   closegraph();
   return 0;
}

The random numbers are generated with a simple MS Excel macro, listed here:

Sub Macro1()
Dim i
For i = 1 To 400
Randomize

Range("a" & i) = Int(Rnd * 588) + 1
Range("b" & i) = Int(Rnd * 380) + 1

Next i
End Sub

This generates 2 columns of random numbers. Each column is copied and pasted into its own *.txt file , i.e. rnd1.txt and rnd2.txt and placed in a directory where they can be accessed by the c++ program that follows. Substitute the "c:\PATH\rnd1.txt" and "C:\PATH\rnd2.txt" with the correct path.

#include<iostream>
#include<fstream> 
#include<graphics.h>

using namespace std;
 int i,j,k;
int main(int argc, char** argv) {
   std::ifstream infile1;
   infile1.open("c:\\PATH\\rnd1.txt",ios::in);
   ifstream infile2;
   infile2.open("c:\\PATH\\rnd2.txt",ios::in);
   int gd = DETECT, gm, area, temp1, temp2, left = 25, top = 75;
   void *p;
   initgraph(&gd,&gm,"C:\\TC\\BGI");

   setcolor(YELLOW);
   circle(50,100,25);
   setfillstyle(SOLID_FILL,YELLOW);
   floodfill(50,100,YELLOW);

   setcolor(BLACK);
   setfillstyle(SOLID_FILL,BLACK);
   fillellipse(44,85,2,6);
   fillellipse(56,85,2,6);

   ellipse(50,100,205,335,20,9);
   ellipse(50,100,205,335,20,10);
   ellipse(50,100,205,335,20,11);

   area = imagesize(left, top, left + 50, top + 50);
   p = malloc(area);

   setcolor(WHITE);
   settextstyle(SANS_SERIF_FONT,HORIZ_DIR,2);
   outtextxy(155,451,"Smiling Face Animation ");

   setcolor(BLUE);
   rectangle(0,0,639,449);

   while(!kbhit())
   {
      infile1 >> j;
      temp1 = j;
      infile2 >> k;
      temp2 = k;
      if(infile2.eof()) {
       closegraph();
       void close();
       return 0;
        }                
      getimage(left, top, left + 50, top + 50, p);
      putimage(left, top, p, XOR_PUT);
      putimage(temp1 , temp2, p, XOR_PUT);
      delay(100);
      left = temp1;
      top = temp2;
      }

      }

This program will run for about 40 seconds and then terminate.

LJTurk
  • 1
  • 3
    Using Excel to generate random numbers for a C++ application... bleh. Much better to find a decent library if you don't want to use the 'built-in' options. [obligitory xkcd link](http://xkcd.com/763) – Baldrickk Sep 17 '14 at 08:58
  • 1
    graphics.h, conio.h and... EXEL? Seriously? – yyny May 17 '16 at 09:55