博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js随机数
阅读量:4567 次
发布时间:2019-06-08

本文共 2260 字,大约阅读时间需要 7 分钟。

引子:

    在写程序间突然需要用到随机数,于是用到了js的Math.random随机函数,生成指定范围内的随机数,根据网上流传的写法生成指定范围内的随机数如下

function random(min, max){    return Math.round(Math.random()*(max-min))+min;}var zero = one = two = three = 0;for(var i=0;i<10000;i++){    var num = random(0,3);    if(num==0){        zero++;    }else if(num==1){        one++;    }else if(num==2){        two++;    }else if(num==3){        three++;    }else{        console.log("assert false");    }}console.log(zero,one,two,three);

经过10000次计算,在0-3范围内生成的结果数据如下,0=1670次 1=3348次 2=3266次 3=1717次

发现这个算法略坑,min以及max的边界命中率简直低的可怜,根本不是均匀分布,反而有点像正态分布,只能改进重写了

Math.random()函数

  根据官方的定义:random() 方法可返回介于 0 ~ 1 之间的一个随机数。那么猜想在0~1之间,如果对生成的随机数进行四舍五入,那么该概率在(0,1)是呈均匀分布状态,也就是说出现0或者是1的概率是相等的,接下来验证猜想

function guess(){    var zero = 0;    var one = 0;    for(var i=0;i<100000;i++){        Math.round(Math.random()) ==1 ? one++ : zero++;    }    return zero+"  "+one;}for(var i=0;i<10;i++){    var g = guess();    console.log(g);}

运行结果如下

50093  49907
49787  50213
49862  50138
49948  50052
49820  50180
50158  49842
50179  49821
49967  50033
49920  50080
50063  49937
从数据结果中可以看出,对随机数四舍五入之后,出现0和出现1的概率呈均匀分部状态,测试次数无穷大的情况下,那么出现1或0的概率的极限都是1/2,根据这个特性,由二进制开始联想,那么在指定位数的情况下,在这个区间内,每一个数出现的概率也是均匀分布的,概率各为1/2^n,于是就有了下面的验证程序如下

var Helpers = {    getbit: function(num){        var bit = 0;        while(num>0){            num = num>>1;            bit++;        }        return bit;    },    randomBin : function(times){        var num = Math.round(Math.random());        while(times>1){            num = (num<<1) + Math.round(Math.random());            times--;        }        return num;    },    random : function(min,max){        var num = max-min;        var times = this.getbit(num);        do{            var binNum = this.randomBin(times);        }while(!(binNum<=num));        return binNum+min;    }}var zero = one = two = three = 0;for(var i=0; i<=10000; i++){    var n = Helpers.random(0,3);    if(n == 0){        zero++;    }else if(n == 1){        one++;    }else if(n == 2){        two++;    }else if(n == 3){        three++;    }}console.log(zero,one,two,three);

运行10000次的结果:2523 2548 2416 2514 ,根据数据可以看出,这种生成随机数的方式比之第一种要更加的均匀

尾语:

  虽然复用代码是一个好习惯,但是不要盲目的去复用他人的代码,靠巧合编程是无法长久的,惟有不断的提升自己,才会觉得数学与计算机真的是非常的有趣。

转载于:https://www.cnblogs.com/crisenchou/p/5961928.html

你可能感兴趣的文章
python3之运算符
查看>>
创建控制器的方法、控制器加载view过程、控制器view的生命周期、多控制器组合...
查看>>
Angualr6访问API
查看>>
使用SQLAlchemy对博客文章进行分页
查看>>
spell checking
查看>>
Java设计模式视频讲解
查看>>
面试 9:Java 玩转冒泡排序
查看>>
线程初步了解 - <第一篇>
查看>>
NET(C#):使用HttpWebRequest头中的Range下载文件片段
查看>>
scrollTop()--返回或设置匹配元素的滚动条的垂直位置
查看>>
JavaScript学习 - 基础(八) - DOM 节点 添加/删除/修改/属性值操作
查看>>
解决SharePoint2010文档库中新建文档不是保存到文档库而是保存到本地电脑的问题...
查看>>
hadoop3.0新特性及新功能
查看>>
数据库面试常问的一些基本概念
查看>>
Intent中的四个重要属性——Action、Data、Category、Extras
查看>>
Android 自定义 ViewPager 打造千变万化的图片切换效果
查看>>
泛型集合的运用--DataSet转换为泛型集合
查看>>
IsBackground的理解
查看>>
Java中的Scoket编程
查看>>
WPF邮件群发工具开发 之 进度条(属性改变通知机制)的实现
查看>>