为javascript编写一个真正包容的随机方法

IT技术 javascript math random
2021-03-19 05:56:45

Javascript 的 MATH 对象有一个随机方法,它从集合 [0,1) 0 inclusive, 1 excludes 中返回。有没有办法返回一个真正随机的方法,其中包括 1.

例如

var rand = MATH.random()*2;

if(rand > 1)
{
   rand = MATH.floor(rand);
}

return rand; 

虽然这总是从集合 [0,1] 中返回一个数字,但它并不是真正随机的。

6个回答

这将返回 [0,1] 包括:

if(MATH.random() == 0)
    return 1;
else
    return MATH.random();

说明:如果第一次调用 random() 返回 0,则返回 1。否则,再次调用 random,即 [0,1)。因此,它将返回 [0,1] 全包。

我想很难说统一,但 +1 表示带回 1。
2021-04-27 05:56:45
如果第一个 random() 调用不是 0,则第二个 random() 调用可能是。
2021-05-08 05:56:45
@Gaby 这确实包括 0。
2021-05-09 05:56:45
正如您在对 nickf 的评论中提到的,这也不包括 0
2021-05-11 05:56:45
@Justin ,是的,我从 Trevor 的后续评论中理解了这一点。谢谢
2021-05-12 05:56:45

说白了,你想做的事没有意义。

请记住,在连续概率分布下,获得特定值的概率是无穷小的,因此从数学上讲,您永远不会看到 1 的确切值。

当然,在计算机世界中,RNG 的分布并不是真正连续的,因此您“可能”会遇到一个特定的值(听起来很傻),但概率会非常小,以至于在实践中你永远不会观察到它。

为了更清楚地说明这一点:如果您确实设法根据双精度浮点数编写了这样的函数,那么准确获得 1 的概率约为 2 -64如果每秒调用该函数 100 万次,则必须等待大约 600,000 年才能得到 1。

感谢您的回复。我认为这只是我正在做的一种形式不佳的练习。练习是使用随机方法编写您自己的 Math 对象,该方法将 min、max 和 inclusive 作为参数。包含参数是一个布尔值,表示您希望集合是包含的还是不包含的。现在,正如我在最初的问题中指出的那样,Math.random() 函数既不包含也不排斥,因为它包含 0 但不包含 1。所以编写一个真正包含或排斥且均匀分布的随机方法是不可能的,对吧?
2021-04-25 05:56:45
这并非不可能,因为实际上 RNG 只能生成有限数量的介于 0 和 1 之间(而不是连续体)的值。然而,这样做在数学上是荒谬的。该练习要么专门针对整数,要么是一个糟糕的问题。此外,扩展离散均匀分布以形成另一个均匀分布并非易事。Trevor 和 Brian McKenna 的解决方案非常接近,但并不完全一致。
2021-04-26 05:56:45

Math.random函数返回一个介于 0 和 1 之间的随机数,其中 0 是包含的,1 是不包含的。这意味着将随机数正确分配为区间中的整数的唯一方法是使用独占上限。

要指定包含的上限,您只需添加一个以使其在计算中不包含。这将在 7 和 12 之间正确分配随机数,包括:

var min = 7;
var max = 12;
var rnd = min + Math.floor(Math.random() * (max - min + 1));
+1 对于定义任意随机范围的经典方法
2021-05-08 05:56:45

从我从 Chrome 中的 JavaScript 控制台看到的,Math.random()生成一个从 0 到 0.9999999999999999 的数字。考虑到这一点,您可以通过添加修饰符来获得所需的内容。例如,这里有一个函数可以为您提供 0 和 1 之间的准随机浮点数,其中 1 包括在内:

function randFloat() {
  // Assume random() returns 0 up to 0.9999999999999999
  return Math.random()*(1+2.5e-16);
}

您可以在控制台中按 Enter 尝试此操作0.9999999999999999*(1+2.5e-16)- 它会返回 1。您可以进一步使用此函数返回 0 到 1024(含)之间的浮点数:

function randFloat(nMax) {
  // Assume random() returns 0 up to 0.9999999999999999
  // nMax should be a float in the range 1-1024
  var nMod;
  if (nMax<4) nMod = 2.5e-16;
  else if (nMax<16) nMod = 1e-15;
  else if (nMax<32) nMod = 3.5e-15;
  else if (nMax<128) nMod = 1e-14;
  else if (nMax<512) nMod = 3.5e-14;
  else if (nMax<1024) nMod = 1e-13;
  return Math.random()*(nMax+nMod);
}

某处可能有更有效的算法。

你想让它包括 1?

return 1 - Math.random();

但是,我认为这是暗示其他问题的问题之一。为什么需要包含1?可能有更好的方法来做到这一点。

是的,但他没有说排除0是问题,只是排除1是问题。
2021-04-25 05:56:45
这将是 0 独占现在 .. 不是吗?
2021-05-02 05:56:45