自从我听说它以来,我一直在使用java的SplittableRandom,因为它速度快,而且不需要多线程。但是,虽然几乎所有来自Random类的方法都没有nextFloat()
。为什么?
现在,真正的问题是,我将如何创建nextFloat
方法呢?看到double
生成如下:(来自JDK 8)
final double internalNextDouble(final double n, final double n2) {
double longBitsToDouble = (this.nextLong() >>> 11) * 1.1102230246251565E-16;
if (n < n2) {
longBitsToDouble = longBitsToDouble * (n2 - n) + n;
if (longBitsToDouble >= n2) {
longBitsToDouble = Double.longBitsToDouble(Double.doubleToLongBits(n2) - 1L);
}
}
return longBitsToDouble;
}
..我希望我能用以下内容将其转换为32位数字生成;
final float internalNextFloat(final float min, final float max) {
float intBitsToFloat = (this.nextInt() >>> 11) * 1.1102230246251565E-16f;
if (min < max) {
intBitsToFloat = intBitsToFloat * (max - min) + min;
if (intBitsToFloat >= max) {
intBitsToFloat = Float.intBitsToFloat(Float.floatToIntBits(max) - 1);
}
}
return intBitsToFloat;
}
然而,这会返回0.000000
。我只能假设它溢出某处,在这种情况下我很确定问题出在以下几行:
(this.nextInt() >>> 11) * 1.1102230246251565E-16f;
所以,没有经历过转移(我猜想使用epsilon),我怎么能达到我的目的呢?
答案 0 :(得分:2)
在没有深入思考这个数学的情况下,在我看来,您可以使用nextDouble
方法在所需范围内生成double
,然后将结果转换为{{ 1}}。
答案 1 :(得分:1)
你需要先了解这一行背后的含义:
double longBitsToDouble = (this.nextLong() >>> 11) * 1.1102230246251565E-16;
this.nextLong()
返回64长。>>> 11
将long
转为无符号并删除最后11位,因此现在我们得到一个53位随机值。这也是double
的精确度。* 1.1102230246251565E-16
。这相当于1 / 9007199254740992.0
或2 -53 。所以longBitsToDouble
是从0(含)到1(不包含)的随机统一double
。
与float
相比,其精度为24位,而this.nextInt()
生成32位随机值,因此相应的行应写为
float intBitsToFloat = (this.nextInt() >>> 8) * 5.960464477539063E-8f;
(而不是十进制表示法5.960464477539063E-8f
,您也可以使用hexadecimal float,这可能会让读者更清楚:
float intBitsToFloat = (this.nextInt() >>> 8) * 0x1.0p-24;
)