必威体育Betway必威体育官网
当前位置:首页 > IT技术

C语言中构造随机数原理及rand()取余构造随机数方法

时间:2019-10-19 22:45:11来源:IT技术作者:seo实验室小编阅读:82次「手机版」
 

随机数

在C语言中,ANSIC C程序库提供rand()函数来产生随机数。但事实上,rand()是并不是一个真正的随机数产生器,即可以预测随机序列的顺序,在默认随机种子情况下产生0~99之间的随机数,其随机序列为{83,86,77,15,……},比如以下程序:

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

int main(){
    int num;
    printf("A set of random numbers:\n");
    for(int i = 0; i < 10; i++){
        num = rand()%100; //产生0-99之间的随机数;
        printf("%d ",num);
    }
    putchar('\n');
    return 0;
}

编译、执行结果:

可以看出,在执行三次情况下,rand()产生的随机序列都是一样的。这是因为,rand()使用的是产生伪随机数的“魔术公式”,它的随机数种子是一直没有变的,所以每次产生的随机序列是一样的。在调用rand()函数之前,可以使用srand()函数设置随机数种子,如果没有设置随机数种子,rand()函数在调用时,自动设计随机数种子为1。随机种子相同,每次产生的随机数也会相同。rand()函数被包含在头文件<stdlib.h>中。

如果想要构造每次产生不同的随机数序列的函数,则需要引入一个不断变化的随机种子。最常用的就是时间变量,利用时间函数time()获取系统时间(其返回值time_t一定是数值类型)。time()的参数是一个time_t类型对象的地址,时间值则存储在该地址中。所以,可以使用空指针0或者NULL作为参数。此时,时间通过返回值机制提供。time()函数包含在头文件<time.h>中。写一个简单地程序说明time()函数;

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

int main(){
    int num1,num2;
    printf("The return value of time:\n");
    num1 = time(0);
    num2 = time(NULL);
    printf("%d,%d\n",num1,num2);
    return 0;
}

编译并执行三次:

可以看出,使用空指针0或者NULL作为参数得到的结果是一致的,但是每次执行的结果不一样。将时间函数作为随机种子:

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

int main(){
    int num;
    srand(time(0)); //将时间函数传入到随机数产生函数;
    printf("A set of random numbers:\n");
    for(int i = 0; i < 10; i++){
        num = rand()%100;
        printf("%d ",num);
    }
    putchar('\n');
    return 0;
}

执行结果:

在将时间函数作为随机种子之后,可以发现每次产生的随机序列都不在一样。此时。需要考虑如何产生一定范围内的随机数。rand()产生的是从0到RAND_MAX(32767)之间的伪随机数(正整数),如果我们想要1~100之间的随机序列呢?这里我们用到了取余%运算,一个正整数对5取模运算,产生的余数范围必在0~4之间。所以,对正整数进行模a的取余运算,得到的余数范围在0~a-1,如果对取余运算的结果加上b,得到的结果就在b~a+b-1之间。所以,我们要得到[M,N]区间内的随机数,函数rand()就要对(N-M+1)取余运算,再加上M。

编写一个输出包含100个[1,10]区间内整数的随机序列产生程序。

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

int main(){
    int num;
    srand(time(0));
    printf("A set of random numbers:\n");
    for(int i = 0; i < 100; i++){
        num = rand()%10+1;
        printf("%d ",num);
    }
    putchar('\n');
    return 0;
}

编译并执行两次:

相关阅读

iSCSI协议简介

本文综合了几篇参考文献的内容,做了删减与重组,但严格来说,不算原创。 笔者笔记如下: iSCSI initiator和target的核心功能都在内核中,

mapreduce编程初探

1.map和reduce 1.1 mapReduce处理逻辑 在本系列文章的第一篇中,曾对MapReduce原理做过简单的描述,在这里再重述一遍。 首先我们

Java爬虫系列:使用HttpClient抓取页面HTML

今天就来介绍下抓取html内容的工具:HttpClient。 围绕下面几个点展开: 1.什么是HttpClient 2.HttpClient入门实例 3.复杂应用 4.结

macOS 开发 - 添加可执行程序 Command Line Tool

文章目录添加步骤成功验证其他说明 添加步骤 1、选中左侧最上方,总工程菜单。点击栏目下方添加;2、在弹窗中搜索 command, 方便快速

反应堆模式(reactor)

在提到高性能服务器编程的时候肯定有听过reactor模式,如果只是简单的写一个服务器和客户端建立连接的程序来熟悉一下使用socket函

分享到:

栏目导航

推荐阅读

热门阅读