Java-java Random.nextFloat 的问题
http://docs.oracle.com/javase/7/docs/api/java/util/Random.html
java7的Random.nextFloat实现是:
public float nextFloat() {
return next(24) / ((float)(1 << 24));
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先引述其中的next方法说明:
int java.util.Random.next(int bits)
Generates the next pseudorandom number. Subclasses should override this, as this is used by all other methods.
The general contract of next is that it returns an int value and if the argument bits is between 1 and 32 (inclusive), then that many low-order bits of the returned value will be (approximately) independently chosen bit values, each of which is (approximately) equally likely to be 0 or 1. The method next is implemented by class Random by atomically updating the seed to
(seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)
and returning
(int)(seed >>> (48 - bits)).
This is a linear congruential pseudorandom number generator, as defined by D. H. Lehmer and described by Donald E. Knuth in The Art of Computer Programming, Volume 3: Seminumerical Algorithms, section 3.2.1.
Parameters:
bits random bits
Returns:
the next pseudorandom value from this random number generator's sequence
Since:
1.1
请注意最后的输出结果:
(int)(seed >>> (48 - bits)).
参考下面的引文:
http://www.math.utah.edu/~beebe/java/random/README
里面提到了为什么早期版本要获取48位中的30位高位(high-order),是发现16位low-order出现0的概率要高于1的概率。我个人猜测现在改为24位也是出于这个原因,后期使用过程中发现不光是低16位。这个算法得到的结果依赖于选取的种子数。
早上写了好多,本以为解决了,后来想想不对。线性同余生成算法没有过多了解,不过这样一个简单的公式就可以在近乎全空间生成近乎平均的伪随机值来讲真的太伟大了。
关于上面2/3的那个结论,我写了一个case,用的是long,发现确实是不均匀的,后50%只有可怜的25%。对于float起码落在前后的概率是相同的,但是暂时没验证全空间均匀。
资料:
http://en.wikipedia.org/wiki/Linear_congruential_generator
http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextFloat%28%29
jdk api doc;
http://www.math.utah.edu/~beebe/java/random/README
首先计算机中不能模拟出绝对的随机数
其次jdk中随机数也是通过算法进行实现的,以前有人做过一个统计,随机数会有三分之二的机会落到前50%中,如果想做到相对均匀的分布,可以自己写算法映射一下