出于好奇,Math.random()可以为零吗?
例如,如果我有:
while (true){
if (Math.random() == 0)
return 1;
}
Run Code Online (Sandbox Code Playgroud)
我真的会得到一个回报吗?还需要考虑舍入误差,因为Math.random()返回一个double.
我问,因为我的CS教授说random()从0到1包括在内,我一直认为它是独占的.
Ang*_*ngs 38
是的,它确实可以.Math.random()创建一个java.util.Random带有种子的全局生成器(System.currentTimeMillis() ^ 0x5DEECE66DL) & ((1L << 48) - 1)并调用nextDouble()它.如果它的种子到达状态107048004364969L(并且它将java.util.Random具有完整的时间段),则下一个double生成的将是0.0.虽然运气不好,但你可能最终会在周期中出现错误的平价,因为这
Random.nextDouble()会使状态两次提升.如果运气稍差,你可能不得不在循环结束之前生成2 ^ 47个随机数,因为我没有找到任何其他种子0.0.
种子前进,好像是,seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
并且使用两个连续种子值的26和27个高位生成双精度.在示例中,两个下一个种子值将为0L和11L.
如果您设法创建全局生成器System.currentTimeMillis()==107038380838084L,则代码会立即返回.你可以用以下方法模拟:
java.util.Random k = new java.util.Random(107038380838084L);
System.out.println(k.nextDouble()==0);
Joe*_*oey 10
它完全有可能永远不会返回零.Java包含的PRNG是一个48位的LCG,从中只使用了32位.对于double尾数的所有53位为零,您基本上需要至少一次调用next()高32位为零的位置和另一位大多数位于零的位置.(如果我没弄错的话,我会说发生器的工作方式不会发生这种情况,但现在已经很晚了,我已经累了,我也不会打赌它.)
由于方法文档明确说明了如何获得随机数,因此Java运行库的其他实现几乎没有余地产生不同的结果.该合约可能会说,你得到的数字是[0,1).但实际上有很多值你永远不会命中(因为你需要来自生成器的两个连续值,它们可以在连续值之间产生线性相关性 - 只有48位状态.你不能生成所有不同的值53位组合 - 至少不是它的完成方式.)
当然,由于Math.random()自动播种静态Random实例,我们可能还必须考虑这里的种子,这可能需要非常具体才能使测试用例得以解决.这可能意味着确切的时间点可能是几十年或几千年.
从理论上讲,它可以返回零值.
在实践中,您可能需要等待很长时间才能完全为零.如果随机数发生器实现良好,它至少有56位内部状态(否则返回结果的所有位都不是随机的).这意味着,如果随机生成的值的分布是平坦的,那么在2 ^ 56中最多只有一次机会获得所有位为零的值.这大约是10 ^ -19.我不会屏住呼吸.
(其他人正确地观察到,如同记载的那样,理论上[并且可能在实践中]它不能返回值1.0).
| 归档时间: |
|
| 查看次数: |
12006 次 |
| 最近记录: |