Math.random()
在我的控制台中返回一个二进制小数点后 17 位的数字,因此它恰好为 0 的概率非常低。从技术上讲,它可以是 0,但永远不可能是 1,因为它基本上永远不会返回这些数字中的任何一个,这到底有什么意义呢?是什么导致了这一点?有人能给我一些与 Math.random()
的属性相关的例子吗?
通常为了生成随机浮点值,首先生成随机整数,然后将其缩放到浮点范围。由于浮点值的二进制表示形式,在 0 和 1 之间存在 2 的幂均匀分布的值(不包括 1.0)。如果确实包含 1.0,则范围是 2 的幂加一;生成这样一个范围内的均匀随机整数要困难得多。
除此之外,返回 1.0 只会导致问题。将其乘以一个常数后,您最终获得该常数的机会极小,但仍然有机会。即使在使用舍入到最近值进行量化之后,与任何其他值相比,您仍然只有一半的发生机会(零除外,它也会受到相同的惩罚)。
所以它更容易做,而且更有用。
也就是说,这里没有必要对“完美”均匀分布大惊小怪。只需将浮点值(本质上仅限于某些有限值集)乘以常数并对结果进行量化,您最终会得到一些结果比其他结果稍微(无法估量)更有可能的结果。
有人可以给我一些与
Math.random()
的属性相关的例子吗
假设我们有一个三元素数组:
[0, 1, 2]
要选择一个随机的、没有任何偏差的元素,我们实际上想要排除 1 的属性。 继续这个数组的示例:
我们需要使用类似
3*Math.random()
Math.trunc
(或
Math.floor
),最终获得索引(我们特别不想使用
Math.round
之类的东西,例如,这样会,该指数
0
只有其他指数获得的一半机会)。
3
(由于从
1
返回random()
)会导致越界错误(这在sh1的答案中已经指出)。
但也许更重要的是,即使存在某种将索引限制在数组范围内的故障安全机制,我们也恰恰需要排除的 1.0
才能使概率均匀分布在所有三个值上。这是因为 Math.trunc
将有效地创建这些间隔,并具有以下行为:
索引 0
[0;1)
索引 1
[1;2)
index 2
[2;3)
(我们不希望这个区间包含在内。我们希望它与其他区间相同。)
0.1172250276084208
的分辨率值很可能需要转换为某些所需的分辨率,因此此属性非常需要
trunc
产生所有具有相同跨度的间隔。