为什么当我给他一个负数和一个正数时,我的 JS 随机整数生成器如此错误

Why is my JS random ints generator so wrong when I give him one negative and one positive number?

本文关键字:一个 整数 随机 JS 错误 我的 为什么      更新时间:2023-09-26

所以我使用这样的脚本在范围内随机生成整数

function randomInRange(start, end)
{
  if ((start >= 0) && (end >= 0))
  {
    return Math.round(Math.abs(start) + (Math.random() * (Math.abs(end) - Math.abs(start))));
  }
  else if ((start <= 0) && (end <= 0))
  {
    return 0 - (Math.round(Math.abs(start) + (Math.random() * (Math.abs(end) - Math.abs(start)))));
  }
  else
  {
    return Math.round(((start) + Math.random() * (end - start)));
  }
}

你可以在这里看到它的工作。 对于正范围它是正确的,对于负范围它是正确的,但我得到混合的糟糕和错误的结果。为什么以及如何修复它?

我尝试使用类似Math.round(start + Math.random() * (end - start));的公式

如果你使用Math.round你会得到一个不均匀的分布。

例如,如果您要求 2 到 4 之间的数字,则只有 2.0 和 2.5 之间的随机数将四舍五入为 2,只有 3.5 和 4.0 之间的数字将四舍五入为

4,而 2.5 和 3.5 之间的数字将四舍五入为 3。这意味着 50% 的数字将是 3,而只有 25% 将是 2,25% 将是 4。

请改用Math.floor来获得随机数的均匀分布。

您不必检查startend的符号,表达式end - start + 1将是范围的大小,符号根据start的哪一侧而不同。

function randomInRange(start, end) {
  if (start > end) start++; else end++;
  return Math.floor((start + Math.random() * (end - start)));
}

演示:jsfiddle.net/guaEp/1/

校正:

如果start> end,表达式 end - start + 1 不起作用。如果上限是排除的,则表达式 end - start 有效,即范围 -10 到 11 返回 -10 到 10 之间的数字。我添加了代码,以便该函数采用包含上限并将其转换为独占。

也:

正如 davin 指出的那样,您正在馈送函数字符串,这将使函数连接字符串而不是进行算术运算。

只需使用 parseInt 函数将字符串转换为数字:

val.innerHTML = randomInRange(parseInt($('fnt').value), parseInt($('lint').value));

好的,我发现了问题,您正在对字符串执行代数(因为在您的代码中$('fnt').value是输入框的值,这是一个字符串(,而不是数字,所以像+这样的东西最终会连接字符串而不是添加它们的数字内容。在您的特定示例中,您有:

Math.round(((start) + Math.random() * (end - start)))

其计算结果为:

Math.round((('13') + Math.random() * ('-666' - '13'))) 

其计算结果为(例如(:

Math.round("13-339.44615370430984")

由于'13' + '-339.44615370430984'将被串联起来,最后Math.round调用将返回NaN

您应该具备:

function randomInRange(start, end) {
  start = Number(start); end = Number(end);
  return Math.round(start + Math.random() * (end - start));
}

或者更改传递到函数中的值,确保它们是数字。

function randomInRange(start, end) {
    return Math.round(start + Math.random() * (end - start));
}

应该工作。

jsFiddle 演示


更新:正如@Guffa正确指出的那样,分布不会均匀。您可以使用它:

return Math.floor(start-- + Math.random() * (end - start));

我懒得在你的代码中找到错误,但计算可以更容易地完成:

function randomInRange(start, end)
{
    //Extra variables to make it easier to understand
    var rangeBegin = Math.min(start,end);
    var rangeEnd = Math.max(start,end);
    var rangeSize = rangeEnd-rangeBegin+1;    
    var seed = Math.random();
    var result = Math.floor((seed*rangeSize)+rangeBegin);
    return result;
}