1

Here are two of the variations to generate random integers within a range (start, end):

method 1:

int rand = (int)(Math.random()*(end-start)+1)+start;

method 2:

Random numbergenerator = new Random();
int rand=numbergenerator.nextInt(end-start)+start;

Method 2 seems to work for me.

The reason I ask this: I was trying to debug my code and when I changed my random int generation to method 2, everything seem to work fine. Method 1 was giving unexpected results.

The unexpected results come from different post: but that is a distraction to this question still it is here. Here I replaced mehtod 1 with method 2 and everything worked fine.

so the question is are these methods of random int generation different. method 1 I used has been upvoted in this post.

What would be an example case where they both could differ (if they are different)?

Community
  • 1
  • 1
brain storm
  • 30,124
  • 69
  • 225
  • 393
  • 1
    How are the results unexpected? –  Dec 20 '13 at 02:12
  • 2
    Random numbers should be unexpected. That's the point. – Eran Dec 20 '13 at 02:13
  • 1
    "*What would be an example case where they both could differ (if they are different)*" you tell us! You observed the unexpected results! – Julián Urbano Dec 20 '13 at 02:13
  • `Math.random()` is equivalent to `Random.nextDouble()` not `Random.nextInt()` – iWumbo Dec 20 '13 at 02:13
  • Clarify (ie show or describe in detail) what "unexpected results" you're getting – Bohemian Dec 20 '13 at 02:13
  • @Eran: its not the actual numbers I talk about. but the range I of values I get out – brain storm Dec 20 '13 at 02:13
  • @Bohemian: here is my another post where I used method 1 and had issues. replacing with method 2 fixed the issues.. look here: http://stackoverflow.com/questions/20694571/randomized-quick-sort-in-java-need-a-suble-fix – brain storm Dec 20 '13 at 02:14
  • I think he means they are consistently skewed. – Bohemian Dec 20 '13 at 02:14
  • @MichaelT: please see my reply above to Bohemain – brain storm Dec 20 '13 at 02:15
  • My guess is: casting to `(int)` truncates, it doesn't do rounding. So if `start = 0`, and `end = 1`, if the result of `Math.random()` is greater or equal to `0` and lesser than `1`, the value of that expression will be `0`. If and only if `Math.random()` returns exactly `1.0` will the result be `1`. DERP: `Math.random()` never returns `1.0`, so the first approach is just completely broken. – millimoose Dec 20 '13 at 02:19
  • Moral of the story: when you're trying to generate an int, use the appropriate method, unless you know how to correctly slice the interval `[0.0, 1.0]` into equal-sized parts. – millimoose Dec 20 '13 at 02:20
  • @millimoose: I followed this post for random integer generation within a range: http://stackoverflow.com/questions/363681/generating-random-numbers-in-a-range-with-java – brain storm Dec 20 '13 at 02:20
  • You have to explain what "unexpected results" means, as has already been asked. – vanza Dec 20 '13 at 02:21
  • @vanza: I edited the question above – brain storm Dec 20 '13 at 02:24
  • 2
    @user1988876 You followed it wrong. You're missing a parenthesis around `(end-start)+1`. That is, the whole shebang should be `Math.random() * ((end - start) + 1)`. Operator precedence makes your code equivalent to `(Math.random() * (end - start)) + 1`. The idea is to make the **range** bigger by `1` to avoid the problem I described above. Not to add `1` to the result of getting a random number from a smaller range. – millimoose Dec 20 '13 at 02:24
  • I strongly suggest actually drawing this on paper using a number axis that you "randomly" poke a pencil at to see what's going on. The way the algorithm works is that it picks a number greater or equal than `start`, and lesser than `end + 1`, then truncates it. If you don't make that range bigger, you obviously can never get a number greater than `end`, which truncated can never be equal to `end`. Moral of the story #2: don't blindly follow code snippets from the internet you don't understand. – millimoose Dec 20 '13 at 02:26
  • @millimoose: thanks for catching up on my mistake. I will fix it – brain storm Dec 20 '13 at 02:27

1 Answers1

3

Given that your unexpected results come from a sorting algorithm, I suspect that by unexpected you mean it doesn't really sort numbers.

The problem is that the range of random numbers is not the same in both methods. The range in method 1 is [start+1 , end], and in method 2 it is [start, end-1].

So basically remove the +1 part here:

int rand = (int)(Math.random()*(end-start)+1)+start;

so that the range is the usual [start, end-1]. I say usual because arrays are indexed in the range [0, length-1].

Community
  • 1
  • 1
Julián Urbano
  • 8,378
  • 1
  • 30
  • 52