0

I've ported an LCG algorithm from JavaScript (by kotarou3) to Java. The original code states that if no parameters are passed to the function, it should return a real number in [0, 1), just like Math.random(). However, my implementation occasionally returns negative numbers between -1 and 0.

Code:

private int[] startingSeed = new int[]{(int) Math.floor(Math.random() * 0x10000),
        (int) Math.floor(Math.random() * 0x10000),
        (int) Math.floor(Math.random() * 0x10000),
        (int) Math.floor(Math.random() * 0x10000)};

private int[] seed = new int[4];

public double random() {
    this.seed = this.nextFrame();
    double result = (this.seed[0] << 16 >>> 0) + this.seed[1];
    result = result / 0x100000000L;
    return result;
}

public int[] nextFrame() {
    int[] seed = this.seed;
    int n = 1;

    for(int frame = 0; frame < n; ++frame) {

        int[] a = new int[]{0x5D58, 0x8B65, 0x6C07, 0x8965};
        int[] c = new int[]{0, 0, 0x26, 0x9EC3};

        int[] nextSeed = new int[]{0, 0, 0, 0};
        int carry = 0;

        for (int cN = seed.length - 1; cN >= 0; --cN) {
            nextSeed[cN] = carry;
            carry = 0;

            int aN = seed.length - 1;
            int seedN = cN;
            for(; seedN < seed.length; --aN, ++seedN) {
                int nextWord = a[aN] * seed[seedN];
                carry += nextWord >>> 16;
                nextSeed[cN] += nextWord & 0xFFFF;
            }
            nextSeed[cN] += c[cN];
            carry += nextSeed[cN] >>> 16;
            nextSeed[cN] &= 0xFFFF;
        }

        seed = nextSeed;
    }
    return seed;
}

The original code is nearly identical, only the data types int and double are vars, but the algorithm remains the same.

Ikuzen
  • 55
  • 1
  • 4
  • Do you have a link to the original algorithm or JavaScript code? With that, it might be possible to see why your code behaves differently; but without it, this may be impossible to figure out. Also, what are you expecting `>>> 0` to do? – ajb Aug 19 '14 at 00:46
  • 1
    I feel that you can do this much more simply in Java: an LCG is merely (A*B)+C mod D, and Java supports 64-bit integers, unlike JavaScript, so all this work in the `nextFrame` method could be greatly simplified. – Peter O. Aug 19 '14 at 00:51
  • I've read [here](http://stackoverflow.com/questions/1822350/what-is-the-javascript-operator-and-how-do-you-use-it) that using >>>0 "ensures you've got an integer between 0 and 0xFFFFFFFF". – Ikuzen Aug 19 '14 at 00:53
  • @Ikuzen javascript =/= java, in java that does nothing. also one of the seeds that produces an negative value is [52264, 65161, 13989, 26305] – vandale Aug 19 '14 at 00:56
  • Thanks everyone for helping me out. I'll do as Peter O. suggested and rewrite the code completely, not just "port" it to Java. – Ikuzen Aug 19 '14 at 01:13

0 Answers0