C语言 随机数 (2012-08-20 19:15:38) http://blog.sina.com.cn/s/blog_8b745a5f01014ec7.html

C语言 随机数

  (2012-08-20 19:15:38)
   

头文件:#include<stdlib.h>

函数原型:long int random(void);

          void srandom(unsigned int seed);

          char* initstate(unsigned int seed,char* state,size_t n);

          char* setstate(char* state);

 

          int rand(void);

          int rand_r(unsigned int* seedp);

          void srand(unsigned int seed);

注意一下几点:

1、random和rand的区别

    很多编译器的rand(GCC除外)rand函数采用的是乘同余算法,这种算法比较简单,产生的随机数的不重复周期较短(一般小于2**sizeof(int))。而random函数采用的是“非线性增长-反馈”算法,此算法产生的随机数的不重复周期较长(一般为16*(2**sizeof(int)-1))。  乘同余算法之所以产生的随机数不重复周期短是因为它每步循环后都只有一个变常量next被传递到下一循环,即使next是unsigned int类型,也只有64位,而“非线性增长—反馈”算法是一组变常量在循环之间传递,可以高达2048位(最低64位,与线性算法相同),使得有限状态自动机的状态数目大大增多,从而增加了不重复周期长度。

    random函数实现比较复杂,所以速度比rand函数慢一点,但因为其不重复周期长,所以不用频繁初始化。

    random的返回值是long int型,而rand函数的返回值是int型。

    乘同余的rand函数和srand函数的实现举例:

                     static unsigned long int next;//next的定义

                     int myrand()//rand函数的实现版本

                     {

                           next = next * 1103515245 + 12345;
                           return((unsigned)(next/65536) % 32768);

                      }

                      void mysrand(unsigned seed) //srand函数的实现版本

                      {
                            next = seed;
                       }
     GCC的rand函数采用“非线性增长-反馈”的算法(高位随机率和低位随机率相同),但更早的版本或不同的系统上可能采用的乘同余算法(高位的随机率比低位的随机率高),所以为了兼容,取某个范围内的随机数时,应该取高位。 If you want to generate a random integer between 1 and 10, you should always do it by using high-order bits, as
              in

                     j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));

              and never by anything resembling

                     j = 1 + (rand() % 10);

              (which uses lower-order bits).

2、rand和rand_r的区别

    rand函数是非线程安全的,因为没调用一次rand函数,都要改变其状态值(如next值),由于同一进程的不同线程之间共享这些状态,所以每个线程对rand函数的调用,会影响到其他线程对rand的使用,所以在多线程环境中应该使用明确指定seed值的rand_r函数。

3、srand(srandom同)

    srand函数为rand函数指定种子,在调用rand函数之前假如没有调用srand函数,则默认rand函数的种子为1。假如srand指定的种子没有变化,则每次执行所产生的随机数序列是相同的。若srand每次指定的seed是不同的,则每次执行所产生的随机数序列是不同的。相当于每一个种子对应一串伪随机数序列,不同的种子对应不同的伪随机数序列。若要想每次执行执行产生的随机数序列不同,可以向srand函数传递可变化的参数,例如 srand((unsigned)time(0));。注意,使用time函数应引入头文件#include<time.h>。

4、RAND_MAX的值一般为2**(sizeof(int)-1);

5、rand_r函数的调用对rand函数没有影响。即若调用了rand_r函数,然后再调用rand函数(之前没有调用srand函数),则rand函数仍会产生默认种子值1的伪随机数序列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值