views:

801

answers:

3

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
There are special cases for a double (like NaN) that you'd want to avoid.
Jon B
-0 Jon is right. The worse thing is the number is not between 0 and 1.
Mehrdad Afshari
Try this: BitConverter.GetBytes(double.NaN). Returns and 8 byte array ending in 248, 255.
Jon B
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
See my comment to Michael's post. May result in NaN, -Infinity, etc.
Jon B
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
+6  A: 
byte[] result = new byte[8];
rng.GetBytes(result);
return (double)BitConverter.ToUInt64(result,0) / ulong.MaxValue;
Mehrdad Afshari
My brain can't handle simple math today. That's exactly what I was trying to do. +1 to you.
Jon B
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
@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
Thank you Mehrdad! Works like a charm!
Kamil Zadora