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' 随机数(不包括特定范围)的主要内容,如果未能解决你的问题,请参考以下文章
JS中,输出1-10之间的随机整数,用Math.random()咋搞呢