Frage

The same XorShift functions written in C and Python give different results. Can you explain it?

The XorShift function generates numbers in the following way:

x(0) = 123456789
y(0) = 362436069
z(0) = 521288629
w(0) = 88675123 

x(n+1) = y(n)
y(n+1) = z(n)
z(n+1) = w(n)
w(n+1) = w(n) ^ (w(n)>>19) ^ (x(n)^(x(n)<<11)) ^ ((x(n)^(x(n)<<11)) >> 8)

I wrote this function in Python to generate subsequent values of w:

X = 123456789
Y = 362436069
Z = 521288629
W = 88675123

def xor_shift():
    global X, Y, Z, W
    t = X ^ (X << 11)
    X = Y
    Y = Z
    Z = W
    W = W ^ (W >> 19) ^ t ^ (t >> 8)
    return W

W1 = xor_shift() # 252977563114
W2 = xor_shift() # 646616338854
W3 = xor_shift() # 476657867818

The same code written in C (it can be found on Wikipedia http://en.wikipedia.org/wiki/Xorshift) gives different results:

#include <stdint.h>
uint32_t xor128(void) {
    static uint32_t x = 123456789;
    static uint32_t y = 362436069;
    static uint32_t z = 521288629;
    static uint32_t w = 88675123;
    uint32_t t;

    t = x ^ (x << 11);
    x = y; y = z; z = w;
    return w = w ^ (w >> 19) ^ t ^ (t >> 8);
}

cout << xor128() <<'\n'; // result W1 = 3701687786
cout << xor128() <<'\n'; // result W2 = 458299110
cout << xor128() <<'\n'; // result W3 = 2500872618

I suppose that there is a problem with my Python code or my use of cout (I am not very good at C++).

EDIT: Working solution:

need to change the return value from uint32_t to uint64_t:

#include <stdint.h>
uint64_t xor128(void) {
    static uint64_t x = 123456789;
    static uint64_t y = 362436069;
    static uint64_t z = 521288629;
    static uint64_t w = 88675123;
    uint64_t t;

    t = x ^ (x << 11);
    x = y; y = z; z = w;
    return w = w ^ (w >> 19) ^ t ^ (t >> 8);
}
War es hilfreich?

Lösung

Change all your uint32_t types to uin64_t and you'll get the same result. The difference is the precision between uint32_t and the unlimited precision of python integer types.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top