第一个随机数总是小于休息 [英] First random number is always smaller than rest

查看:217
本文介绍了第一个随机数总是小于休息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我碰巧注意到,在C ++中,使用std rand()方法调用的第一个随机数大部分时间比第二个小。关于Qt实现,第一个几乎总是小几个量级。

  qsrand(QTime :: currentTime ); 
qDebug()<< qt1:<< qrand();
qDebug()<< qt2:< qrand();

srand((unsigned int)time(0));
std :: cout<< std1:<< rand()<< std :: endl;
std :: cout<< std2:<< rand()<< std :: endl;

输出:

 code> qt1:7109361 
qt2:1375429742
std1:871649082
std2:1820164987

这是否意味着,由于种子错误或错误?
同时,qrand()输出剧烈变化,第一个rand()输出似乎随时间线性变化。只是想知道为什么。

解决方案

我不确定是否可以归类为一个错误,让我们检查一下情况:


  1. 查看 rand的实现


  2. 使用 QTime :: currentTime()。msec() ,其本质上由 0..999 的小范围界限,但 qsrand 接受 uint 范围 0..4294967295


Qtime :: currentTime()msec()+ 100000000 >



现在第一个值可能会大于第二个大部分时间。



太担心太多。这种模式似乎只发生在前两个生成的值上。



EDIT:



为了使事情更清楚,请尝试运行下面的代码。它将比较前两个生成的值,看看哪个更小,使用所有可能的毫秒值(范围:0..999)作为种子:

  int totalCalls,leftIsSmaller = 0; 
for(totalCalls = 0; totalCalls< 1000; totalCalls ++)
{
qsrand(totalCalls);
if(qrand()< qrand())
leftIsSmaller ++;
}
qDebug()<< (100.0 * leftIsSmaller)/ totalCalls;

它将打印94.8,这意味着94.8%的时间第一个值将小于第二个。

我在这里做了一些测试,并且该模式似乎在第二个值生成后消失。我的建议:找到一个好的值来调用 qsrand (在程序开始时显然只能调用一次)。良好的值应该跨越 uint 类的整个范围。请查看此其他问题的一些想法:





另外,这个:




I happen to notice that in C++ the first random number being called with the std rand() method is most of the time significant smaller than the second one. Concerning the Qt implementation the first one is nearly always several magnitudes smaller.

qsrand(QTime::currentTime().msec());
qDebug() << "qt1: " << qrand();
qDebug() << "qt2: " << qrand();

srand((unsigned int) time(0));
std::cout << "std1: " << rand() << std::endl;
std::cout << "std2: " << rand() << std::endl;

output:

qt1:  7109361
qt2:  1375429742
std1: 871649082
std2: 1820164987

Is this intended, due to error in seeding or a bug? Also while the qrand() output varies strongly the first rand() output seems to change linearly with time. Just wonder why.

解决方案

I'm not sure that could be classified as a bug, but it has an explanation. Let's examine the situation:

  1. Look at rand's implementation. You'll see it's just a calculation using the last generated value.

  2. You're seeding using QTime::currentTime().msec(), which is by nature bounded by the small range of values 0..999, but qsrand accepts an uint variable, on the range 0..4294967295.

By combining those two factors, you have a pattern.

Just out of curiosity: try seeding with QTime::currentTime().msec() + 100000000

Now the first value will probably be bigger than the second most of the time.

I wouldn't worry too much. This "pattern" seems to happen only on the first two generated values. After that, everything seems to go back to normal.

EDIT:

To make things more clear, try running the code below. It'll compare the first two generated values to see which one is smaller, using all possible millisecond values (range: 0..999) as the seed:

int totalCalls, leftIsSmaller = 0;
for (totalCalls = 0; totalCalls < 1000; totalCalls++)
{
    qsrand(totalCalls);
    if (qrand() < qrand())
        leftIsSmaller++;
}
qDebug() << (100.0 * leftIsSmaller) / totalCalls;

It will print 94.8, which means 94.8% of the time the first value will be smaller than the second.

Conclusion: when using the current millisecond to seed, you'll see that pattern for the first two values. I did some tests here and the pattern seems to disappear after the second value is generated. My advice: find a "good" value to call qsrand (which should obviously be called only once, at the beginning of your program). A good value should span the whole range of the uint class. Take a look at this other question for some ideas:

Also, take a look at this:

这篇关于第一个随机数总是小于休息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆