javascript笔记之随机数函数

API介绍

Math.random

Math.random可以产生一个0-1间的随机数(包括0,不包括1)

1
Math.random(); // 获取一个大于等于0,小于1的随机数

Math.round

Math.round 返回一个数字四舍五入后最接近的整数

1
2
3
4
5
6
7
8
9
10
11
12
Math.round(20.49); // 20
Math.round(20.5); // 21
Math.round(-20.5); // -20
Math.round(-20.51); // -21
Math.round(0.5); // 1
Math.round(0.49); // 0
Math.round(-0.5); // 0
Math.round(-0.51); // -1
// 随机获取0和1
Math.round(Math.random());
// 获取0到10的随机整数, 包括0和10
Math.round(Math.random() * 10);

Math.floor

Math.floor 返回小于或等于一个给定数字的最大整数,即向下取整。

1
2
3
4
5
6
7
Math.floor( 45.95); // 45 
Math.floor( 45.05); // 45
Math.floor( 4 ); // 4
Math.floor(-45.05); // -46
Math.floor(-45.95); // -46
// 获取0到10的随机整数, 不包括10
Math.floor(Math.random() * 10);

Math.ceil

Math.ceil 返回大于或等于一个给定数字的最小整数,即向上取整。

1
2
3
4
5
6
7
8
Math.ceil( 45.95); // 46
Math.ceil( 45.05); // 46
Math.ceil( 4 ); // 4
Math.ceil(-45.05); // -45
Math.ceil(-45.95); // -45
// 获取0到10的随机整数, 包括0和10
// 注意:只有Math.random为0的时候才为0,所以出现0的概率会比较低
Math.ceil(Math.random() * 10);

如何使用

当我们需要获取一组连续随机数的时候,我们希望这一组连续随机数是均线分布的,也就是在这一组随机数中,每一个具体数字出现的概率都是相当的。

例如,我们希望以相等的概率随机出现0或者1,我们实际上可以通过计算落在(0, 0.5),(0.5, 1)这两个区间内的累积概率分别代表0,和1。

因此,当我们需要获得指定区间的随机数时,我们可以在 Math.random()上乘以一定的数值,把整个区间范围拉长放大,例如,我们需要返回 [1,10] (注意是闭区间,包括1和10),我们可以用Math.floor(Math.random()*10+1)获得.

之所以使用 floor 函数向下取整,而不能使用 round 函数四舍五入取整,round 取整后得到的是非均匀分布。

因为我们要每个数字出现的概率相等,就要保证每个区间长度相等,使用 round 取整后, 映射到1的区间为(1,1.5) 映射到2的区间为(1.5, 2.5)…… (9.5,10.5),(10.5,11) 可见其区间长度是不同的,即1和11出现的概率为其他数字出现概率的一半。通过代码测试下:

使用Math.floor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 
var temp;
var arr={};
var t = 1000000;
for(var i=0;i<t;i++){
temp=Math.floor(Math.random()*10+1);
arr[temp]=(arr[temp]?arr[temp]:0)+1;
}
console.log(arr)
for (var j in arr) {
console.log(`得到${j}的概率:` + arr[j]/t);
}
// 可以看到出现各个值的概率是基本相等的。
/*
"得到1的概率:0.036753"
"得到2的概率:0.036697"
"得到3的概率:0.036808"
"得到4的概率:0.037075"
"得到5的概率:0.036365"
"得到6的概率:0.037077"
"得到7的概率:0.036649"
"得到8的概率:0.036889"
"得到9的概率:0.036621"
"得到10的概率:0.036676"
*/

使用 round:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var temp;
var arr={};
var t = 1000000;
for(var i=0;i<t;i++){
temp=Math.round(Math.random()*10+1);
// var index = temp>0?(temp-1):temp;
// console.log(arr[temp]);
arr[temp]=(arr[temp]?arr[temp]:0)+1;
}
console.log(arr)
for (var j in arr) {
console.log(`得到${j}的概率:` + arr[j]/t);
}
// 得到1和11的概率为其他数字的一半。
/**
"得到1的概率:0.01608"
"得到2的概率:0.031666"
"得到3的概率:0.031815"
"得到4的概率:0.031614"
"得到5的概率:0.031795"
"得到6的概率:0.031918"
"得到7的概率:0.032079"
"得到8的概率:0.031509"
"得到9的概率:0.031664"
"得到10的概率:0.031598"
"得到11的概率:0.016016"
*/

所以Math.random服从 [0,1) 区间的均匀分布,因为均匀分布是连续性分布,我们也可以说是Math.random服从 (0,1)区间的均匀分布,这不影响我们使用累计概率密度。

因此,如果想获得 [min, max], 可以使用 Math.floor(Math.random() * (max - min + 1)) + min;

如果想获得 [min, max), 可以使用 Math.floor(Math.random() * (max - min )) + min;

如果想获得 (min, max], 可以使用 Math.ceil(Math.random() * (max - min )) + min;

获取随机颜色

下面是百度 2014年秋校园招聘 中,web前端开发岗位 的一道题,要求生成随机颜色,我们指定颜色的rgb表示方式中,三个值都是0到255之间的数字,那么我们如果能随机生成三个[0,255]的数字,那就能随机组成一个颜色值了,实现代码如下:

1
2
3
4
5
6
function randomRGB(){
var rc = function(){
return Math.floor(Math.random()*(255+1));
}
return `rgb(${rc()},${rc()},${rc()})`
}

参考

产生服从均匀分布随机数