C中的随机数生成…第一个数字不是很随机

前端之家收集整理的这篇文章主要介绍了C中的随机数生成…第一个数字不是很随机前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图在不使用增强的情况下在C中获得0到1之间的均匀随机数.我不想依赖图书馆.

每当我开始我的课程时,我都会:
srand(time(NULL));

然后我打印8个随机数.我用一个空白行分隔程序的不同运行:

Random number: 0.226063
Random number: 0.449186
Random number: 0.474514
Random number: 0.160779
Random number: 0.220868
Random number: 0.136685
Random number: 0.260120
Random number: 0.843334

Random number: 0.226181
Random number: 0.422253
Random number: 0.808594
Random number: 0.040531
Random number: 0.212377
Random number: 0.421073
Random number: 0.965790
Random number: 0.026305

Random number: 0.226306
Random number: 0.526858
Random number: 0.898279
Random number: 0.378934
Random number: 0.736653
Random number: 0.924420
Random number: 0.718503
Random number: 0.888140

Random number: 0.226463
Random number: 0.157614
Random number: 0.010386
Random number: 0.551936
Random number: 0.391998
Random number: 0.303603
Random number: 0.659396
Random number: 0.465434

为什么每次第一个数字几乎完全相同?我不明白.我应该把第一个号码丢掉还是什么?

示例代码

#include <iostream>

int main() {
  srand( time(NULL) );
  printf("%f\n",(float)rand()/RAND_MAX);
  printf("%f\n",(float)rand()/RAND_MAX);
}

解决方法

不,不要扔掉第一个.这会扭曲结果.序列{1,1,1}与任何其他任意七位数序列完全一样,尽管人类试图在所有事物中找到意义的倾向:-)

试图摆弄它因为你不喜欢这个序列会使随机生成更糟,而不是更好.

对于它的价值,你应该确保你的运行至少间隔一秒,这样你就不会使用相同的种子(这似乎不是这里的情况).除此之外,使用PRNG按原样提供的结果或找到更好的发电机.

你是一个统计学家/密码​​学家,你不会使用正常的随机函数,或者它真的没关系!对于绝大多数情况,它是后者.

如果你不想要一个花哨的(或一个涉及大量额外的东西)并且你对实现提供的那个不满意,那么很容易实现一个基于gcc版本,如:

seed = (1103515245 * seed + 12345) & 0xffffffff
return seed & 0x7fffffff

并且请记住,初始种子值是根据提供给srand的参数计算的,其模数为231-1,以最小化与初始种子具有线性相关性的序列(序列仍然是线性的,而不是来自初始种子值).

如果您只是在寻找快速解决方案而不依赖于外部库或花费时间实现更复杂的生成器,以下代码可能会让您的生活更轻松:

// Assume 32-bit integer.
static int seed = 1;
void mySRand (int newseed) {
    seed = newseed % 0x7fffffff;
}
int myRand() {
    seed = 1103515245 * seed + 12345;
    return seed & 0x7fffffff;
}

以下程序实际上会让您了解该算法将对提供给mySRand的种子值的小变化做些什么.

它从时间获得初始种子(NULL),然后显示20个连续种子值的初始值超出myRand,以及百分比变化.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

static int seed = 1;
void mySRand (int newseed) { seed = newseed % 0x7fffffff; }
int myRand() { seed = 1103515245 * seed + 12345; return seed & 0x7fffffff; }

int main (void) {
    int i,xyzzy,val,lastVal;
    double avg,diff;
    xyzzy = time (NULL);
    mySRand (xyzzy);
    lastVal = myRand();
    printf ("seed=%d,val=%12d\n",lastVal);
    for (i = 0; i < 20; i++) {
        mySRand (++xyzzy);
        val = myRand();
        avg = val; avg = (avg + lastVal) / 2;
        diff = 100 * fabs (avg - val) / avg;
        printf ("seed=%d,val=%12d,avg=%12.1f,%%chg=%f\n",avg,diff);
        lastVal = val;
    }
    return 0;
}

百分比变化基于当前值与当前值和之前的平均值之间的差异,以便有希望不引入偏差.示例输出是:

seed=1324533721,val=  1092183454
seed=1324533722,val=    48215051,avg= 570199252.5,%chg=91.544175
seed=1324533723,val=  1151730296,avg= 599972673.5,%chg=91.963792
seed=1324533724,val=   107761893,avg= 629746094.5,%chg=82.888041
seed=1324533725,val=  1211277138,avg= 659519515.5,%chg=83.660545
seed=1324533726,val=   167308735,avg= 689292936.5,%chg=75.727484
seed=1324533727,val=  1270823980,avg= 719066357.5,%chg=76.732504
seed=1324533728,val=   226855577,avg= 748839778.5,%chg=69.705726
seed=1324533729,val=  1330370822,avg= 778613199.5,%chg=70.864150
seed=1324533730,val=   286402419,avg= 808386620.5,%chg=64.571108
seed=1324533731,val=  1389917664,avg= 838160041.5,%chg=65.829626
seed=1324533732,val=   345949261,avg= 867933462.5,%chg=60.141039
seed=1324533733,val=  1449464506,avg= 897706883.5,%chg=61.463005
seed=1324533734,val=   405496103,avg= 927480304.5,%chg=56.279815
seed=1324533735,val=  1509011348,avg= 957253725.5,%chg=57.639642
seed=1324533736,val=   465042945,avg= 987027146.5,%chg=52.884483
seed=1324533737,val=  1568558190,avg=1016800567.5,%chg=54.264095
seed=1324533738,val=   524589787,avg=1046573988.5,%chg=49.875518
seed=1324533739,val=  1628105032,avg=1076347409.5,%chg=51.262038
seed=1324533740,val=   584136629,avg=1106120830.5,%chg=47.190523
seed=1324533741,val=  1687651874,avg=1135894251.5,%chg=48.574735

所以你可以看到,基于靠近的初始种子,起始值实际上存在很大差异.

猜你在找的C&C++相关文章