# Re: [ljc] A little Friday morning challenge for the group...

 From: user 7. Sent on: Saturday, January 26, 2013 7:06 PM
Not kind, Michael, credit where credit's due! I didn't like the do while loop but it is the only way I can think of doing it, I've tried exploring different methods. Even the commons math RandomDataImpl falls into the same trap as my version, the only difference is they are doing something fairly clever to avoid having to use BigIntegers, they don't use a range at all in their implementation of the method but the method won't pick all values of long because they are basing it around a random double. I believe your method to be the best of all that have been listed so far.

On Sat, Jan 26, 2013 at 6:03 PM, Michael Rogers <[address removed]> wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Aww shucks. Thanks Stuart, that's very kind. :-)

Cheers,
Michael

On 26/01/13 17:07, Stuart Wakefield wrote:
> I'm going to hands down call Michael my hero. The solution that I
> came up with is quick and dirty and quite right it won't return
> every value of long because there are not enough distinct values of
> double between 0.0 and 1.0 to cover every distinct value of long.
> The problem with a do while for Random.nextLong() is for a small
> range you could be generating a huge number of random longs but you
> should get an equal distribution (it says in the docs that the seed
> is only 48 bits so you don't get every value of long but I must be
> too dumb to understand why because the source shows that it simply
> packs two random ints which it says there should be an
> approximately equal distribution). Michael's solution while quite
> long tackles to problem of nextLong by increasing the probability
> of a match by only generating a number with the amount of bits
> required to represent the range, this will reduce the number of
> potential loops to return a match within the required range. Genius
> and my hero.
>
>
> On Sat, Jan 26, 2013 at 3:38 PM, Wesley Hall
> wrote:
>
> Michael,
>
> Nice :). I would have to say that all the bit shifting and binary
> mathematics is probably a good sign that you are smarter than I
> am. Curse these inconvenient ten fingers ;).
>
> Jahan,
>
> Yeah, actually once I figured out the max - min problem, then the
> next step my mind took was to do some midpoint calculations. I put
> your solution into my IDE and tested it and it appears to work
> beautifully, the only anomaly I can see is that for a range -100 to
> 100, then 0 is about twice as frequent as any other given result.
>
>
>
> On Sat, Jan 26, 2013 at 12:33 PM, Michael Rogers
> wrote: On 25/01/13 11:01, Wesley Hall wrote:
>>>> Your mission, should you choose to accept it, is to write a
>>>> method, in Java, with the following signature...
>>>>
>>>> public static long generateRandom(long min, long max) { //
>>>> code here }
>
> My attempt (rather heavyweight but I think it's correct):
>
> import java.math.BigInteger; import java.util.Random;
>
> public class LongRandom {
>
> private static final Random random = new Random();
>
> public static long generateRandom(long min, long max) { BigInteger
> bigMin = BigInteger.valueOf(min); BigInteger bigMax =
> BigInteger.valueOf(max); BigInteger exclusive =
> bigMax.subtract(bigMin); BigInteger inclusive =
> exclusive.add(BigInteger.ONE); // Work out how many bytes we need
> to generate int bits = exclusive.bitLength(); int bytes = (bits % 8
> == 0) ? bits / 8 : bits / 8 + 1; assert bytes > 0 && bytes <= 8; //
> The PRNG generates bytes, so there will be up to 7
>> spare bits
> int spareBits = bytes * 8 - bits; assert spareBits >= 0 &&
> spareBits < 8; // Mask out the spare bits each time we generate
> bytes int mask = 0xff; for(int i = 0; i < spareBits; i++) mask ^= 1
> << (7 - i); // Generate random bytes until we get a value in the
> required // range (unlike the modulus, this gives a uniform
>> distribution)
> byte[] b = new byte[bytes]; BigInteger rand; do {
> random.nextBytes(b); b[0] &= mask; // Mask out the spare bits rand
> = new BigInteger(1, b); // Positive signum }
> assert rand.min(bigMin).equals(bigMin); // rand >= min assert
> rand.max(bigMax).equals(bigMax); // rand <= max return
> rand.longValue(); } }
>
> Cheers, Michael
>
>>
>>
>>
>>
> everyone on this mailing list ([address removed]
>> http://www.meetup.com/Londonjavacommunity/ This message was sent
>> by Michael Rogers ([address removed]
> <mailto:[address removed]>) from LJC - London Java
> Community.
>> profile:
> http://www.meetup.com/Londonjavacommunity/members/49372592/
>> Set my mailing list to email me
>>
>> As they are sent
>> http://www.meetup.com/Londonjavacommunity/list_prefs/?pref=1
>>
>> In one daily email
>> http://www.meetup.com/Londonjavacommunity/list_prefs/?pref=2
>>
>> Don't send me mailing list messages
>> http://www.meetup.com/Londonjavacommunity/list_prefs/?pref=0
>> Meetup, POB 4668 #37895 NY NY USA 10163 | [address removed]
>>
>
>
>
>
> everyone on this mailing list ([address removed]
> http://www.meetup.com/Londonjavacommunity/ This message was sent by
> <mailto:[address removed]>) from LJC - London Java
> profile:
> http://www.meetup.com/Londonjavacommunity/members/15396461/ Set my
> mailing list to email me
>
> As they are sent
> http://www.meetup.com/Londonjavacommunity/list_prefs/?pref=1
>
> In one daily email
> http://www.meetup.com/Londonjavacommunity/list_prefs/?pref=2
>
> Don't send me mailing list messages
> http://www.meetup.com/Londonjavacommunity/list_prefs/?pref=0
> Meetup, POB 4668 #37895 NY NY USA 10163 | [address removed]
>
>
>
>
>
>
> *everyone* on this mailing list ([address removed]
> <mailto:[address removed]>) This message was sent by Stuart
> Wakefield ([address removed]) from LJC - London Java
> Community <http://www.meetup.com/Londonjavacommunity/>. To learn
> more about Stuart Wakefield, visit his/her member profile
> <http://www.meetup.com/Londonjavacommunity/members/74908532/> Set
> my mailing list to email me As they are sent
> <http://www.meetup.com/Londonjavacommunity/list_prefs/?pref=1> | In
> one daily email
> <http://www.meetup.com/Londonjavacommunity/list_prefs/?pref=2> |
> Don't send me mailing list messages
> <http://www.meetup.com/Londonjavacommunity/list_prefs/?pref=0>
>
> Meetup, POB 4668 #37895 NY NY USA 10163 <#> | [address removed]

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iQEcBAEBAgAGBQJRBBphAAoJEBEET9GfxSfMU5gH/2eAIF5UzUwtUP4mHgOj+JdY
5Fg+cjCPC6JnxPuluMOGvnvFSvn/smjPTtUbPkRxlAMSwwK/v1n9q6Bzwxw7gSr5
XXpVj2Y/Hs/g5zr2O1SGd8mgQ/DhXfbYHEANQcUJa7W2R5Vw/P+LuhJCZ8939Kmx
7aIejpzm3VQD8WDEUCI9p9OgIHFLNcxCIAkPRJDDFuotukAIL7hqwgvvrWwaquNv
/gyLJzVR4cWexHUgx71WNFlsa/PESrTnq67hjLAcGoPYHta1ZDxbql3NoT/RSuks
IxF4S+U09N/qtjpys/VCOPMdWlkHtdm47/teEB827EPtiuudSR+PlKycJyETgNk=
=LLTJ
-----END PGP SIGNATURE-----

### London, United Kingdom

Founded Nov 26, 2007

#### Organizers:

• ##### Our Blog

Read the latest news from the LJC

• ##### RecWorks Ltd

Fixing Tech Recruitment using the Power of Community

• ##### jClarity

Java/JVM Performance Analysis Tools & mentoring for Java related matters

• ##### LJC Aggrity

Our LJC Aggrity site contains blog posts from our members

• ##### LJC Book Club

Our Book club with book reviews from our members

• ##### Devoxx UK

Java Community Conference in collaboration with the LJC, 8-10th June 16

• ##### SkillsMatter

"Host, help organise, promote, film many of our meetings."

• ##### IBM

Build Enterprise-grade apps at start-up speed.

• ##### New Relic

New Relic makes sense of billions of metrics a day in real time.

• ##### Hazelcast

Hazelcast is the leader in operating in-memory computing.

• ##### Java.Net

We are an official Java User Group recognised by Oracle's JUG program

• ##### O'Reilly

Discounts on ebooks and O'Reilly conferences

#### People in this Meetup are also in:

• ##### GraphQL London

1,399 Mutations

• ##### London IT Contractors Group

1,141 Members

• ##### Agile Practitioners

2,635 Professionals

• ##### Virtual Java User Group

15,082 vJUGers

• ##### London Scala Users' Group

3,215 Enthusiasts

• ##### FREE Marketing, Analytics & Digital Skills in London

16,808 Digital Professionals