我实际上正在开展一个项目,但我遇到了一个问题:
我必须从范围Double
生成随机[a, b]
值。通过在互联网上搜索,有人说下面的公式有效:
b + (b - a) * random.nextDouble();
但如果我们做一些微积分,我们发现a
不可能被包括在内。
我怎么能做这样的事情?有没有人有任何线索?
提前感谢您的帮助!
答案 0 :(得分:3)
nextDouble
函数的工作原理是创建一个53位整数,然后除以2 ^ 53.来自javadocs:
public double nextDouble() {
return (((long)next(26) << 27) + next(27))
/ (double)(1L << 53);
}
因此产生范围[0, 1)
- 上限接近(n - 1) / n
的限制。
要创建完全包含范围,请自行创建该53位整数,但用(2 ^ 53) - 1
除以。
请注意,就所有意图和目的而言,包容性和排他性之间的差异几乎不重要 - 与修改后的代码完全匹配1.0
的几率为1 / ((2 ^ 53) - 1)
- 几乎无限小的数字。
此外,(2 ^ 53) - 1
的这种划分可能比原始代码慢得多。 2 ^ n
除以对于CPU来说是完全无关紧要的,因为它所做的只是递减浮点指数并可能使尾数移位。除数上的- 1
使得除法更加冗长,甚至可能使得结果序列的随机性低于低阶位的随机序列。
答案 1 :(得分:2)
这更合乎逻辑
a + (b - a) * random.nextDouble();
<强>更新强>
但是这个逻辑将排除b,因为random.nextDouble();范围在[0,1)之间,这意味着它不包括1.