C++ rand() 和 random() 函数有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18726102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:10:04  来源:igfitidea点击:

What difference between rand() and random() functions?

c++random

提问by Sunrise

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?

有一次,我的老师教我在 C++ Builder 中使用randomize()random()生成伪随机数的函数。现在我更喜欢在 VS 2012 中工作,但是当我尝试在那里使用这些函数时,它说“找不到标识符”,即使我添加了#include <stdlib.h>. 经过一段时间的谷歌搜索,我发现还有rand()srand()功能。它们之间有什么区别,哪个更好用?

回答by bames53

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++.

randomize()并且random()不是标准库的一部分。也许你的老师写的功能,这些名字用在你的类,或者你真的是random()srandom()它们是POSIX的一部分,而不是Windows上可用。rand()并且srand()是标准库的一部分,将由任何符合标准的 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).

您应该避免rand()srand()使用新的 C++11<random>库。<random>被添加为 C++11 标准的一部分(VS2012 确实提供了它)。

Video explaining why: rand()Considered Harmful

解释原因的视频:被rand()认为是有害的

  • rand()is typically 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 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_seqalso implements a common pRNG warm-up.

  • rand()通常是低质量的 pRNG,不适合需要合理水平不可预测性的应用程序。<random>提供各种具有不同特性的引擎,适用于许多不同的用例。

  • 将 的结果rand()转换为您可以直接使用的数字通常依赖于难以阅读且容易出错的代码,而使用<random>分布很容易并生成可读代码。

  • 在给定分布中生成值的常用方法rand()进一步降低了生成数据的质量。%通常会偏置数据,浮点除法仍然会产生非均匀分布。<random>发行版质量更高,可读性更高。

  • rand()依赖于隐藏的全局资源。除其他问题外,这会导致rand()线程不安全。一些实现可以保证线程安全,但这不是必需的标准。<random>将 pRNG 状态封装为具有值语义的对象提供的引擎,允许对状态进行灵活控制。

  • srand()只允许有限范围的种子。<random>可以使用允许最大可能种子数据的种子序列来初始化引擎。seed_seq还实现了常见的 pRNG 预热。



example of using <random>:

使用示例<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';
  }
}

回答by Atlant

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):

尽管(显然,上面)有人会以宗教热情断言rand()是坏的而random()不是,但事实证明,您的里程可能会有所不同。这是 gcc 对“有什么区别......”问题的回答,由 stdlib.h 的 gcc 版本提供(强调已添加):

/* These are the functions that actually do things. The random',srandom', initstate' andsetstate' functions are those from BSD Unices. The rand' andsrand' 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. */

/* 这些是实际做事的函数。的random',srandom“ initstate' andsetstate这”功能是指那些从BSD Unix系统。的rand' and函数srand”功能由ANSI标准要求。 我们为同一个随机数生成器提供两个接口。//返回0到RAND_MAX(含)之间的随机长整数。*/

回答by AnT

It looks like you were using C-style functions, even though your question is labeled C++. Also, stdlib.his 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().

看起来您使用的是 C 风格的函数,即使您的问题被标记为 C++。此外,stdlib.h是来自 C 标准库的头文件。有没有这样的功能random(),并randomize()在C标准库。C 标准库具有rand()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.

如果您正在通过 使用random()或类似的东西stdlib.h,那么它一定是 Borland 编译器包中的一些非标准库扩展。

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.

所以,如果你想坚持使用 C 风格的标准函数,那又是,rand()并且srand(). 但是如果你用 C++ 编写,你可能在 C++ 标准库中有更好(也更合适)的选项。

回答by Jér?me Pouiller

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

函数rand()random()至少从 POSIX.1-2001 开始由 POSIX 定义(并且randomize()没有标准化)。

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

在较旧的rand()实现中,以及在不同系统上的当前实现中,低位的随机性远低于高位。

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

如果可用,random()则不会遇到此问题。

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

此外,现代版本rand()使用与random(). 所以rand()可能是正确的,但不能保证。

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).

所以,总是使用random()代替rand()。如果random()在您的操作系统上不可用,请要求操作系统开发人员提供更新的标准 API 实现(2001 标准现在已经足够老,可以期望任何系统提供它)。

回答by Zac Howland

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.

srand()是用于播种(伪)随机数生成器的 C 标准库实现。 rand()是 C 标准库中的(伪)随机数生成器。

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

C++ 在<random>头文件中实现了一个更新的(伪)随机数生成器,它有多种不同的引擎可供使用:http: //en.cppreference.com/w/cpp/numeric/random

回答by Shafik Yaghmour

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.

我不熟悉的randomize()random(),但它们不是标准库的一部分。你应该避免使用rand()这个视频解释了为什么使用 rand() 被认为是有害的

You should be using the random headerintroduced in C++11, here is example using both std::uniform_real_distributionand std::uniform_int_distribution:

您应该使用C++11 中引入的随机标头,这里是使用std::uniform_real_distributionstd::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 ;
}

回答by LJTurk

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

这是使用 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.

这是C中的原始程序,从“ http://www.programmingsimplified.com/”复制而来,该程序无法运行,因为“temp1 = 1 + random (588);” “temp2 = 1 + 随机(380);” 语句不起作用。'random' 不是 graphics.h、conio.h 或 stdlib.h 的函数,如果包含 random.h,它也不起作用。此列表下方是随机函数的变通方法。

#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:

随机数是用一个简单的 MS Excel 宏生成的,这里列出:

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.

这会生成 2 列随机数。每一列都被复制并粘贴到它自己的 *.txt 文件中,即 rnd1.txt 和 rnd2.txt 并放置在一个目录中,在那里它们可以被后面的 c++ 程序访问。用正确的路径替换“c:\PATH\rnd1.txt”和“C:\PATH\rnd2.txt”。

#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.

该程序将运行约 40 秒,然后终止。