System.Random类 - 关于NextDouble()的警示故事 [英] System.Random Class - a cautionary tale about NextDouble()

查看:115
本文介绍了System.Random类 - 关于NextDouble()的警示故事的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可能会合理地期望Random NextDouble()方法返回小于1的随机浮点数。并且如文件所述,大于或等于零。嗯它确实!


但是不要指望它在这个范围内返回一个随机的Double;它没有。


然而,Double是NextDouble()的声明返回类型;什么给出了?


最后,通过访问文档和源代码,我们可以看到实际发生的事情:


https://msdn.microsoft .com / zh-CN / library / system.random(v = vs.110).aspx


是的,你会在0到1之间得到2 ^ 32个可能的随机双数,在此范围内可用的2 ^ 52个随机双数中。从未生成此范围内的大量双精度数。事实上,只有大约一亿美元的可能数字生成。


因此,如果您从事科学或工程计算,NextDouble()可能会导致实际问题。


例如,使用NextDouble()生成的100,000个随机数的列表将超过可能有重复的条目。根据双精度定义,您可以预期在这种重复的
百万美元中只有一次机会。


此外,任意两个随机数之间的差异将始终大于0到1范围内的某个值(约1e-6)。但实际上任何两个真正的 随机双数可以有差异
到大约Double.MinValue。


只是说应该修复,或至少澄清。 Double q1 = r1.nextDouble()不会产生精度为double的均匀随机变量。我说这是一个合理的期望它应该是,
就像你期望双Math.Sin(x)精确到最低有效位一样。


注意:Microsoft似乎在Excel的= Rand()函数中做得更好。


解决方案

< blockquote>

与往常一样,如果您需要严格(例如,加密质量)随机数,请不要使用Random类。就像几乎所有其他编程语言一样(除了那些专门用于统计分析的编程语言),默认随机数生成器的性能优化为
(生成数字的速度),而不是随机性质。


文档的备注部分已经将其调出:


[quote]


生成加密安全随机数,例如一个这适用于创建随机密码,请使用

RNGCryptoServiceProvider
类或从
System.Security.Cryptography RandomNumberGenerator


[/ quote]


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:

https://msdn.microsoft.com/en-us/library/system.random(v=vs.110).aspx

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.

解决方案

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:

[quote]

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.

[/quote]


这篇关于System.Random类 - 关于NextDouble()的警示故事的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆