Java 为什么允许对nextLong()的底部单词进行签名?

Java 为什么允许对nextLong()的底部单词进行签名?,java,random,bit-shift,mersenne-twister,Java,Random,Bit Shift,Mersenne Twister,Random类有一个方法nextLong,它自己调用next32,返回一个随机有符号整数 public long nextLong() { // it's okay that the bottom word remains signed. return ((long)(next(32)) << 32) + next(32); } 为什么保持底部单词的签名不会影响随机生成的数字的质量?当构造一个例子时,如果底部字为负值,生成的长值中间的一个位为零。 final lon

Random类有一个方法nextLong,它自己调用next32,返回一个随机有符号整数

public long nextLong() {
    // it's okay that the bottom word remains signed.
    return ((long)(next(32)) << 32) + next(32);
}
为什么保持底部单词的签名不会影响随机生成的数字的质量?当构造一个例子时,如果底部字为负值,生成的长值中间的一个位为零。
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

目前,较低的字贡献33位,而较高的字只有32位。即使由于32位移位,上面的字是负数,它也不会环绕。我知道javadocs声明:

因为类{@code Random}使用的种子只有48位, 此算法不会返回所有可能的{@code long}值

在这种情况下,它可能不会有害,但例如,gmu的实现正好使用此函数调用。这不会影响生成的随机数的质量吗?我错过了什么


目前,较低的字贡献33位,而较高的字只有32位

我错过了什么

正如Jacob G指出的,低位字贡献32位。不是33位。一个32位整数大约是31位精度加上一个符号位


在本例中,我们只是将这些31+1位视为位。那么代码做的是取两个由32个均匀分布的随机位组成的序列,将它们连接在一起,得到一个由64个均匀分布的随机位组成的序列。。。然后以长的形式返回。

当前较低的字贡献了33位-您是如何得出这个结论的?第32位是符号位;不存在第33位。@JacobG。因为在上面的单词示例中,第33-63位由1表示,而结果的第33位由输出结果显示为0。