C#的Random.Next方法 - 是否永远不会返回上限?

81
random.Next(0,5)

它从未返回5(但有时会返回0)。为什么?我认为这些只是可以返回的边界值。谢谢


9
为什么要这样做?这样做只会让人感到不必要的困惑。 - user660871
3
为什么?可能是因为这个:var randomValue = myArray[rand.Next(0, myArray.Length)]; (该代码段中的变量和方法名已保留原文) - Brett Allen
26
比起重新打代码并触发 IntelliSense 或搜索 MSDN 文库,我发现这份文档更快。通常情况下在调试或阅读代码时并不会打代码。我直觉地将 "maxValue" 理解为 "最大可能值" 而不是 "最大值减一"。没有必要告诉原帖作者去 RTFM(读取相关文档)。 - JonH
9
我知道我来晚了,但实际上我对此感到非常惊讶。像世界上其他人一样,我把“maxValue”理解为此函数将返回的最大数字。我相当确定我的代码出现了问题,可能已经在生产中出现了。 - Brandon
OP正在问“为什么?”但似乎没有人回答。我对他们为什么这样设计很感兴趣。 - Xonatron
显示剩余3条评论
6个回答

156

Next()方法中上限的maxValue排除在外的——范围包括minValuemaxValue-1和它们之间的所有数字。


14
他们为什么选择让一个包容,另一个排除?这似乎有点奇怪... - anakic
23
我能想到的一个原因是 array[random.Next(0, array.Length)] - Mark Cidade
12
名称 maxValue(作为参数称呼)会误导读者,应该改为 upper Bound。因为最大值始终是集合中的元素。请注意,upper bound 是指集合中所有元素的上限而不一定是其中的最大值。 - Harry Berry
1
@AntonioNakicAlfirevic - 请查看此处以了解此行为背后的原因:http://programmers.stackexchange.com/questions/311250/exclusive-upper-bound-in-random-number-range/311253 - Matt Wilko
7
如果你在minValue和maxValue中传递相同的值,那么maxValue不再是排除的。 描述“返回特定范围内的随机整数”也是误导性的。 - EventHorizon
显示剩余2条评论

14

文档中指出,上限是“排除的”。 排除意味着它不包括在可能的返回集合中。在更数学的符号表示中,0 <= x < 5 在本例中。


1
如果min=max,则不适用此规则。如果minValue等于maxValue,则返回minValue。 - jasdefer
5
那么,为什么它返回 minValue 而不是 maxValue - qxz
@qxz 我只是在讨论这种情况:minValue = maxValue。在这种情况下,返回minValuemaxValue并不重要,因为它们相等。minValue <= x < maxValue不成立。如果minValue = maxValue = 0,则返回x = 0,但0 < 0不成立。 - jasdefer

6

直接从文档中摘录:

 Summary:
   Returns a random number within a specified range.

 Parameters:
   minValue:
     The inclusive lower bound of the random number returned.

   maxValue:
     The exclusive upper bound of the random number returned. maxValue must be
     greater than or equal to minValue.

 Returns:
     A 32-bit signed integer greater than or equal to minValue and less than maxValue;
     that is, the range of return values includes minValue but not maxValue. If
     minValue equals maxValue, minValue is returned.

如果你查看参数,你会发现minValue是包含的(这就是为什么你的0出现了),而maxValue是不包含的(你的5从未出现)。

2

记住这个方法的好办法是将max视为从中取随机数的数字数量。

因此,random.Next(0,2)的意思是从0和1两个数中随机选取一个数。


2
这是一种很好的记忆方式,但前提是给定的下限为0。例如,random.Next(1,2)并不是从1开始随机选择2个数字。 - user1311045

1

虽然这篇文章写得很久远,但我还是想发表一下评论。我认为该设计决策的主要原因是,大多数随机数生成器在其核心生成0到2^32-1之间的数字。因此,如果您指定Int32.MaxValue,您将永远不会获得那个数字。对于一个数字有一个例外是无法被设计师接受的,因此他们决定拥有括号是排除性的。问题解决了!


-2

当你在谷歌上搜索“c# random”,并跟随第一个链接到所需的方法时,你会来到这里:http://msdn.microsoft.com/en-us/library/aa329893(v=vs.71).aspx

而且没有关于上限排他性的提示。他们必须已经在代码中发现了错误,并通过文档进行了更正。

因此,在查看文档时,始终检查框架的版本非常重要。即使使用旧版本的框架,也值得查看更新的文档。


2
我点击了你发的链接,找到了这个内容:"返回值 - 一个32位有符号整数,大于或等于最小值并且小于最大值;也就是说,返回值的范围包括最小值但不包括最大值。如果最小值等于最大值,则返回最小值。" - dbasnett
3
正如dbasnett所说,文档确实在这里指定了行为。不仅如此,这也是定义类似随机数范围的传统方式。我认为你猜测这实际上是一个错误是很差的。 - Jon Skeet
允许最大值和最小值相同有点不直观,因为这会导致有效值集合始终为空。 - Grubsnik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接