Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / August 2006

Tip: Looking for answers? Try searching our database.

generating a positive rand number in range (0, 2^63]

Thread view: 
Varun  Kacholia - 03 Aug 2006 01:48 GMT
Please correct me if I am wrong but as per my understanding
java.util.Random.nextLong() can
return a negative number as well. I need to get a positive long only.
What would be the best way?
(Math.abs wont work since it cannot convert LONG.MIN_VALUE to a
positive long).
Suggestions?

Thanks!
Eric Sosman - 03 Aug 2006 01:55 GMT
Varun Kacholia wrote:

> Please correct me if I am wrong but as per my understanding
> java.util.Random.nextLong() can
> return a negative number as well. I need to get a positive long only.
> What would be the best way?
> (Math.abs wont work since it cannot convert LONG.MIN_VALUE to a
> positive long).

    r.nextLong() >>> 1 comes to mind.  Or you could use
((long)r.next(31) << 32) + r.next(32).

Signature

Eric Sosman
esosman@acm-dot-org.invalid

Varun  Kacholia - 03 Aug 2006 02:06 GMT
>      r.nextLong() >>> 1 comes to mind.  Or you could use
that could still result in 0. (r.nextLong() >>> 1 + 1 wont help either)

> ((long)r.next(31) << 32) + r.next(32).
0?

Eric Sosman - 03 Aug 2006 02:23 GMT
Varun Kacholia wrote:

>>     r.nextLong() >>> 1 comes to mind.  Or you could use
>
[quoted text clipped - 3 lines]
>
> 0?

    I apologize; I didn't notice your subject line.

    Note that a `long' cannot cover the range you've asked for;
2^63 is larger than Long.MAX_VALUE.  A `double' can cover the
range, but not with 63-bit accuracy.  If you really need (0,2^63]
I think you'll need to use BigInteger values.  The easiest way
is probably to use r.next() twice to generate a 63-bit value
in the range [0,2^63), generate a BigInteger from that (use the
BigInteger(byte[]) constructor), and add BigInteger.ONE to the
result.

Signature

Eric Sosman
esosman@acm-dot-org.invalid

Varun  Kacholia - 03 Aug 2006 04:40 GMT
>      I apologize; I didn't notice your subject line.

my bad as well. i intend it to be between (0, 2^63) (excluding 0 and
2^63).
suggestions?

>      Note that a `long' cannot cover the range you've asked for;
> 2^63 is larger than Long.MAX_VALUE.  A `double' can cover the
[quoted text clipped - 4 lines]
> BigInteger(byte[]) constructor), and add BigInteger.ONE to the
> result.
Patricia Shanahan - 03 Aug 2006 04:57 GMT
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.
Flávio Barata - 03 Aug 2006 13:25 GMT
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
Patricia Shanahan - 03 Aug 2006 02:13 GMT
Varun Kacholia wrote:
> Please correct me if I am wrong but as per my understanding
> java.util.Random.nextLong() can
[quoted text clipped - 5 lines]
>
> Thanks!

If you intend to exclude zero, and include 2^63, as indicated by the
range in the subject, it cannot be done because the largest long,
Long.MAX_VALUE, is 2^63-1.

Patricia


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.