微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将定制的随机生成器从 JS 移植到 Python 3

如何解决将定制的随机生成器从 JS 移植到 Python 3

伙计们。

我发现 here一个非常基本的具有播种功能随机生成器。 还附上了代码片段。

var m_w = 123456789;
var m_z = 987654321;
var mask = 0xffffffff;

// Takes any integer
function seed(i) {
    m_w = (123456789 + i) & mask;
    m_z = (987654321 - i) & mask;
}

// Returns number between 0 (inclusive) and 1.0 (exclusive),// just like Math.random().
function random()
{


    m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask;
    m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask;

    var result = ((m_z << 16) + (m_w & 65535)) >>> 0;
    result /= 4294967296;
    return result;
}

seed(1);

console.log(random())
console.log(random())
console.log(random())
console.log(random())
console.log(random())

我正在尝试将其移植到 Python 3 并意识到位运算存在差异,因为 JS 和 Python 对长整数的行为不同。

到目前为止的 Python 代码是:

#!/usr/bin/python
import ctypes

m_w = 123456789
m_z = 987654321
mask = 0xFFFFFF

#JS returns 123456790,987654320
def bespokeSeed(seed_):

    global m_w,m_z,mask

    m_w = m_w + seed_
    m_z = m_z - seed_

def bespokeRandom():

    global m_w,mask

    #JS returns 990784270,945037883
    m_z = (36969 * (m_z & 65535 & (2**53-1)) + (m_z >> 16) & (2**53-1))
    m_w = (18000 * (m_w & 65535 & (2**53-1)) + (m_w >> 16) & (2**53-1))
    #JS returns 722346555
    result = ((ctypes.c_int(m_z << 16 ^ 0).value + ctypes.c_int(m_w & 65535 ^ 0).value) >> 0) / 4294967296
    return result

bespokeSeed(1)
print(bespokeRandom())
print(bespokeRandom())
print(bespokeRandom())
print(bespokeRandom())
print(bespokeRandom())

JS 代码(如果调用 random() 5 次)返回

0.16818441334180534
0.7648323038592935
0.1521853597369045
0.22241602488793433
0.4391189150046557

虽然Python得到

0.16818441334180534
-0.23516769614070654
0.1521853597369045
0.22241602488793433
0.4391189150046557

如您所见,它部分有效,但在返回负数时存在一些问题。 关于如何修复它的任何想法?

解决方法

我不明白为什么你在那里有 ctypes。问题是 Javascript 整数限制为 32 位,而 Python 具有无限精度。这可以满足您的要求:

import ctypes

m_w = 123456789
m_z = 987654321
mask = 0xFFFFFFFF

def bespokeSeed(seed_):

    global m_w,m_z

    m_w = m_w + seed_
    m_z = m_z - seed_

def bespokeRandom():

    global m_w,m_z

    #JS returns 990784270,945037883
    m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask
    m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask 
    result = ((m_z << 16 & mask) + (m_w & 65535)) / 4294967296
    return result

bespokeSeed(1)
print(bespokeRandom())
print(bespokeRandom())
print(bespokeRandom())
print(bespokeRandom())
print(bespokeRandom())

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。