[英]What difference between rand() and random() functions?
有一次,我的老师教我使用randomize()
和random()
函数在C ++ Builder中生成伪随机数。 现在我更喜欢在VS 2012中工作,但当我尝试使用这些函数时,它会说“找不到标识符”,即使我添加了#include <stdlib.h>
。 经过一段时间的谷歌搜索后,我发现还有rand()
和srand()
函数。 它们之间有什么区别,哪个更好用?
randomize()
和random()
不是标准库的一部分。 也许你的老师用这些名字编写函数用于你的类,或者你真的是指random()
和srandom()
,它们是POSIX的一部分,在Windows上不可用。 rand()
和srand()
是标准库的一部分,将由C ++的任何标准符合实现提供。
你应该避免使用rand()
和srand()
并使用新的C ++ 11 <random>
库。 <random>
作为C ++ 11标准的一部分添加(VS2012确实提供了它)。
视频解释原因: rand()
认为是有害的
rand()
通常是低质量的pRNG,不适合需要合理水平的不可预测性的应用。 <random>
提供了适用于许多不同用例的各种不同特性的发动机。
将rand()
的结果转换为可以直接使用的数字通常依赖于难以阅读且容易出错的代码,而使用<random>
分布很容易并产生可读代码。
使用rand()
在给定分布中生成值的常用方法进一步降低了生成数据的质量。 %
通常偏差数据,浮点除法仍然产生非均匀分布。 <random>
分布质量更高,可读性更高。
rand()
依赖于隐藏的全局资源。 在其他问题中,这会导致rand()
不是线程安全的。 某些实现可以保证线程安全,但这不是标准。 <random>
提供的引擎将pRNG状态封装为具有值语义的对象,允许灵活地控制状态。
srand()
只允许有限范围的种子。 可以使用允许最大可能种子数据的种子序列来初始化<random>
引擎。 seed_seq
还实现了常见的seed_seq
预热。
使用<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';
}
}
虽然有(显然,上面)人会以宗教热情断言rand()是坏的而且随机()不是,但事实证明你的里程可能会有所不同。 这是gcc版本的stdlib.h提供的“有什么不同......”的问题的gcc答案(强调添加):
/ *这些是实际做事的功能。 random',
srandom', initstate' and
setstate'函数来自BSD Unices。 ANSI标准要求使用rand' and
srand'函数。 我们为同一随机数生成器提供两个接口。 //返回0到RAND_MAX之间的随机长整数。 * /
看起来您使用的是C风格的函数,即使您的问题标记为C ++。 另外, stdlib.h
是来自C标准库的头文件。 在C标准库中没有这样的函数是random()
和randomize()
。 C标准库有rand()
和srand()
。
如果您通过stdlib.h
使用random()
或类似的东西,它必须是Borland编译器包中的一些非标准库扩展。
所以,如果你想坚持使用C风格的标准函数,那就是rand()
和srand()
。 但是如果你是用C ++编写的,那么在C ++标准库中可能有更好(也更合适)的选项。
srand()
是用于播种(伪)随机数生成器的C标准库实现。 rand()
是C标准库中的(伪)随机数生成器。
C ++在<random>
头文件中实现了一个较新的(伪)随机数生成器,它有多种不同的引擎可供使用: http : //en.cppreference.com/w/cpp/numeric/random
函数rand()
和random()
由POSIX定义,因为至少POSIX.1-2001(和randomize()
未标准化)。
在较旧的rand()
实现以及不同系统上的当前实现中,低阶位比高阶位更不随机。
如果可用, random()
不会遇到此问题。
在添加,现代版的rand()
使用相同的随机数发生器random()
所以rand()
可能是正确的,但它没有保证。
因此,始终使用random()
而不是rand()
。 如果您的操作系统上没有random()
,请要求操作系统开发人员提供更新的标准API实现(2001标准现在已经足够大,可以期望任何系统提供它)。
我不熟悉randomize()
和random()
但它们不是标准库的一部分。 你应该避免使用rand()
这个视频解释了为什么使用rand()被认为是有害的 。
您应该使用C ++ 11中引入的随机头 ,这里是使用std :: uniform_real_distribution和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 ;
}
这是在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秒然后终止。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.