> I apologize; I didn't notice your subject line.
Varun Kacholia wrote:
>> I apologize; I didn't notice your subject line.
>
[quoted text clipped - 10 lines]
>> BigInteger(byte[]) constructor), and add BigInteger.ONE to the
>> result.
How about:
long result;
do{
result = r.nextLong() >>> 1;
}while(result == 0)
[Based on one of Eric's earlier suggestions]
Patricia
Jussi Piitulainen - 03 Aug 2006 08:00 GMT
> Varun Kacholia wrote:
>>> I apologize; I didn't notice your subject line. my
>> bad as well. i intend it to be between (0, 2^63)
[quoted text clipped - 18 lines]
>
> [Based on one of Eric's earlier suggestions]
How about just:
long result;
do {
result = r.nextLong();
}
while (result <= 0);
Eric Sosman - 03 Aug 2006 13:16 GMT
>>Varun Kacholia wrote:
>
[quoted text clipped - 29 lines]
> }
> while (result <= 0);
It's a "micro-pessimization." Roughly speaking, Patricia's
code will average one nextLong() call per delivered result, while
Jussi's will average two. (Patricia accepts the nextLong() value
with probability (2^63-1)/2^63 = 1-2^(-63), while Jussi accepts
each value with probability (2^63-1)/2^64 = 0.5-2^(-64).)

Signature
Eric Sosman
esosman@acm-dot-org.invalid
Jussi Piitulainen - 03 Aug 2006 13:59 GMT
...
>>> How about:
>>>
[quoted text clipped - 17 lines]
> with probability (2^63-1)/2^63 = 1-2^(-63), while Jussi accepts
> each value with probability (2^63-1)/2^64 = 0.5-2^(-64).)
Thanks. I didn't realize her code was _that_ efficient.
I should explain why I asked about the alternative at all. The reason
is that my version is rather obviously still uniform (all the accepted
numbers are equally probable in the underlying generator) while with
your/Patricia's version something more subtle is going on, and I get
nervous when there is something subtle going on.
Let me see. Assume we have a uniform distribution for the 2^64 bit
patterns before the shift. When we lop off the rightmost bit, we are
left with 2^63 bit patterns, each of which occurred once with 0 and
once with 1 to its right, so they are all equally probable. And we
reject both occurrences of 63 zeroes.
I think I see it now. Thanks again.
The range you want could be generated with this code below:
long x = 0;
long y = Math.round(Math.pow(2, 63));
long randomNumber = (long) (Math.random() * (y - x -
1)) + 1;
System.out.println(x + " " + y);
System.out.println(randomNumber);
The range is (x, y] ;-)
flávio
> > I apologize; I didn't notice your subject line.
>
[quoted text clipped - 10 lines]
> > BigInteger(byte[]) constructor), and add BigInteger.ONE to the
> > result.
Patricia Shanahan - 03 Aug 2006 14:32 GMT
> The range you want could be generated with this code below:
>
> long x = 0;
> long y = Math.round(Math.pow(2, 63));
This is a bit indirect, but equivalent to:
long y = Long.MAX_VALUE;
"If the argument is positive infinity or any value greater than or equal
to the value of Long.MAX_VALUE, the result is equal to the value of
Long.MAX_VALUE" (Math.round API documentation).
> long randomNumber = (long) (Math.random() * (y - x -
> 1)) + 1;
There are 2^53 possible results of Math.random(), the same as the number
of possible different results from Random's nextDouble() method. The
(0,2^63) range has (2^63)-1 possible values. About one in every 1024
positive longs has probability 2^-53. The others all have probability zero.
I believe the OP wanted a uniform distribution over all the longs in the
range.
Patricia