为什么要将Math.floor与Math.random相结合?

13

为什么有人会在 Math.random 的结果上调用 Math.floor?我看到过它被这样使用:

Math.floor(Math.random() * num);

可以有人解释一下吗?


@quixoto 因为我看到这段代码很多次了,所以才说“我们”,不过我会改的。 - Aziz Al-ghannam
1
我并不是在批评你的措辞。对于这种问题,实际上说明它是你经常看到的东西,或者在某种类型的代码中经常看到,这样人们就有了背景和知道如何最好地回答你的方式。 - Ben Zotto
7个回答

19

Math.random 返回一个在0到1之间的 浮点数

返回一个范围在 [0, 1) 的浮点伪随机数,即从 0(包括)到 1(不包括)之间的数,然后您可以根据自己的需求进行缩放。

将此乘以n会得到一个在 0(包括)到 n(不包括)之间的浮点数。

然后使用 Math.floor 将该浮点数转换为介于 0 和 n - 1(包含)之间的整数


Math.random() 是否真的包括 0?我在一个 while 循环中运行了 1 百万次,它没有生成过 0 :/ 我问这个问题是因为某些计算,如 Math.ceil(Math.random() * 10)Math.floor(Math.random() * 10 + 1) 更简洁。 - oldboy
@oldboy 因为JavaScript使用双浮点数,所以似乎获得特定值的概率约为1/2^53 ~ 1/10^16。在1百万次尝试中获得成功的概率几乎为零。请参见 https://stackoverflow.com/questions/52048999/can-math-random-exactly-equal-5 和 https://lemire.me/blog/2017/02/28/how-many-floating-point-numbers-are-in-the-interval-01/。 - leonbloy

17
为什么有人要对Math.random的结果调用Math.floor函数呢?
简单来说,当你想将小数值截断为最接近的整数时,就会调用Math.floor()函数(通过丢弃小数部分)。例如,3.9变成3,2.1变成2等等。因此,在需要整数且你想要小于或等于小数值的整数时,通常会使用它。Math库还提供了Math.ceil()和Math.round()函数。Math.ceil()可以得到下一个较大的整数,Math.round()则四舍五入至最接近的整数,取决于哪个更接近。
我见过这样的用法:Math.floor(Math.random() * num);Math.floor(Math.Random() * num)拆分成各个部分并解释每个部分,你会得到以下内容:
Math.random()会给你一个0到1之间(包括0但不包括1)的随机小数。它可能会给你像0.38548569372这样的值。 Math.random() * num会给你一个0到num之间(包括0但不包括num)的随机小数。所以如果num是10,它可能会给你3.8548569372Math.floor(Math.random() * num))会给你一个0到num之间(包括0但不包括num)的随机整数。所以它可能会给你3
Math.floor()会将小数截断为只保留整数部分。随机整数通常用于从数组中获取随机值(需要是整数)。

抱歉打断一下,但是为了澄清一下... floor 是向下取整,而 ceiling 是向上取整吗? - Myles
1
@Myles - Math.floor() 返回比输入小的最大整数。Math.ceil() 返回比输入大的最小整数。Math.round() 检查输入值并返回最接近它的下一个较小或较大的整数,具体取决于哪个更接近。将来,MDN 网站 是所有这些类型问题的绝佳参考。 - jfriend00

2

Math.random()会返回一个长长的、随机的小数。通常我们会将这个小数乘上10、100、1000等来得到一个随机的整数。但由于这样的小数太长,为了得到一个绝对的整数,你需要使用Math.floor()函数将它向下取整。


2
为什么要将Math.floorMath.random结合使用?
结合使用是为了避免返回浮点数。使用Math.floor可以确保返回指定范围内的整数。
Math.random返回介于0和1之间的浮点数。将它乘以您的num或最大范围得到一个具有该数字最大值(1 * num)的值。因此,Math.floor只是强制使其成为整数。
幕后:随机数-> .35-> 11的最大值(num)乘以->获得3.85-> Math.floor(3.85)-> 3。
请注意,num是MAX + 1。将num设置为5只会生成1-4的数字!
您可以查看以下链接获取更多信息:http://www.javascriptkit.com/javatutors/randomnum.shtml 完成 :)

2

这是用于获取0到(max-1)之间整数随机数的函数。

另一方面,可以使用| 0更快地实现:

const randomInt = Math.random() * num | 0;
| 0是对0进行二进制或运算,JavaScript规范有效地表示在执行|操作之前将结果转换为整数。请注意,| 0Math.floor不同。 | 0四舍五入到0,而Math.floor向下取整。
         | 0   Math.floor         
------+------+------------
  2.5 |   2  |   2
  1.5 |   1  |   1
  0.5 |   0  |   0
 -0.5 |   0  |  -1
 -1.5 |  -1  |  -2
 -2.5 |  -2  |  -3

对我来说,位运算符感觉就像是 JavaScript 中的暗网等效物,你绝对需要能够看到矩阵绿色文本才能知道如何、何时以及在哪里使用这些东西。 - eballeste
我不认为这是暗网。我认为这是学习你正在使用的语言。每种语言都有其惯用语。人们无处不在地使用 value = maybeValue || defaultValue 以及 value = condition && expression,两者看起来都像巫术,但你会习惯的。 |0 也类似。你只需要查找它的含义,现在它就是你知识的一部分了。 - gman
没事,我只是在用隐喻的方式说话,对于位运算符及其工作原理以及人们如何使用它们,我始终难以理解,现在仍然不明白... - eballeste

1
var num = Math.floor(Math.random() * 1000); // e.g. 885

var flNum = Math.random() * 1000; //e.g. 885.9936205333221

尝试使用Math.random() * 1000作为示例,您可能会得到类似于885.9936205333221的结果。在许多情况下,我们需要一个四舍五入的数字,因此许多开发人员将其与Math.floor或Math.ceil一起使用以获得像885这样的整数。如果在您的情况下,您不介意使用浮点数,请将其保留为原样...
有关Math.floor如何工作的更多信息,请查看此链接:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math/floor


1

Math.random() 返回类似于 0.8747230430599302 的值,范围在 [0,1) 之间。

我们使用 .floor 将其向下舍入到最近的整数。例如:

Math.random()*5 == 2.5889716914389282 这将生成一个介于 [0,5) 之间的数字。

Math.floor(Math.random()*5) == 2 //在这种情况下 生成一个介于 [0,4] 之间的数字。


Math.random() 是否真的包括 0?我在一个 while 循环中运行了 1 百万次,它没有生成过 0 :/ 我问这个问题的原因是因为某些计算,如 Math.ceil(Math.random() * 10)Math.floor(Math.random() * 10 + 1) 更简洁。 - oldboy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接