简体   繁体   English

为什么允许保留nextLong()的底部单词签名?

[英]Why is it allowed to keep the bottom word of nextLong() signed?

The java.util.Random class has a method nextLong() which on it's own calls next(32) returning a random signed integer. java.util.Random类具有一个nextLong()方法,该方法自己调用next(32)返回一个有符号整数。

public long nextLong() {
    // it's okay that the bottom word remains signed.
    return ((long)(next(32)) << 32) + next(32);
}

How come keeping the bottom word signed does not impact the quality of the randomly generated numbers? 为何使底部单词保持签名不会影响随机生成的数字的质量? When constructing an example a bit in the middle of the generated long value is zeroed if the bottom word is negative. 构造示例时,如果底部字为负,则生成的long值中间的位将清零。

final long INTEGER_MASK = 0xFFFFFFFFL;

int upper = Integer.MAX_VALUE;
int bottom = -1;

System.out.printf("%14s %64s%n","Upper:",Long.toBinaryString(((long)upper << 32)));
System.out.printf("%14s %64s%n","Lower:",Long.toBinaryString((long)bottom));

System.out.printf("%14s %64s%n"," Lower Masked:",Long.toBinaryString(((long)bottom)& INTEGER_MASK));

long result = ((long)upper << 32) + bottom;
System.out.printf("%14s %64s%n","Result:",Long.toBinaryString(result));

//Proper
long resultMasked = ((long)upper << 32) + (((long)bottom & INTEGER_MASK));
System.out.printf("%14s %64s%n%n","Masked",Long.toBinaryString(resultMasked));


Upper:  111_1111_1111_1111_1111_1111_1111_1111_0000_0000_0000_0000_0000_0000_0000_0000
Lower: 1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111
Lower Mask:                                    1111_1111_1111_1111_1111_1111_1111_1111    
Result: 111_1111_1111_1111_1111_1111_1111_1110_1111_1111_1111_1111_1111_1111_1111_1111
Masked  111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111

Currently the lower word contributes 33 bits while the upper only has 32 bits. 当前,低位字贡献33位,而高位字仅贡献32位。 Even if the upper word is negative due to the 32 bit shift it won't wrap around. 即使由于32位移位而使高位字为负,它也不会回绕。 I am aware of the javadocs stating that: 我知道javadocs指出:

Because class {@code Random} uses a seed with only 48 bits, this algorithm will not return all possible {@code long} values. 由于类{@code Random}仅使用48位种子,因此该算法不会返回所有可能的{@code long}值。

In this case it might not be detrimental but eg gmu's MersenneTwister implementation uses exactly this function call. 在这种情况下,它可能不会有害,但是例如gmu的MersenneTwister实现完全使用此函数调用。 Doesn't this impact the quality of random numbers generated? 这不影响生成的随机数的质量吗? What am I missing here? 我在这里想念什么?

Currently the lower word contributes 33 bits while the upper only has 32 bits. 当前,低位字贡献33位,而高位字仅贡献32位。

... ...

What am I missing here? 我在这里想念什么?

As Jacob G points out, the lower word contributes 32 bits. 正如Jacob G指出的那样,低位字占32位。 Not 33 bits. 不是33位。 A 32-bit integer is (roughly speaking) 31 bits of precision plus a sign bit. 一个32位整数(大致来说)是31位精度加上一个符号位。

In this case we are just treating those 31 + 1 bits as just bits. 在这种情况下,我们只是将这31 + 1位视为仅位。 So what the code does it to take two sequences of 32 uniformly distributed "random" bits, join them together to give one sequence of 64 uniformly distributed "random" bits ... which it then returns as a long . 因此,该代码执行的操作是取两个32个均匀分布的“随机”位序列,将它们连接在一起,得到一个64个均匀分布的“随机”位序列,然后将其返回为long

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM