Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Random giving negative numbers

Tags:

java

random

I'm having trouble with Javas Random class, if i do this:

Random rng = new Random(seed) // seed == 29 in this example  String ss = "";         for(int i = 0; i < 10; i++)         {             int s = rng.nextInt();             ss += Integer.toString(s);             ss +="\n";         } 

This is what i get back:

-1169335537 -2076183625 1478047223 1914482305 722089687 2094672350 -1234724057 -1614953544 -321574001 1000360613 

From what I have read this should only be returning positive numbers for a start?

This may be a bit far fetched but it couldnt have anything to do with running a 64 bit machine on Windows 7 64 bit?

Any help at all would be awesome need to get this finished for an assignment hand in today!

like image 730
Vade Avatar asked Apr 29 '11 01:04

Vade


People also ask

How do you randomize a negative number in Java?

The correct code is int rand = new Random(). nextInt((30 - 20) + 1) + 20; .

How do you generate only positive random numbers in Java?

The nextDouble() and nextFloat() method generates random value between 0.0 and 1.0. The nextInt(int bound) method accepts a parameter bound (upper) that must be positive. It generates a random number in the range 0 to bound-1.

Can random nextInt returns negative?

newInt(10); This will return a random number between 0 and 9. Show activity on this post. If you happen to work with numbers that have the possibility of having a negative value you can turn it into a positive value using a conditional declaration automatically by multiplying the value to a negative one.

Is random nextInt positive?

nextInt(int n) : The nextInt(int n) is used to get a random number between 0(inclusive) and the number passed in this argument(n), exclusive. Declaration : public int nextInt(int n) Parameters : n : This is the bound on the random number to be returned. Must be positive.


1 Answers

From the Java docs for nextInt():

All 232 possible int values are produced with (approximately) equal probability.

One approach is to use the following transform:

s =  rng.nextInt() & Integer.MAX_VALUE; // zero out the sign bit 

The reason something like this is needed (as opposed to using absolute value or negation) is that Integer.MIN_VALUE is too large in absolute value to be turned into a positive integer. That is, due to overflow, Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE and Integer.MIN_VALUE == -Integer.MIN_VALUE. The above transformation preserves the approximately uniform distribution property: if you wrote a generate-and-test loop that just threw away Integer.MIN_VALUE and returned the absolute value of everything else, then the positive integers would be twice as likely as zero. By mapping Integer.MIN_VALUE to zero, that brings the probability of zero into line with the positive integers.

Here is another approach, which may actually be a tiny bit faster (although I haven't benchmarked it):

int s = rng.next(Integer.SIZE - 1); // Integer.SIZE == 32 

This will generate an integer with 31 random low-order bits (and 0 as the 32nd bit, guaranteeing a non-negative value). However (as pointed out in the comment by jjb), since next(int) is a protected method of Random, you'll have to subclass Random to expose the method (or to provide a suitable proxy for the method):

public class MyRandom extends Random {     public MyRandom() {}     public MyRandom(int seed) { super(seed); }      public int nextNonNegative() {         return next(Integer.SIZE - 1);     } } 

Another approach is to use a ByteBuffer that wraps a 4-byte array. You can then generate a random four bytes (by calling nextBytes(byte[])), zero out the sign bit, and then read the value as an int. I don't believe this offers any advantage over the above, but I thought I'd just throw it out there. It's basically the same as my first solution (that masks with Integer.MAX_VALUE).

In an earlier version of this answer, I suggested using:

int s = rng.nextInt(Integer.MAX_VALUE); 

However, according to the docs this will generate integers in the range 0 (inclusive) to Integer.MAX_VALUE (exclusive). In other words, it won't generate the value Integer.MAX_VALUE. In addition, it turns out that next(int) is always going to be faster than nextInt(int).

like image 78
Ted Hopp Avatar answered Sep 23 '22 23:09

Ted Hopp