I would like to use RNGCryptoServiceProvider as my source of random numbers. As it only can output them as an array of byte values how can I convert them to 0 to 1 double value while preserving uniformity of results?
A:
You can use the BitConverter.ToDouble(...) method. It takes in a byte array and will return a Double. Thre are corresponding methods for most of the other primitive types, as well as a method to go from the primitives to a byte array.
Michael Bray
2008-12-31 17:49:52
There are special cases for a double (like NaN) that you'd want to avoid.
Jon B
2008-12-31 17:50:57
-0 Jon is right. The worse thing is the number is not between 0 and 1.
Mehrdad Afshari
2008-12-31 17:55:37
Try this: BitConverter.GetBytes(double.NaN). Returns and 8 byte array ending in 248, 255.
Jon B
2008-12-31 17:56:08
A:
Use BitConverter to convert a sequence of random bytes to a Double:
byte[] random_bytes = new byte[8]; // BitConverter will expect an 8-byte array
new RNGCryptoServiceProvider().GetBytes(random_bytes);
double my_random_double = BitConverter.ToDouble(random_bytes, 0);
Brian
2008-12-31 17:54:48
Thank you but results would be very ununiform, with their denisty increasing towards 0 and no chance to get anything between 0.5 and 1
Kamil Zadora
2008-12-31 18:43:11
+6
A:
byte[] result = new byte[8];
rng.GetBytes(result);
return (double)BitConverter.ToUInt64(result,0) / ulong.MaxValue;
Mehrdad Afshari
2008-12-31 18:00:49
My brain can't handle simple math today. That's exactly what I was trying to do. +1 to you.
Jon B
2008-12-31 18:05:07
Yeah this is much better... The situation with 1.0/value is horrible... You only need a double value > 2 before you are already halfway from 1 to 0. There are many more doubles from 2..double.Max than there is from 0..2.
Michael Bray
2008-12-31 18:09:20
@Micheal: You were right. I did notice that 1/x might be satisfied by numbers more than Max which will harm the distribution.
Mehrdad Afshari
2008-12-31 18:11:03