Tricky
Tricky

Reputation: 145

Random number generator acting strange

I wanted a random number ranging from 0 to 3 and tried the following code just to see how it works.

int[] count = new int[4];

    for (int i = 0; i < 1000; i++) {
        int t = (int)(Math.round((Math.random() *3)));

        count[t] +=1;

    }


    for (int i = 0; i < count.length; i++) {
        System.out.println(count[i]);

    }

Weird thing now is that 0 and 3 hit about half the times 1 and 2 hit, how is that possible?

Upvotes: 0

Views: 162

Answers (4)

Mikhail
Mikhail

Reputation: 4223

class Math {
    ...
    public static long round(double a) {
       return (long)floor(a + 0.5d);
    }
    ...
}

There is more probability to hit 1 and 2

int t = (int)(Math.ceil((Math.random() * 4))) - 1;

Using ceil instead of round gives better distribution:

250
239
242
269

Upvotes: 1

James
James

Reputation: 8586

http://docs.oracle.com/javase/6/docs/api/java/lang/Math.html#round(double)

Returns the closest long to the argument. The result is rounded to an integer by adding 1/2, taking the floor of the result, and casting the result to type long.

You're creating buckets of unequal size:

0 - 0.4999... => 0 (.5)

0.5 - 1.499... => 1 (1)

1.5 - 2.499... => 2 (1)

2.5 - 2.99999... => 3 (.5)

To fix, either use:

Random.nextInt(4);

Er... typo, thanks @TedHopp - I mean:

Random r = new Random();
...
r.nextInt(4);

Or do

(int) (Math.random() * 4);s

Which will do what you expect.

Upvotes: 2

FatalError
FatalError

Reputation: 54621

Look at the intervals that round to each integer:

|----+----|----+----|----+----|
0         1         2         3

<...>
Rounds to 0
     <........>
     Rounds to 1
               <........>
               Rounds to 2
                         <....>
                         Rounds to 3

You can see that the range that round to 0 and 3 is half the size as the others, so if you choose uniformly you hit them half as often.

Upvotes: 6

Breavyn
Breavyn

Reputation: 2242

This happens because you are rounding. 0 can only be rounded to if its less than 0.5. However 1 could be picked if its between 0.5 and 1.5. Therefore giving it twice the chance of occurring. The same thing happens for 2, between 1.5 and 2.5. And 3 is only from 2.5 to 3.

Upvotes: 1

Related Questions