为什么Random.Next(int,int)的.Net实现需要maxValue> = minValue?

时间:2014-12-09 02:31:35

标签: c# .net random

在制作方法将新创建的表单放在屏幕上完全随机的位置而不超出所述屏幕的界限时,我有一个有趣的代码合同消息说明......

  

合同需要未经证实的minValue< = maxValue

...使用代码时:

        Location = new Point(
            this.rnd.Next(targetBounds.Left, targetBounds.Right - Width),
            this.rnd.Next(targetBounds.Top, targetBounds.Bottom - Height));

看了.Net implementation我感到困惑。

我的问题是,为什么他们不能简单地交换最大值为< MINVALUE。
有没有(除了可能没有捕捉到晦涩的错误)的原因,为什么一个人不应该允许Random.Next(100,50)?

如果你说“给我一个介于100(不包括)和50(含)之间的随机数”和“......介于50(含)和100(不含)之间,这应该没有任何区别”。
> 数字的范围仍然是相同的不是吗?

这是在考虑使用Random.Next(1,2)和Random.Next(1,1)之前的陷阱之前,两者都是完全有效的代码而没有任何警告。两者都在每个新一代都返回1,实际上应该警告用户这种行为。

编辑调用Random.Next(20,20)时潜在陷阱的一个例子。

如果你在你的代码中假设提供20的上限将总是给你低于和19之间的随机数,并且你的下限允许到20,包括你,在这种特殊情况下,你可能会破坏你的代码下限命中20,因为这是Random.Next将返回20的一种情况。想象一下,你有一些上限为数百万的代码,可能需要一些时间才能突然遇到边缘情况。至少 IS 记录在案。

我已经知道这个问题:Why can minValue == maxValue in Random.Next?

2 个答案:

答案 0 :(得分:7)

答案很可能是"他们可以拥有,但他们没有"。

编程语言和库是完全这样的怪癖,除了你认为是怪癖,其他人可能会做出设计决定: - )

提供一个具有最小值和最大值的函数是没有意义的,然后继续为您提供 值的范围。如果参数类似于limit1/limit2one_end/the_other_end,但在任何情况下,如果值的定义包含在名称中(例如min/maxupper/lower,则足够公平),您最好遵循某些指导原则,例如principle of least astonishment

您正在讨论的所有行为都有详细记录,它不是它的错误(如果doco错误)或者甚至是灰色(如果doco没有提及)它)。它是所有人阅读并注意到的plainly spelled out

  

minValue:返回的随机数的包含性更低范围。

     

maxValue:返回的随机数的唯一范围。 maxValue 必须大于或等于minValue

     

返回值:32位有符号整数大于或等于minValue且小于maxValue ;也就是说,返回值的范围包括minValue但不包括maxValue如果minValue等于maxValue,则会返回minValue

如果真的想要一个可逆的范围,那么就没有什么可以阻止你自己做这件事,比如(伪代码):

def revRandom (end1, end2):
    if end1 > end2:
        return realRandom (end2, end1)
    return realRandom (end1, end2)

唯一棘手的问题是你如何处理两端的包容性/排他性。在上面的示例中,无论如何,我都选择了更高的数字。如果你想让第二个参数独占,你需要稍作改动。


在任何情况下,根据您的代码,您似乎想要放置某个对象的角落,以便整个对象落在目标边界内。如果是这种情况,那么您所希望的行为正好您要避免的行为。

如果对象的宽度由于某种原因大于目标边界的宽度,它会将对象放在边界的之外(当然,如果它的话,那么) not 更大,无论如何你都没有问题,因为.Next()的参数会很好。

为了说明(我们此处仅覆盖左/右边界但顶部/底部相似),假设您的目标边界为left=100right=200。如果对象的宽度在1100 (a)之间,则它将正常工作,并且对象将完全包含。

如果对象决定增加一点到150(例如),那么它的左侧将落在50100之间,远远超出允许的边界。


(a) 可能是由Jedi错误导致的边界点处的细微边缘情况(Obi Wan = OB1 =一个接一个,得到它?)但为了简单起见,我对此进行了折扣。

答案 1 :(得分:4)

我觉得这个问题很奇怪。

  
    

我的问题是,为什么他们不能简单地交换最大值为< MINVALUE。

  

这些参数称为mixValuemanValue。如果您为7传递了值minValue,为3传递了maxValue,并且返回值为4,则这将是完全令人震惊和不良行为。没有大于或等于7且小于或等于3的值,因此所有方法都可以抛出异常。

他们可以改为调用参数oneValueotherValue,并确保结果介于两者之间,但我不认为有一个方法可以指定一系列数值价值递增;这很常见。 (我认为这也不是一个无理要求)。

  
    

在任何情况下,同一个方法调用的两个不同输入导致相同的输出并不适合我

  

为什么呢? Math.Floor()将为输入33.04以及数万亿其他输入生成3.99997。对于不同输入产生相同输出的方法没有任何问题。这也是一种常见的情况。