• js随机数


    引子:
        在写程序间突然需要用到随机数,于是用到了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 ,根据数据可以看出,这种生成随机数的方式比之第一种要更加的均匀

    尾语:

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

  • 相关阅读:
    开始之旅9.18
    驱动学习
    Extjs TextField扩展
    数据结构经典算法java
    JAVA BeanUtil应用 一个类向另一个类转换
    Extjs timefield
    图片压缩成指定大小
    js正则表达式提取字符串中的数字
    STM32笔记记录2
    #ifdef,#else,#endif,#if用法详解
  • 原文地址:https://www.cnblogs.com/crisenchou/p/5961928.html
Copyright © 2020-2023  润新知