Java中的Xorshift随机
我正在尝试用Java实现。它有一个C语言的例子,它有无符号的long。考虑到Java没有无符号数字,我怎样才能去掉下面代码中的Java中的Xorshift随机,java,random,Java,Random,我正在尝试用Java实现。它有一个C语言的例子,它有无符号的long。考虑到Java没有无符号数字,我怎样才能去掉下面代码中的Math.abs 我只想要正数 private static long x = 0; private static long y = 0; private static long z = 0; private static long w = 0; private static long xorShiftRandom() { while ((x | y | z |
Math.abs
我只想要正数
private static long x = 0;
private static long y = 0;
private static long z = 0;
private static long w = 0;
private static long xorShiftRandom() {
while ((x | y | z | w) == 0) {
Random rand = new Random();
x = rand.nextLong();
y = rand.nextLong();
z = rand.nextLong();
w = rand.nextLong();
}
long t = x ^ (x << 11);
x = y;
y = z;
z = w;
return w = Math.abs(w ^ (w >>> 19) ^ (t ^ (t >>> 8)));
}
私有静态长x=0;
私有静态长y=0;
私有静态长z=0;
私有静态长w=0;
私有静态长xorShiftRandom(){
而((x | y | z | w)==0){
Random rand=新的Random();
x=rand.nextLong();
y=rand.nextLong();
z=rand.nextLong();
w=rand.nextLong();
}
长t=x^(x>>19)^(t^(t>>8));
}
Java中没有未签名,因此这不是一个选项。我认为实际上你的问题是当打印它们时,它们显示为负片。您可以使用十六进制格式(Long.toHexString()
)来显示无符号值。或者,您可以使用更大的holder(如biginger
)来表示无符号十进制
编辑:如果Java中的
long
从long.MIN\u值
生成到long.MAX\u值
,则随机数生成器将生成整个域中的数字,而不仅仅是正数(仅为域的一半)。您可以将函数的最后一行更改为:
w = (w ^ (w >>> 19) ^ (t ^ (t >>> 8)));
return w & 0x7fffffffffffffffL;
这仍将生成所有64位,但仅报告其中的63位
顺便说一下,您不应该在多次调用方法的情况下产生一个新的
Random
对象。移动Random rand=new Random()代码>到您要声明的x
、y
、z
和w
,并将其设置为私有静态
。即使在第一次调用方法后几乎不会触发循环,但多次实例化PRNG通常不是一个好主意。请注意,您的算法是完全错误的。来自Wikipedia的示例使用32位变量。它是一个128位的状态生成器,您使用的移位只会为这样的生成器提供一个最大周期
DSI实用程序()包含几个xorshift*/xorshift+生成器的实现,它们是xorshift的64位变体,不显示线性伪影。我建议你从那里开始。你指的是什么?如果是这样,那就是一个C示例。(另外,在你的问题中把这个联系起来会很好。)@John,我只想要正数。。。移位产生的大多是负数,有没有一种方法可以在不使用abs功能的情况下获得正数?@mfc位操作与符号无关。你的问题实际上是当显示这些值时,请看我的答案。与你的abs无关()问题:虽然x,y,z,w不可能都为零,但它们中的一个或多个为零是完全可以的。有一个操作确实关心符号,而且是向右移动,这可以通过符号扩展或仅对原始位执行,就像数字是无符号的一样。不出所料,Java同时提供了>
和>
运营商来满足这一需求。但即使在Java中,这是一个关心符号性的按位操作。@Joey实际上,>>是按位移位,>>>是算术移位。所以没有关心符号性的位运算。@Kayaman不,他们关心符号是因为符号扩展,请看。哦,我的意思是>>是算术移位。>>>是逻辑移位,不是按位移位。