伪随机数C语言编程

在程序设计中,有时会用到随机数。本文介绍在 Linux 编程环境下,如何生成伪随机数。

什么是伪随机数

伪随机数是通过一个确定性的算法计算出来的“似乎”是随机的数序,因此伪随机数实际上并不随机。在计算伪随机数时,假如初始值不变的话,那么伪随机数的数序也不变。

伪随机数的优点

要产生真正的随机数,必须使用专门的设备,比如热噪信号、量子力学效应、放射性元素的衰退辐射,或使用无法预测的现象等。而伪随机数计算比较简单,不需要外部特殊硬件的支持,因此在计算机科学中伪随机数依然被使用。

伪随机数的缺点

由于伪随机数不是真的随机数,在有些方面它们不能被使用。例如在密码学中使用伪随机数要小心,因为其可计算性是一个可以攻击的地方。统计学、蒙特·卡罗方法上使用的伪随机数也必须挑选周期极长、随机性够高的随机函数,以确保计算结果有足够的随机性。

利用 rand() 函数生成伪随机数

函数原型:

//需要包含头文件 <stdlib.h>  
int rand(void);

Linux 中的rand()函数会返回一随机数值,其范围在0RAND_MAX 间。这里的RAND_MAX定义在stdlib.h中(如下图的128行所示),值为 2147483647(=2^31-1)。
这里写图片描述

以下例子利用 rand() 函数生成伪随机数。

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

#define RAND_NUM    5

int main(int argc, char *argv[])
{
    for(int i=0; i< RAND_NUM; ++i)
        printf( "%d ", rand() );

    printf("\n");
    return 0;
}

编译后连续运行两次,结果是:

$ ./rand
1804289383 846930886 1681692777 1714636915 1957747793 
$ ./rand
1804289383 846930886 1681692777 1714636915 1957747793

为什么会这样呢?

计算机产生的伪随机数是通过递推的方法得来的,必须要有一个初始值,也就是通常所说的种子。如果不对种子进行初始化,那么计算机会使用一个默认值。由于两次运行中初始值一样(都是默认值),递推公式也一样,所以才有完全一样的伪随机序列。

对于rand()函数,如果未设随机数种子,rand()在被调用时会自动设随机数种子为1

要想避免这种结果,就需要在每次程序运行时对种子进行初始化 ,且初始值不一样(比如到目前为止经过的时间 )。

获取当前时间(以秒计算)

函数原型:

// 需要包含头文件 <time.h>   
time_t time (time_t* timer);

time_t其实是一个长整形。

time_t time (time_t* timer)函数的用法是:

当参数为NULL的时候,返回从1970年1月1日0时0分0秒到此时的秒数;当参数不为NULL的时候,不仅返回从1970年1月1日0时0分0秒到此时的秒数,还把返回值存储到参数指向的time_t类型的变量里。

设置种子

函数原型:

// 需要包含头文件 <stdlib.h> 
void srand (unsigned int seed);

srand函数把种子值作为参数。结合函数time_t time (time_t* timer),我们可以这样设置种子:

srand( (unsigned int)time(NULL) );

参考代码

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

#define RAND_NUM    5

int main(int argc, char *argv[])
{
    srand( (unsigned int)time(NULL) );

    for(int i=0; i< RAND_NUM; ++i)
        printf( "%d ", rand()%100 );

    printf("\n");
    return 0;
}

实验结果如下:

$ ./rand
61 71 64 35 13 
$ ./rand
50 11 83 43 69 
$ ./rand
68 32 35 94 83 

【完】

参考资料

http://txgcwm.github.io/blog/2013/07/07/linuxxia-cyu-yan-wei-sui-ji-shu-bian-cheng/

https://zh.wikipedia.org/wiki/%E4%BC%AA%E9%9A%8F%E6%9C%BA%E6%80%A7

https://blog.csdn.net/duyiwuer2009/article/details/49497199

http://www.cplusplus.com/reference/cstdlib/srand/?kw=srand

http://blog.jobbole.com/108049/

猜你喜欢

转载自blog.csdn.net/u013490896/article/details/80645812