JS语言里常见的随机函数示例,实验结果分布规律分析
在JavaScript语言里有个 Math.random() 随机函数,用于生成指定范围内的随机数。
Math.random()函数
根据官方的定义: Math.random() 函数返回一个浮点数, 伪随机数在范围[0,1),也就是说,从0(包括0)往上,但是不包括1(排除1),然后您可以缩放到所需的范围。实现将初始种子选择到随机数生成算法;它不能被用户选择或重置。
也就是说 random() 方法可返回介于 0 ~ 1 之间的一个随机数。比如:0.9322870363051519、0.08182448197313485、0.6718927278167157,每次调用它会返回一个含16位小数的随机浮点数。
我们日常代码过程中实际上是需要生成整数,或是指定区间的随机数,这就需要对它封装改造一下了。常见的封装改造有以下几种。
随机整数:floor + random
示例:生成随机整数,传入参数是最大值(不包括),即返回值是 [0, max)
function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
console.log(getRandomInt(3));
// expected output: 0, 1 or 2
console.log(getRandomInt(1));
// expected output: 0
指定区间的随机数(一)
示例:这个例子返回了一个在指定值之间的随机数 [min, max)。这个值不小于 min(有可能等于),并且小于(不等于)max。
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
console.log(getRandomArbitrary(1,3));
// expected output: 1.0501238302537486,1.9956248025522734,2.7839421306375227 ……
指定区间的随机数(二)
示例:这个例子返回了一个在指定值之间的随机整数 [min, max)。这个值不小于 min (如果 min 不是整数,则不小于 min 的向上取整数),且小于(不等于)max。
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值
}
console.log(getRandomInt(1,3));
// expected output: 1 or 2
也许很容易想到用 Math.round() 来实现,但是这会导致你的随机数处于一个不均匀的分布,这可能不符合你的需求。
指定区间的随机数(三)
上一个例子提到的函数 getRandomInt() 结果范围包含了最小值,但不含最大值。如果你的随机结果需要同时包含最小值和最大值,怎么办呢? getRoundRandom() 函数可以实现得到一个两数之间的随机整数,包括两个数在内。
示例:这个例子返回了一个在指定值之间的随机整数 [min, max]。这个值不小于 min (如果 min 不是整数,则不小于 min 的向上取整数),且不大于max(如果 max 不是整数,则不小于 max 的向下取整数)。
function getRoundRandom(min, max){
return Math.round(Math.random()*(max-min))+min;
}
console.log(myRoundRandom(1,3));
// expected output: 1, 2 or 3
需要注意:Math.round() 函数返回一个数字四舍五入后最接近的整数。它取整的结果分布不均,大概成正泰分布。验证:var num = getRoundRandom(0, 5); 生成5轮,每轮10000个结果分布如下:

指定区间的随机数(四)
得到一个两数之间的随机整数,包括两个数在内。如果想概率分布均匀一点可以使用 Math.trunc()
Math.trunc() 方法会将数字的小数部分去掉,只保留整数部分。Math.trunc() 的执行逻辑很简单,仅仅是删除掉数字的小数部分和小数点,不管参数是正数还是负数。传入该方法的参数会被隐式转换成数字类型。
示例:这个例子返回了一个在指定值之间的随机整数 [min, max]。这个值不小于 min,且不大于max。
function getTruncRandom(min, max){
return Math.trunc(Math.random()*(max-min+1))+min;
}
console.log(getTruncRandom(1,3));
// expected output: 1, 2 or 3
可以简写:const getTruncRandom=(min,max)=>Math.trunc(Math.random()*(max-min+1)+min);
验证:var num = getTruncRandom(0, 5); 生成5轮,每轮10000个结果分布如下:

指定区间的随机数(五)
前面例子提到的函数 getRandomInt() 结果范围包含了最小值,但不含最大值。如果你的随机结果需要同时包含最小值和最大值,怎么办呢? getRandomIntInclusive() 函数可以实现得到一个两数之间的随机整数,包括两个数在内。
示例:这个例子返回了一个在指定值之间的随机整数 [min, max]。这个值不小于 min (如果 min 不是整数,则不小于 min 的向上取整数),且不大于max(如果 max 不是整数,则不小于 max 的向下取整数)。
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random()*(max-min+1))+min; //含最大值,含最小值
}
console.log(getRandomIntInclusive(1,3));
// expected output: 1, 2 or 3
验证:var num = getRandomIntInclusive(0, 5); 生成5轮,每轮10000个结果分布如下:

总结
1,实验三采用round + random方式最终验证随机结果分布不均衡,不予采用;
2,实验四、实验五最终验证随机结果分布接近均衡,均可以采用;
3,实验四利用 trunc + random 实现方式简洁,运算次数更少,推荐采用;
附件代码:生成5轮,每轮10000个结果分布
<script>
// round + random()函数
function getRoundRandom(min, max){
return Math.round(Math.random()*(max-min))+min;
/* 实验结果
游戏开始:zero = 0 one =0 two =0 three =0 four =0 five=0
游戏结束:zero = 1034 one =2011 two =1965 three =2004 four =1978 five=1008
游戏结束:zero = 978 one =2097 two =1967 three =1947 four =2062 five=949
游戏结束:zero = 1083 one =2066 two =1933 three =1908 four =1986 five=1024
游戏结束:zero = 994 one =1974 two =2092 three =1918 four =1967 five=1055
游戏结束:zero = 1010 one =1979 two =2086 three =1970 four =1944 five=1011
*/
}
// trunc + random()函数
function getTruncRandom(min, max){
return Math.trunc(Math.random()*(max-min+1))+min;
/* 实验结果
游戏开始:zero = 0 one =0 two =0 three =0 four =0 five=0
游戏结束:zero = 1752 one =1607 two =1636 three =1631 four =1650 five=1724
游戏结束:zero = 1667 one =1660 two =1696 three =1654 four =1646 five=1677
游戏结束:zero = 1708 one =1658 two =1658 three =1724 four =1619 five=1633
游戏结束:zero = 1688 one =1620 two =1689 three =1664 four =1664 five=1675
游戏结束:zero = 1737 one =1644 two =1655 three =1656 four =1694 five=1614
*/
}
// ceil + floor + random()函数
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
}
function guess(){
var zero = one = two = three = four = five = 0; // 记录每个数出现次数
console.log('游戏开始:zero = '+zero+' one ='+one+' two ='+two+' three ='+three+' four ='+four+' five='+five);
for(var i=0; i<10000; i++)
{
// 自定义生成随机数
// var num = getRoundRandom(0, 5);
// var num = getTruncRandom(0, 5);
var num = getRandomIntInclusive(0, 5);
// 对结果类型计数
switch(num){
case 0: zero++; break;
case 1: one++; break;
case 2: two++; break;
case 3: three++; break;
case 4: four++; break;
case 5: five++; break;
default: console.error('生成数字错误 num='+num);
}
}
// 该轮结束输出结果类型计数
console.log('游戏结束:zero = '+zero+' one ='+one+' two ='+two+' three ='+three+' four ='+four+' five='+five);
}
guess();
</script>
【完】
JS语言里常见的随机函数示例,实验结果分布规律分析的更多相关文章
- 用python实现js语言里的特性
有大佬说:“搜 arraybuffer 的 polyfill 然后翻译成 python就行了” ...
- NODE.JS学习的常见误区及四大名著
NODE.JS学习的常见误区及四大名著 前段时间由于不满于社区里很多人对于NODE.JS的种种误解而写了一篇文章名为: NODE.JS之我见:http://www.cnblogs.com/pugang ...
- 【原】JS正则表达式里的控制符
正则表达式易于使用而又让人费解,乍一看上去,就像是一行行的乱码,但是它的功能确实又不容小觑.今天整理正则时,纠正了自己的一个误解. 先缕一缕: 正则表达式的两种声明方式: 字面量.构造器 (RegEx ...
- JS 语言核心(JavaScript权威指南第六版)(阅读笔记)
前言: 对于程序员,学习是无止境的,知识淘换非常快,能够快速稳固掌握一门新技术,是一个程序员应该具备的素质.这里将分享本人一点点不成熟的心得. 了解一门语言,了解它的概念非常重要,但是一些优秀的设计思 ...
- const分别在C和C++语言里的含义和实现机制
const的含义 简单地说:const在c语言中表示只读的变量,而在c++语言中表示常量. C语言 const是constant的缩写,是恒定不变的意思,也翻译为常量,但是很多人都认为被 ...
- ES6学习一 JS语言增强篇
一 背景 JavaScript经过二十来年年的发展,由最初简单的交互脚本语言,发展到今天的富客户端交互,后端服务器处理,跨平台(Native),以及小程序等等的应用.JS的角色越来越重要,处理场景越来 ...
- js currying & js 科里化
js currying & js 科里化 var test = ( function (a){ console.log(`a2 =`, a);// 1 // console.log(`b2 = ...
- 基于 React.js + Redux + Bootstrap 的 Ruby China 示例 (转)
一直学 REACT + METEOR 但路由部分有点问题,参考一下:基于 React.js + Redux + Bootstrap 的 Ruby China 示例 http://react-china ...
- 在js脚本里计算多个小数的加法问题
当在js脚本里计算多个小数的加法时,算得的结果往往会自动取整,这时候我们就应该加入以下代码: function toDecimal(x) { var val = Number(x); if (!isN ...
- c语言里用结构体和指针函数实现面向对象思想
一.基础研究 观察如下两个程序a.c和b.c: A.c: B.c: 这两个程序都是要实现在屏幕上第10行40列打印一个绿色的字符c: 这两个程序的数据组织方式是一样的,都是使用结构体,而且对共性和个性 ...
随机推荐
- 第139篇:JS数组常用方法(map(),reduce(),foreach())
好家伙,本篇为MDN文档数组方法的学习笔记 Array.prototype.reduce() - JavaScript | MDN (mozilla.org) 数组方法这块的知识缺了,补一下 1. ...
- 2022-01-11:给定一个正数数组arr长度为n、正数x、正数y。 你的目标是让arr整体的累加和<=0, 你可以对数组中的数num执行以下三种操作中的一种,且每个数最多能执行一次操作 : 1.
2022-01-11:给定一个正数数组arr长度为n.正数x.正数y. 你的目标是让arr整体的累加和<=0, 你可以对数组中的数num执行以下三种操作中的一种,且每个数最多能执行一次操作 : ...
- vue cli3 整合Cesium,处理build 时内存溢出问题
一直使用cesium,但是都是使用script直接引入的,但是在将其放置在增加路由的子页面中中时会出现一个问题,刷新后提示cesium is undefined 看直接引入cesium.js < ...
- golang依赖注入工具digo
golang依赖注入工具 digo工具地址:https://github.com/werbenhu/digo 特性 使用注释中的注解 自动代码生成 自动检测循环依赖 编译时期依赖注入 自动初始化 支持 ...
- CVE-2021-41773 apache路径遍历
来自tryhackeme的漏洞复现 CVE-2021-41773/42013 利用:路径遍历利用将允许服务器公开任意文件 需要启用mod_cgi模块才能获得远程代码执行 2021 年 10 月 5 日 ...
- 2023-06-11:redis中,如何在100个亿URL中快速判断某URL是否存在?
2023-06-11:redis中,如何在100个亿URL中快速判断某URL是否存在? 答案2023-06-11: 传统数据结构的不足 当然有人会想,我直接将网页URL存入数据库进行查找不就好了,或者 ...
- 从0搭建Vue3组件库(十):如何搭建一个 Cli 脚手架
本篇文章将实现一个名为create-easyest脚手架的开发,只需一个命令npm init easyest就可以将整个组件库开发框架拉到本地. 创建 Cli 包 首先,我们在 packages 目录 ...
- pcie reset系列之 内核框架
FLR是pci reset的一种. 关于FLR的寄存器操作比较简单, 相关的寄存器有: 配置空间里device cap里的FLR capability bit, 这个表示设备是否支持FLR. 配置空间 ...
- 【AI在网络安全中的应用:趋势和未来】展望
目录 [AI在网络安全中的应用:趋势和未来]- 展望 随着数字化和智能化的不断深入,网络安全问题越来越受到人们的关注.其中,人工智能技术在网络安全领域中的应用已成为当前研究的热点之一.本文将探讨AI在 ...
- WebAPI公开接口请求签名验证
前言 现在的系统后端开发的时候,会公开很多API接口 对于要登录认证后才能访问的接口,这样的请求验证就由身份认证模块完成 但是也有些接口是对外公开的,没有身份认证的接口 我们怎么保证接口的请求是合法的 ...