Can somebody verify this method. I need a long type number inside a range of two longs. I use the .NET Random.Next(min, max) function which return int's. Is my reasoning correct if I simply divide the long by 2, generate the random number and finally multiply it by 2 again? Or am I too enthusiastic... I understand that my random resolution will decrease but are there any other mistakes which will lead to no such a random number.
long min = st.MinimumTime.Ticks; //long is Signed 64-bit integer long max = st.MaximumTime.Ticks; int minInt = (int) (min / 2); //int is Signed 64-bit integer int maxInt = (int) (max / 2); //int is Signed 64-bit integer Random random = new Random(); int randomInt = random.Next(minInt, maxInt); long randomLong = (randomInt * 2);
Seventeen is: Described at MIT as 'the least random number', according to the Jargon File. This is supposedly because in a study where respondents were asked to choose a random number from 1 to 20, 17 was the most common choice. This study has been repeated a number of times.
What is a random number? As the term suggests, a random number is a number chosen by chance -- i.e., randomly, from a set of numbers. All the numbers in a specified distribution have equal probability of being chosen randomly.
We are told that MIPS chip designer Mark Johnson, who claims it is the World's most common random number, is responsible for scribbling this number onto the mask. A number of visitors have responded to us about the concept of 37 being the most random number.
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).
Some other answers here have two issues: having a modulo bias, and failing to correctly handle values of max = long.MaxValue
. (Martin's answer has neither problem, but his code is unreasonably slow with large ranges.)
The following code will fix all of those issues:
//Working with ulong so that modulo works correctly with values > long.MaxValue ulong uRange = (ulong)(max - min); //Prevent a modolo bias; see https://stackoverflow.com/a/10984975/238419 //for more information. //In the worst case, the expected number of calls is 2 (though usually it's //much closer to 1) so this loop doesn't really hurt performance at all. ulong ulongRand; do { byte[] buf = new byte[8]; random.NextBytes(buf); ulongRand = (ulong)BitConverter.ToInt64(buf, 0); } while (ulongRand > ulong.MaxValue - ((ulong.MaxValue % uRange) + 1) % uRange); return (long)(ulongRand % uRange) + min;
The following fully-documented class can be dropped into your codebase to implement the above solution easily and brain-free. Like all code on Stackoverflow, it's licensed under CC-attribution, so you can feel free to use to use it for basically whatever you want.
using System; namespace MyNamespace { public static class RandomExtensionMethods { /// <summary> /// Returns a random long from min (inclusive) to max (exclusive) /// </summary> /// <param name="random">The given random instance</param> /// <param name="min">The inclusive minimum bound</param> /// <param name="max">The exclusive maximum bound. Must be greater than min</param> public static long NextLong(this Random random, long min, long max) { if (max <= min) throw new ArgumentOutOfRangeException("max", "max must be > min!"); //Working with ulong so that modulo works correctly with values > long.MaxValue ulong uRange = (ulong)(max - min); //Prevent a modolo bias; see https://stackoverflow.com/a/10984975/238419 //for more information. //In the worst case, the expected number of calls is 2 (though usually it's //much closer to 1) so this loop doesn't really hurt performance at all. ulong ulongRand; do { byte[] buf = new byte[8]; random.NextBytes(buf); ulongRand = (ulong)BitConverter.ToInt64(buf, 0); } while (ulongRand > ulong.MaxValue - ((ulong.MaxValue % uRange) + 1) % uRange); return (long)(ulongRand % uRange) + min; } /// <summary> /// Returns a random long from 0 (inclusive) to max (exclusive) /// </summary> /// <param name="random">The given random instance</param> /// <param name="max">The exclusive maximum bound. Must be greater than 0</param> public static long NextLong(this Random random, long max) { return random.NextLong(0, max); } /// <summary> /// Returns a random long over all possible values of long (except long.MaxValue, similar to /// random.Next()) /// </summary> /// <param name="random">The given random instance</param> public static long NextLong(this Random random) { return random.NextLong(long.MinValue, long.MaxValue); } } }
Usage:
Random random = new Random(); long foobar = random.NextLong(0, 1234567890L);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With