J
John B. Matthews
Given an instance of java.util.Random, FindBugs correctly warns [1]
that taking the absolute value of a signed 32-bit random integer can
(rarely) produce a negative number, e.g.:
int randomIndex = Math.abs(random.nextInt()) % fortuneArray.length;
I had initially thought to mask the high bit:
int randomIndex = (random.nextInt() & 0x7fffffff) % fortuneArray.length;
Reflecting on the limitations of Linear Congruential Generators (LCG)
[2], I was then inclined to discard the low-order bit using the
unsigned right shift operator:
int randomIndex = (random.nextInt() >>> 1) % fortuneArray.length;
Then I realized that the preferred method is already in the API [3]:
int randomIndex = random.nextInt(fortuneArray.length);
D'oh. Long odyssey; back in Ithaca; comments welcomed.
[1] "Bad attempt to compute absolute value of signed 32-bit random
integer. This code generates a random signed integer and then computes
the absolute value of that random integer. If the number returned by
the random number generator is Integer.MIN_VALUE, then the result will
be negative as well (since Math.abs(Integer.MIN_VALUE) ==
Integer.MIN_VALUE)."
[2]<http://en.wikipedia.org/wiki/Linear_congruential_generator>
[3]<http://java.sun.com/javase/6/docs/api/java/util/Random.html#nextInt(int)>
that taking the absolute value of a signed 32-bit random integer can
(rarely) produce a negative number, e.g.:
int randomIndex = Math.abs(random.nextInt()) % fortuneArray.length;
I had initially thought to mask the high bit:
int randomIndex = (random.nextInt() & 0x7fffffff) % fortuneArray.length;
Reflecting on the limitations of Linear Congruential Generators (LCG)
[2], I was then inclined to discard the low-order bit using the
unsigned right shift operator:
int randomIndex = (random.nextInt() >>> 1) % fortuneArray.length;
Then I realized that the preferred method is already in the API [3]:
int randomIndex = random.nextInt(fortuneArray.length);
D'oh. Long odyssey; back in Ithaca; comments welcomed.
[1] "Bad attempt to compute absolute value of signed 32-bit random
integer. This code generates a random signed integer and then computes
the absolute value of that random integer. If the number returned by
the random number generator is Integer.MIN_VALUE, then the result will
be negative as well (since Math.abs(Integer.MIN_VALUE) ==
Integer.MIN_VALUE)."
[2]<http://en.wikipedia.org/wiki/Linear_congruential_generator>
[3]<http://java.sun.com/javase/6/docs/api/java/util/Random.html#nextInt(int)>