Math.random() 帮助获取 '+N' 和 '-N' 随机数(不包括特定范围)

Posted

技术标签:

【中文标题】Math.random() 帮助获取 \'+N\' 和 \'-N\' 随机数(不包括特定范围)【英文标题】:Math.random() help get '+N' and '-N' randoms ( excluding specific range )Math.random() 帮助获取 '+N' 和 '-N' 随机数(不包括特定范围) 【发布时间】:2011-10-28 07:05:51 【问题描述】:

我需要一点关于 Math.random() 的帮助: 我必须旋转一些图像(使用 CSS3 变换 (deg)) 从-40+40 获取结果的方式但跳过范围的结果:-20+20

如果我没记错的话,这会给我从 -40+40

范围内的随机结果
  var counter = Math.round(Math.random()*81)-40;

如何从结果中排除 -20 和 +20 之间的数字 ???

【问题讨论】:

【参考方案1】:

随机 -1 或 1 乘以 0-20 随机加 20,可以工作

(Math.random()<.5?-1:1)*Math.floor(Math.random()*20 + 21);

1300 次运行的样本结果(为简单起见仅显示正面):

Number_21: 70
Number_22: 62
Number_23: 56
Number_24: 57
Number_25: 79
Number_26: 57
Number_27: 64
Number_28: 60
Number_29: 57
Number_30: 67
Number_31: 63
Number_32: 81
Number_33: 81
Number_34: 65
Number_35: 59
Number_36: 59
Number_37: 62
Number_38: 71
Number_39: 52
Number_40: 78

【讨论】:

Math.random() 返回一个介于 0 和 1 之间的浮点数。因此,如果 Math.random() 小于 0.5,则返回负数 1,否则返回 1。基本上,它允许大约一半的代码运行将乘以负数。 不是,不是。如果你想要整数的可读性,那么你可以使用 Math.round,但它不是必需的。 此解决方案与 Xeon06 的问题相同。 -40、-20、20 和 40 的给出频率是其他整数的一半。所以它不是均匀分布。【参考方案2】:

我会生成一个介于 20 到 40 之间的随机数,然后随机取反。

var counter = (Math.round(Math.random() * 20) + 20) * (Math.random() < 0.5 ? 1 : -1);

【讨论】:

确实,抱歉耽误了我的测试。问题没有说,但是在给出“随机”答案时,我认为除非另有说明,否则应该预期均匀分布。此解决方案获得 -40、-20、20 和 40 的频率是该范围内其他整数的一半。 哦,这很有趣。我很讨厌概率。为你的答案 +1【参考方案3】:

修改现有答案以给出统一的分布范围 -40 到 -21 和 21 到 40:

(Math.random()<.5?-1:1)*(Math.floor(Math.random()*20) + 21)

【讨论】:

所以,只是为了做一个简历:如果状态*21 比结果是......? 40 - 21,对吧?! -40 到 -20 和 20 到 40:(Math.random()<.5> 对,我不需要 +|- 20,只要从 21 到 40!干得好 user12861!【参考方案4】:

没有分支,只有 单个 random() 调用,使用模数运算符的魔力:

//Return a result between -40 and +40, excluding the range -20 to +20
var zeroToThirtyNine = Math.floor(Math.random()*40)
var counter = ((zeroToThirtyNine+61)%81)-40
零到三十九 |柜台 -------------------------- 0 | 21 1 | 22 2 | 23 ... 18 | 39 19 | 40 20 | -40 21 | -39 ... 37 | -23 38 | -22 39 | -21

【讨论】:

+1 有趣的是有多少种方法可以解决同一个问题!很好的答案! 很酷的想法 - 也应该是这里最快的解决方案,因为它避免了任何处理器管道刷新 @Heinzi:第二次调用Math.Random() 将比管道刷新慢几个数量级...【参考方案5】:

生成介于 -20 和 +20 之间的数字,如果为负数,则再减去 20 度。如果为正,则增加 20 度。

另外,你可能想要地板而不是圆形,这样你就不会得到 41 度。

var counter = Math.floor(Math.random()*81)-40;

【讨论】:

感谢您的示例! ;) +1 如果使用Math.round(Math.random() * x),您将获得的最高值是x 感谢 Xeon06 !我想我明白了 extra '1' 漂浮在周围的意义......只是让计数变得模糊......【参考方案6】:

您要生成 40 个可能的数字(-40 到 -21、21 到 40-这些都是 20 个数字范围)-> 在 [0,39] 中生成一个随机均匀分布的数字(其中也包含 40数)。这可以通过 Math.floor(Math.random()*40) 在 javascript 中完成

将输出范围映射到您想要的范围。

例如:

var uniformFrom0To39 = Math.floor(Math.random()*40)
return uniformFrom0To39 <= 19 ? uniformFrom0To39 - 40 : uniformFrom0To39 + 1

您还可以使用数组 [-40, -39, ..., -21, 21, 22, ..., 40] 执行映射 - 您也可以将该实现解释为“使用您想要的值并随机选择一个”。

【讨论】:

【参考方案7】:

您的代码给出了介于 -40 和 +41 之间的随机数,因为 Math.round() 可以四舍五入。 下面的代码应该给出你想要的:

if(Math.random()>0.5) 
    counter = Math.round(Math.random()*19)-40 // from -40 to -21
 else 
    counter = Math.round(Math.random()*19)+21 //from +21 to +40

【讨论】:

也是非均匀分布。 -40、-21、21 和 40 的出现频率是其他值的一半。【参考方案8】:

如果您有一个不太对称的排除区域,您可以像这样进行随机化:

do

    random = Math.floor(Math.random()*81 - 40);

while ((randomNum < excludedMax) && (randomNum > excludedMin));

如果您想排除 -19 到 4 或其他奇怪的值,这会很好用。它也适用于您的情况。

【讨论】:

如果排除区域大于可接受数字的区域,这种方法可能会很慢。 当然。它只是非常简单、易读且易于修改值并且仍然可以理解。不过绝对没有优化。【参考方案9】:

编写一个循环,直到你得到一个超出范围的数字。这很容易理解,也很容易证明你得到的数字仍然是随机的。

【讨论】:

等等等等!具体如何?这很有趣!感谢您的宝贵时间 伪代码:当随机数在-20到20之间时,再次随机。 效率低下且过于复杂。不过我确实喜欢容易理解。

以上是关于Math.random() 帮助获取 '+N' 和 '-N' 随机数(不包括特定范围)的主要内容,如果未能解决你的问题,请参考以下文章

lua math.random伪随机问题浅析

JavaScript中的Math对象

JS中,输出1-10之间的随机整数,用Math.random()咋搞呢

JS生成限定整数区间范围内的随机整数

使用js Math.random()函数生成n到m间的随机数字

js 随机函数