Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Park Miller Carta PRNG随机发生器allways返回2.33E-10_Java_Actionscript 3_Random - Fatal编程技术网

Java Park Miller Carta PRNG随机发生器allways返回2.33E-10

Java Park Miller Carta PRNG随机发生器allways返回2.33E-10,java,actionscript-3,random,Java,Actionscript 3,Random,我正在尝试用Java实现Park Miller Carta PRNG随机数生成器 下面是ActionScript 3中随机函数的实现 我没有太多的运气让它在Java中工作: int seed = 20; //for example. public double random() { seed = (seed * 16807) % 2147483647; return seed / 0x7FFFFFFF + 0.000000000233; } 这总是返回2.33E-10。你知道

我正在尝试用Java实现Park Miller Carta PRNG随机数生成器

下面是ActionScript 3中随机函数的实现

我没有太多的运气让它在Java中工作:

int seed = 20; //for example.

public double random() {
    seed = (seed * 16807) % 2147483647;
    return seed / 0x7FFFFFFF + 0.000000000233;
}
这总是返回
2.33E-10
。你知道我在Java中做错了什么吗?(AS3代码返回
0.0001565276181885122
,然后返回
0.630757630963248
,前两个响应的种子为
20
)。

替换:

return seed / 0x7FFFFFFF+0.000000000233;
与:

是一个整数运算,因为两个参数都是整数。整数除法总是向下舍入“真”结果。在这种情况下,真实结果介于0和1之间,因此操作始终返回0

要获得浮点结果,至少有一个参数必须是浮点,可以这样实现:

return (double)seed / 0x7FFFFFFF + 0.000000000233;
运算符优先级

(seed / 0x7FFFFFFF)+0.000000000233;

是你真正拥有的。这就是你的意思吗?

好的,那么关键的问题是你需要做浮点除法,而不是像其他人指出的那样做整数除法

但我认为修复这个特定的代码有点超出了重点。为什么一开始就要麻烦它呢?它使用的基本上是同一类算法java.lang.Random

如果你想要一个快速生成器,考虑一个。如果你想要一个质量好的生成器,你就有了它(尽管它慢得多),考虑一下数字配方算法(一个相当快的组合发生器),你可以在java中实现如下:

public class HighQualityRandom extends Random {

  private Lock l = new ReentrantLock();
  private long u;
  private long v = 4101842887655102017L;
  private long w = 1;

  public HighQualityRandom() {
    this(System.nanoTime());
  }
  public HighQualityRandom(long seed) {
    l.lock();
    u = seed ^ v;
    nextLong();
    v = u;
    nextLong();
    w = v;
    nextLong();
    l.unlock();
  }

  @Override
  public long nextLong() {
    l.lock();
    try {
      u = u * 2862933555777941757L + 7046029254386353087L;
      v ^= v >>> 17;
      v ^= v << 31;
      v ^= v >>> 8;
      w = 4294957665L * (w & 0xffffffff) + (w >>> 32);
      long x = u ^ (u << 21);
      x ^= x >>> 35;
      x ^= x << 4;
      return (x + v) ^ w;
    } finally {
      l.unlock();
    }
  }

  protected int next(int bits) {
    return (int) (nextLong() >>> (64-bits));
  }

}
公共类HighQualityRandom扩展了Random{
private Lock l=新的可重入锁();
私人长u;
专用长v=41018428876551017L;
私人长w=1;
公共暴政(){
这个(System.nanoTime());
}
公共高质量暴政(长种子){
l、 锁();
u=种子^v;
nextLong();
v=u;
nextLong();
w=v;
nextLong();
l、 解锁();
}
@凌驾
公共长下长(){
l、 锁();
试一试{
u=u*286293355577941757L+7046029254386353087L;
v^=v>>>17;
v^=v>>8;
w=4294957665L*(w&0xffffffff)+(w>>>32);
长x=u^(u>>35;
x^=x>>(64位);
}
}
这是从我需要并发的代码中复制出来的;原则上可以去掉锁,或者只使用常规同步


如果您绝对坚持使用Park Miller Carta,我至少会将其包装在一个随机子类中,并让java.util.Random负责将int转换为double等——毕竟,这就是面向对象语言中的可扩展库的用途……

为什么?如果这是为了您自己的启发,这是一件事,但对于生产代码来说确实是good(即加密安全)生成随机数非常困难。RNG可能是大多数密码系统中最大的技术漏洞。@Chris和Park Miller Carta相当糟糕。不,优先级规则可能不同。此外,除法运算符的语义可能不同,这似乎是已经发生的事。
return (double)seed / 0x7FFFFFFF + 0.000000000233;
(seed / 0x7FFFFFFF)+0.000000000233;
public class HighQualityRandom extends Random {

  private Lock l = new ReentrantLock();
  private long u;
  private long v = 4101842887655102017L;
  private long w = 1;

  public HighQualityRandom() {
    this(System.nanoTime());
  }
  public HighQualityRandom(long seed) {
    l.lock();
    u = seed ^ v;
    nextLong();
    v = u;
    nextLong();
    w = v;
    nextLong();
    l.unlock();
  }

  @Override
  public long nextLong() {
    l.lock();
    try {
      u = u * 2862933555777941757L + 7046029254386353087L;
      v ^= v >>> 17;
      v ^= v << 31;
      v ^= v >>> 8;
      w = 4294957665L * (w & 0xffffffff) + (w >>> 32);
      long x = u ^ (u << 21);
      x ^= x >>> 35;
      x ^= x << 4;
      return (x + v) ^ w;
    } finally {
      l.unlock();
    }
  }

  protected int next(int bits) {
    return (int) (nextLong() >>> (64-bits));
  }

}