3

在做一个简单的 PRNG 项目时。我遇到了 Math.pow 的奇怪行为,只是将数字相乘。这是什么原因?我已经包含了 PRNG 类,以及我用来运行程序的主类。如果比较结果,它会很好地开始,但在第 3 次迭代中,乘法 PRNG 与 Math.pow() PRNG 不同。乘法 PRNG 也开始给出负数。这是不应该的。

public class PRNG {
int seed;
/**
 * Creates a PRNG with the seed x0
 */
public PRNG(int x0){
    this.seed = x0;
}

/**
 * Return the next random number
 */
public int nextRand(){
    //seed = (int) ((Math.pow(7, 5) * seed) % (Math.pow(2, 31) - 1));
    seed = (int) ((7*7*7*7*7 * seed) % (Math.pow(2, 31) - 1));
    return seed;
} 

}

主要的:

public class main {
final static int SEED = 1;

public static void main(String[] args) {
    PRNG prng = new PRNG(SEED);     

    for(int i = 0; i < 100; i++){
        System.out.println(prng.nextRand());
    }
}

}

提前致谢!

4

3 回答 3

11

这是因为您溢出了种子的 INT 值。

将您的代码更改为:

seed = (int) ((7*7*7*7*7 * (long)seed) % (Math.pow(2, 31) - 1));

修复问题。

于 2013-10-01T19:48:09.917 回答
0

为了解决您的问题的标题,没有区别。

public class MathPow {
    public static void main(String[] args) {
        testInt();
        testLong();
    }

    private static void testInt(){
        int a = 7*7*7*7*7;
        int b = (int) Math.pow(7,5);
        System.out.printf("a=%d b=%d (a==b)=%b\n", a, b, a==b);
    }
    private static void testLong(){
        long a = 7*7*7*7*7;
        long b = (long) Math.pow(7,5);
        System.out.printf("a=%d b=%d (a==b)=%b\n", a, b, a==b);
    }
}

产生输出:

a=16807 b=16807 (a==b)=true
a=16807 b=16807 (a==b)=true
于 2013-10-01T19:50:56.133 回答
0

要解决您关注的行为而不是帖子的标题:

评价步骤:

seed = (int) ((Math.pow(7, 5) * seed) % (Math.pow(2, 31) - 1));
  • Math.pow(7, 5) = 双倍 (16807)
  • 双 * int = 双(64 位)
  • Math.pow(2,31) = 双倍
  • 双 - int = 双
  • 双 % 双 = 双
  • double 被强制转换为 int

seed = (int) ((7*7*7*7*7 * seed) % (Math.pow(2, 31) - 1));

  • 7*7*7*7*7 = 整数 (16807)
  • int * int = int // 这里的整数值溢出。
  • Math.pow(2,31) = 双倍
  • 双 - int = 双
  • int % 双倍 = 双倍
  • double 被强制转换为 int

展示:

public class MathPow {
    static int seed=1;

    public static void main(String[] args) {
        System.out.println("7*7*7*7*7");
        whatType(7*7*7*7*7);
        whatType(7*7*7*7*7*seed);
        whatType(Math.pow(2,31));
        whatType(Math.pow(2,31)-1);
        whatType(((7*7*7*7*7 * seed) % (Math.pow(2, 31) - 1)));

        System.out.println("Math.pow(7,5)");
        whatType(Math.pow(7,5));
        whatType(Math.pow(7,5) * seed);
        whatType(Math.pow(2,31));
        whatType(Math.pow(2,31)-1);
        whatType((Math.pow(7, 5) * seed) % (Math.pow(2, 31) - 1));

    }
    private static void whatType(Object o){
        System.out.println(o.getClass());
    }
}

输出:

7*7*7*7*7
class java.lang.Integer
class java.lang.Integer
class java.lang.Double
class java.lang.Double
class java.lang.Double
Math.pow(7,5)
class java.lang.Double
class java.lang.Double
class java.lang.Double
class java.lang.Double
class java.lang.Double
于 2013-10-01T20:08:28.797 回答