我正在从C到Go移植一个简单​​的RNG函数,给出不正确的结果

Nic*_*ick 1 c go

我正在将一个简单的RNG表格http://en.wikipedia.org/wiki/Multiply-with-carry移植到Golang但是,不知道哪个部分出错了,我的示例程序的结果是不一致的.

结果:

C = 58 1 78 15 57 28 96 73 47 12 61 47 74 86 91 93
GO= 58 8 18 48 90 72 18 84 54 52 94 80 18 8 2 0 
Run Code Online (Sandbox Code Playgroud)

而且我也不明白为什么t,在原始源中使用uint64而不是uint32.

下面是C main和Go counter部分:

去文件:http://play.golang.org/p/YVyIr1bcI8

原C:

#include <cstdlib>
#include <cstdio>

#include <stdint.h>

#define PHI 0x9e3779b9

static uint32_t Q[4096], c = 362436;

void init_rand(uint32_t x)
{
        int i;

        Q[0] = x;
        Q[1] = x + PHI;
        Q[2] = x + PHI + PHI;

        for (i = 3; i < 4096; i++)
                Q[i] = Q[i - 3] ^ Q[i - 2] ^ PHI ^ i;
}

uint32_t rand_cmwc(void)
{
        uint64_t t, a = 18782LL;
        static uint32_t i = 4095;
        uint32_t x, r = 0xfffffffe;
        i = (i + 1) & 4095;
        t = a * Q[i] + c;
        c = (t >> 32);
        x = t + c;
        if (x < c) {
                x++;
                c++;
        }
        return (Q[i] = r - x);
}

int main( int argc, char* argv[])
{
    init_rand(0);

    uint32_t v=0;
    for( int i=0; i<16; i++)
    {
        v = rand_cmwc();
        printf( "%d ", (v%100));
    }

    char input_buf[24]={0};

    printf( "\nType a character to exit:", v);
    scanf("%s", input_buf);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

unw*_*ind 5

咦?

更新时,C代码执行64位整数arithemetic,保持最高 32位:

i = (i + 1) & 4095;
t = a * Q[i] + c;
c = (t >> 32);
Run Code Online (Sandbox Code Playgroud)

在Go代码中,您只使用32位整数; 当然这是不正确的,因为它永远不会产生适当的高位.