Random number in long range, is this the way?

Why don’t you just generate two random Int32 values and make one Int64 out of them?

long LongRandom(long min, long max, Random rand) {
    long result = rand.Next((Int32)(min >> 32), (Int32)(max >> 32));
    result = (result << 32);
    result = result | (long)rand.Next((Int32)min, (Int32)max);
    return result;
}

Sorry, I forgot to add boundaries the first time. Added min and max params. You can test it like that:

long r = LongRandom(100000000000000000, 100000000000000050, new Random());

Values of r will lie in the desired range.

EDIT: the implementation above is flawed. It’s probably worth it to generate 4 16-bit integers rather than 2 32-bit ones to avoid signed-unsigned problems. But at this point the solution loses its elegancy, so I think it’s best to stick with Random.NextBytes version:

long LongRandom(long min, long max, Random rand) {
    byte[] buf = new byte[8];
    rand.NextBytes(buf);
    long longRand = BitConverter.ToInt64(buf, 0);

    return (Math.Abs(longRand % (max - min)) + min);
}

It looks pretty well in terms of value distribution (judging by very simple tests I ran).

Leave a Comment