生成随机数的N种方式
首先需要说明的是,计算机中生成的随机数严格来说都是伪随机,即非真正的随机数,真正随机数的随机样本不可重现。那么我们来看看代码中有哪些方式可以生成随机数。
rand
rand函数声明如下:
#include <stdlib.h>
int rand(void);
rand函数返回[0,RAND_MAX)范围的随机整数,在我的机器上,RAND_MAX为2147483647。
使用示例:
#include<stdlib.h>
#include<stdio.h>
int main(void)
{
int i = 0;
while(i < 5)
{
printf("%d ",rand());
i++;
}
printf("\n");
return 0;
}
编译运行:
$ gcc -o rand rand.c
./rand
1804289383 846930886 1681692777 1714636915 1957747793
多运行几次,你就会惊喜地发现,每次运行的结果都是一样的!!!这还玩个毛线?
srand
别急,rand虽然每次运行的结果都是一样的,那是因为它的种子默认为1。每一个种子会有一串看似随机的序列,每次取下一个出来,整体都近乎是随机分布的。但是如果你的种子每次都是一样的,那么每次运行可能得到的结果也是一样的。我们需要利用srand给它一个种子。
#include <stdlib.h>
void srand(unsigned int seed);
为了保证我们每次的得到的随机数不一样,我们必须在每次调用时,都确保种子不一样,因此通常会选择使用时间作为种子,注意这只是通常的种子选择,你可以根据实际使用需求进行选择。
于是我们在使用之前设置好种子,使用示例:
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
int main(void)
{
srand(time(NULL));//设置随机种子,注意只需要设置一次即可
int i = 0;
while(i < 5)//生成5个随机数
{
printf("%d ",rand());
i++;
}
printf("\n");
return 0;
}
现在好了,每次运行生成的都不一样了。但是还有一个问题,如果这种方式在多线程下使用,也是不可取的,因为rand不是可重入函数。它的每次调用都会修改一些隐藏的属性,因此在多线程中使用它并不合适。
rand_r
为了在多线程下使用,我们使用rand_r,使用方式和rand是一样的:
#include <stdlib.h>
int rand_r(unsigned int *seedp);
使用示例:
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
int main(void)
{
unsigned int seed = time(NULL);
int i = 0;
while(i < 5)//生成5个随机数
{
printf("%d ",rand_r(&seed));
i++;
}
printf("\n");
return 0;
}
多线程中,多个线程可能几乎同时调用,那它们的种子可能也一样,如果想不一样,还可以将种子设置成和线程id有关。
unsigned int seed = time(NULL)^pthread_self();
random
通过前面的例子可以发现,rand生成的整数范围是有限的,为了生成更大范围,可以使用random:
#include <stdlib.h>
long int random(void);
void srandom(unsigned int seed);
random返回的类型为long int,因此在一定程度上,它生成的范围要大得多。另外与rand类似,需要使用srandom函数设置种子。具体的例子就不再放出了。
生成指定范围随机数
前面的例子都是生成[1,RAND_MAX]之间的数,如果要生成指定区间的随机数呢?假设a和b不超过int范围以及它们的差值不超过rand的生成范围。
[a,b)
左闭右开区间,即包含a,不包含:
(rand() % (b - a)) + a;
[a,b]
左闭右闭,即包含a和b:
(rand() % (b - a + 1)) + a;
(a,b]
左开右闭,即不包含a,包含b:
(rand() % (b-a)) + a + 1;
[0,b]
rand() % b ;
0到1之间的浮点数
rand()/(double)RAND_MAX;
生成随机数的N种方式的更多相关文章
- Java生成随机数的4种方式
Random Random 类诞生于 JDK 1.0,它产生的随机数是伪随机数,也就是有规则的随机数.Random 使用的随机算法为 linear congruential pseudorandom ...
- Java生成随机数的三种方式
package cn.zytao.taosir.random; import java.util.Random; public class RandomDemo { private static In ...
- java产生随机数的几种方式
java产生随机数的几种方式 一.在j2se里我们可以使用Math.random()方法来产生一个随机数,这个产生的随机数是0-1之间的一个double,我们可以把他乘以一定的数,比如说乘以100,他 ...
- c#封装DBHelper类 c# 图片加水印 (摘)C#生成随机数的三种方法 使用LINQ、Lambda 表达式 、委托快速比较两个集合,找出需要新增、修改、删除的对象 c# 制作正方形图片 JavaScript 事件循环及异步原理(完全指北)
c#封装DBHelper类 public enum EffentNextType { /// <summary> /// 对其他语句无任何影响 /// </summary> ...
- php生成随机数的三种方法
php生成随机数的三种方法 如何用php生成1-10之间的不重复随机数? 例1,使用shuffle函数生成随机数. <?php$arr=range(1,10);shuffle($arr);for ...
- python 全栈开发,Day94(Promise,箭头函数,Django REST framework,生成json数据三种方式,serializers,Postman使用,外部python脚本调用django)
昨日内容回顾 1. 内容回顾 1. VueX VueX分三部分 1. state 2. mutations 3. actions 存放数据 修改数据的唯一方式 异步操作 修改state中数据的步骤: ...
- Pandas 基础(3) - 生成 Dataframe 的几种方式
这一节想总结一下 生成 Dataframe 的几种方式: CSV Excel python dictionary List of tuples List of dictionary 下面分别一一介绍具 ...
- 数据可视化之powerBI技巧(七)从Excel到PowerBI,生成笛卡尔积的几种方式
假如分别有100个不重复的姓和名,把每个姓和名进行组合匹配,就可以得到一万个不重复的姓名组合,这种完全匹配的方式就是生成一个姓名的笛卡尔积. 下面就来看看生成笛卡尔积的几种方式,为了展现的方便,以5个 ...
- spring生成EntityManagerFactory的三种方式
spring生成EntityManagerFactory的三种方式 1.LocalEntityManagerFactoryBean只是简单环境中使用.它使用JPA PersistenceProvide ...
随机推荐
- 2021.8.6考试总结[NOIP模拟32]
T1 smooth 考场上水个了优先队列多带个$log$,前$80$分的点跑的飞快,后面直接萎了. 其实只需开$B$个队列,每次向对应队列中插入新的光滑数,就能保证队列中的数是单调的. 为了保证不重, ...
- 2021.7.27考试总结[NOIP模拟25]
罕见的改完了题 T1 random 一堆概率,一堆函数,一堆递归,一眼不可做, 但它只有一个参数,所以.. 熠神本着"只有20太难看"的心态,通过样例三个出规律,口胡了一波$\fr ...
- 生产环境部署springcloud微服务启动慢的问题排查
今天带来一个真实案例,虽然不是什么故障,但是希望对大家有所帮助. 一.问题现象: 生产环境部署springcloud应用,服务部署之后,有时候需要10几分钟才能启动成功,在开发测试环境则没有这个问题. ...
- PSS--待看
转载:浅谈可移植激励规范(PSS)复用策略_路科验证-CSDN博客 译者按 :当今硬件设计变得愈加复杂,如何创建出足够的测试来保证设计的正确性是每个硬件工程师需要面对的问题.Accellera的可移植 ...
- wpa_supplicant启动出错rfkill: Cannot open RFKILL control device
在板子是调试网络,千辛万苦把wpa_supplicant及其依赖都移植编译进来了,在板子上调试启动的时候启动报错了 D/wpa_supplicant( 1152): wpa_supplicant v2 ...
- 最短路计数(SPFA× Dijkstra√)
题目描述 给出一个n个顶点m条边的无向无权图,顶点编号为1−n.问从顶点1开始,到其他每个点的最短路有几条. 输入格式 第一行包含2个正整数n,m,为图的顶点数与边数. 接下来M行,每行2个正整数x, ...
- 前端---梳理 http 知识体系 1
最近看了http相关的知识点,觉得还是有必要整理下,这样对自己的网络知识体系也有帮助. http 是什么 http叫超文本传输协议,可以拆成超文本.传输.协议来理解 协议 http 是一个用在计算机里 ...
- Go语言核心36讲(Go语言进阶技术十四)--学习笔记
20 | 错误处理 (下) 在上一篇文章中,我们主要讨论的是从使用者的角度看"怎样处理好错误值".那么,接下来我们需要关注的,就是站在建造者的角度,去关心"怎样才能给予使 ...
- #web开发# 知道cookie hostonly属性的请举手。
Cookie常见姿势.疑难梳理 目前w3c定义浏览器存放每个cookie需要包含以下字段: cookie属性 基本描述 举例 备注 name=value cookie键值对 id=a3fWa expi ...
- 终论到底该不该写isDebugEnabled
以前: 很多日志框架都不支持{}模板的写法(如Log4j1.X, Apache Commons Logging),于是只能通过字符串拼接来输出日志内容: log.debug("debug日志 ...