4

I've installed a plugin (Code Contract Editor Extensions by Microsoft) which displays all code contracts for .NET.

When I look at the contract for Random.Next it says ensures result <= maxValue while MSDN states that maxValue is exclusive. Shouldn't the contract say ensures result < maxValue?

H H
  • 263,252
  • 30
  • 330
  • 514
jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • 1
    Yes. This contract is rumored to fail in 2012. – Hans Passant Jul 06 '11 at 12:09
  • that is assuming MSDN to be correct. In my experience, that's far from always true, and for some reason, it seems to take the better part of a decade for the tiniest fix to get applied to MSDN – jalf Jul 06 '11 at 12:12
  • 2
    @Hans I’m assuming you were making a joke. But still: how can a contract fail when the actual contract is *stricter*? – Konrad Rudolph Jul 06 '11 at 12:16
  • 2
    @jalf MSDN and the contract are both 100% correct; the only error here is the claim that "MSDN states that maxValue is exclusive" - it says no such thing. – Marc Gravell Jul 06 '11 at 12:42
  • @Marc Gravell: MSDN ***do*** claim that. Read the maxValue description for the min/max overload. It also claims what you say in your answer in the remarks. – jgauffin Jul 06 '11 at 12:47
  • 1
    @jgauffin it could perhaps be better stated as "usually exclusive" ;p – Marc Gravell Jul 06 '11 at 12:48

2 Answers2

6

It is not exclusive, and MSDN does not state that it is. Well, OK, it does use the word "exclusive" when talking about maxValue, which is less than clear, but the reality is that in the vast majority of cases it is indeed exclusive as expected.

There are, however, some corner-cases: to be specific with examples, Next(0) returns 0; Next(4,4) returns 4. It is inclusive when it has no option, and this is documented in the "Return Value" sections on MSDN:

To quote from Next(maxValue):

However, if maxValue equals zero, maxValue is returned.

and from Next(minValue,maxValue):

If minValue equals maxValue, minValue is returned.

(which of course could also be stated "maxValue is returned")

So in both cases, it is possible for maxValue to be returned.

The only exception is the parameterless Next() which is documented as being strictly < int.MaxValue.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Ok. I just read the parameter description `The exclusive upper bound of the random number returned`. So the min/max overload is exclusive unless the same value is used for both parameters. That explains the contract. – jgauffin Jul 06 '11 at 12:43
  • I assume the OP talks about the parameterless `Next` which indeed guarantees that the result is less than `int.MaxValue` – CodesInChaos Jul 06 '11 at 12:43
  • @jgauffin exactly; but that means that *from a contract perspective*, it can only be stated that it is `<=` – Marc Gravell Jul 06 '11 at 12:43
  • @CodeInChaos: No, I was talking about the min/max overload. Sorry for not being clear enough about it in my question. – jgauffin Jul 06 '11 at 12:44
  • 1
    Even for the `Next(maxValue)` overload the contract could be improved by adding something like `maxValue==0||result – CodesInChaos Jul 06 '11 at 12:48
  • You might want to update the answer to clarify that it's almost always exclusive. And you'll get a +1 too ;) – jgauffin Jul 06 '11 at 12:55
2

Since the contract in MSDN is stricter than the contract used by code contracts, the contract used by code contracts is obviously correct, but perhaps not tight.

On the other hand if you were to supply a custom implementation of Next in your own Random derived class, it might not fulfill the contract specified on MSDN, but the contract checker won't notice the mistake. So it's still advisable for MS to remove the discrepancy between the two contract versions.

I wouldn't be surprised if the MSDN behavior was originally a mistake and they then changed the code to fit the specification.

I suggest that you file a MS Connect issue asking them to improve one of them.

Quoting MSDN for Next()

A 32-bit signed integer greater than or equal to zero and less than MaxValue.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
  • No, the OP has simply mis-stated MSDN; MSDN clearly states that it can be inclusive (see my answer) – Marc Gravell Jul 06 '11 at 12:40
  • @Marc for the parameterless `Next` MSDN guarantees that the result is less that `int.MaxValue`. – CodesInChaos Jul 06 '11 at 12:45
  • @Marc Gravell: no, I did not mis-stated it as I've explained in a comment for your answer and my question ;) – jgauffin Jul 06 '11 at 12:53
  • @jgauffin ok ok, I get it - `maxValue` mentions the word "exclusive", fine - I hear you. That is perhaps misleading; but it also clarifies the edge condition in the "Return Value" remarks. Yes, it could be better phrased, but *taken in the entirety*, MSDN does attempt to make it clear that it isn't *strictly* exclusive. – Marc Gravell Jul 06 '11 at 12:58
  • Yes. I know. I had missed that part in the remarks. That's why your answer helped me and hopefully others discovering the same thing. – jgauffin Jul 06 '11 at 13:00