首页 > 解决方案 > Python和C为算法返回不同的值

问题描述

我正在尝试在 python 中为 Tausworthe 随机数生成器实现以下 c 代码。代码需要生成0到1范围内的随机数。c代码如下:

#include <stdint.h>
#include <stdio.h>


/**** VERY IMPORTANT **** :
  The initial seeds z1, z2, z3, z4  MUST be larger than
  1, 7, 15, and 127 respectively.
****/

#define SEED 987654321

static uint32_t z1 = SEED, z2 = SEED, z3 = SEED, z4 = SEED;


double lfsr113 (void)
{
   uint32_t b;
   b  = ((z1 << 6) ^ z1) >> 13;
   z1 = ((z1 & 4294967294U) << 18) ^ b;
   b  = ((z2 << 2) ^ z2) >> 27;
   z2 = ((z2 & 4294967288U) << 2) ^ b;
   b  = ((z3 << 13) ^ z3) >> 21;
   z3 = ((z3 & 4294967280U) << 7) ^ b;
   b  = ((z4 << 3) ^ z4) >> 12;
   z4 = ((z4 & 4294967168U) << 13) ^ b;
   return (z1 ^ z2 ^ z3 ^ z4) * 2.3283064365386963e-10;
}

到目前为止,我已经在 python 中实现了这个:

#Tausworthe implementation
#define seeds
s0 = 987654321
s1 = 987654321
s2 = 987654321
s3 = 987654321
b=0

def Taus():        

    global s0
    global s1
    global s2
    global s3
    global b

    b =  (((s0 << 6 )^s0) >>13)
    print(s0)
    s0 = (((s0 & 4294967294)<<18) ^ b)

    b =  (((s1 << 2) ^ s1) >>27)
    s1 = (((s1 & 4294967288) << 2) ^ b)
    b =  (((s2 << 13) ^ s2) >> 21)
    s2 = (((s2 & 4294967280) << 7) ^b)
    b  = ((s3 << 3) ^ s3) >> 12;
    s3 = ((s3 & 4294967168) << 13) ^ b;

    return((s0 ^ s1 ^ s2^s3)* 2.3283064365386963e-10)

当我运行 C 代码时,我得到的前三个值生成为 0.920278、0.277765 和 0.564335。当我运行我的 python 实现时,我得到的前三个值分别为 60479.92110524047、168598.21778273885、1344.2269172724336。

我对自己做错了什么感到有些茫然。C 实现来自关于这个特定 Tausworthe 生成器的论文的作者,因此是正确的,当我运行它时会产生我期望的结果。我需要尝试在 Python 中复制这些结果,但我怀疑 C 是强类型的,而 Python 不是,这可能会给我带来问题。

任何关于为什么我的结果如此偏离的帮助或建议将不胜感激。

标签: pythoncrandom

解决方案


Python 整数不是固定宽度;C 代码依赖于任何超过 32 位的计算被隐式截断。

为了使 Python 以同样的方式工作,您需要& 0xFFFFFFFF 在代码中添加大量操作,以将值显式掩码回 32 位。具体来说,在每次可以想象将值增加到超过 32 位的操作之后,您都需要它们,对于此代码,这看起来就像所有的左移;我根本看不到任何加法或乘法,因此您需要修复的只是左移。


推荐阅读