System.Random Class - a cautionary tale about NextDouble() RRS feed

  • Question

  • One might reasonably expect the Random NextDouble() method to return a random floating point number less than  1. and greater than or equal to zero as the documentations states. Well it does!.

    But do not expect it to return a random Double in this range ; IT DOES NOT.

    And yet Double is the stated return type of NextDouble(); so what gives?

    Finally, with access to the documentation and source code we can see what really happens:

    Yes that's right, you will get 2^32 possible random double numbers between 0 and 1, out of the possible 2^52 random double numbers available in this range. Plenty of double precision numbers in this range are never generated. In fact only about one in a million of the possible numbers are ever generated.

    So if you are into scientific or engineering based computing, NextDouble() can cause real problems.

    For example a list of 100,000 random numbers generated using NextDouble() will more than likely have duplicate entries. From the double precision definition you would expect about a one chance in a million of such a duplicate.

    Also, the difference between any two random numbers will always be greater than a certain value (about 1e-6) in range 0 to 1. but in reality any two truly  random double numbers can have a difference down to about Double.MinValue.

    Just saying it should be fixed, or at least clarified. Double q1=r1.nextDouble() does NOT result in a uniform random variable of precision double. I say it is a reasonable expectation that it should, just as you would expect double Math.Sin(x) to be accurate to the least significant bit.

    NOTE: Microsoft seem to have done a better job in Excel's =Rand() function.

    • Edited by Jeltz191 Wednesday, August 23, 2017 2:21 AM
    Wednesday, August 23, 2017 2:16 AM

All replies

  • As always, don't use Random class if you need serious (say, cryptographic quality) random numbers. Just like almost all other programming languages (except those created specialized for statistics analysis), the default random number generator is optimized for performance (speed of generating the numbers), not quality of randomness.

    The remark section of documentation already called it out:


    To generate a cryptographically secure random number, such as one that's suitable for creating a random password, use the RNGCryptoServiceProvider class or derive a class from System.Security.Cryptography.RandomNumberGenerator.


    Thursday, August 24, 2017 2:04 AM