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

时间:2013-09-10 18:14:02

标签: c++ random

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

7 个答案:

答案 0 :(得分:32)

randomize()random()不属于标准库。也许你的老师用这些名字编写函数用于你的课程,或者你真的是指random()srandom(),它们是POSIX的一部分,在Windows上不可用。 rand()srand()是标准库的一部分,将由C ++的任何标准符合实现提供。


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

视频解释原因:rand() Considered Harmful

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

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

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

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

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


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

答案 1 :(得分:4)

虽然(显然,上面)有人会以宗教热情断言 rand()是坏的而且 random()不是,但事实证明你的里程可能有所不同这是gcc版本的stdlib.h提供的“有什么不同......”的问题的gcc答案(重点补充):

/ *这些是实际做事的功能。 random', srandom',    initstate' and setstate'函数来自BSD Unices。    ANSI标准要求rand' and srand'函数。    我们为同一个随机数生成器提供两个接口。 / / 返回0到RAND_MAX之间的随机长整数。 * /

答案 2 :(得分:3)

看起来您使用的是C风格的函数,即使您的问题标记为C ++。此外,stdlib.h是来自C标准库的头文件。 C标准库中没有random()randomize()这样的函数。 C标准库包含rand()srand()

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

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

答案 3 :(得分:2)

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

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

答案 4 :(得分:2)

函数rand()random()由POSIX定义,因为至少POSIX.1-2001(randomize()未标准化)。

在较早的rand()实现中,以及在不同系统上的当前实现中,低阶位比高阶位更不随机。

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

此外,现代版rand()使用与random()相同的随机数生成器。所以rand()可能是正确的,但不保证。

因此,请始终使用random()代替rand()。如果您的操作系统上没有random(),请要求操作系统开发人员提供更新的标准API实现(2001年标准已经足够大,可以期望任何系统提供它)。

答案 5 :(得分:1)

我不熟悉randomize()random(),但它们不属于标准库。您应该避免使用rand()此视频解释原因using rand() is considered harmful

您应该使用 C ++ 11 中介绍的random header,这是使用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 ;
}

答案 6 :(得分:-3)

这是在c ++之外使用随机数形式的解决方法。

这是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;
}

使用简单的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

这会生成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;
      }

      }

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