使用Google.Math.Long将JS转换为C#

时间:2016-02-08 12:08:32

标签: javascript c#

我正在将一些Javascript代码转换为C#,并且对Google数学longs以及函数如何有点麻烦。这实际上是Delphi随机函数的一个版本 - 根据我的合作开发。

在javascript中我有这个。

function _nextRandom(maxValue, seedValue) {
    if (seedValue !== null) 
        _seed = new goog.math.Long(seedValue);

    _seed = _seed.multiply(134775813).add(_one);
    _seed = new goog.math.Long(_seed.getLowBitsUnsigned());
    return _seed.multiply(new goog.math.Long(maxValue)).getHighBits() >>> 0;
}

在C#中我有这个 - 到目前为止。

private int _nextRandom(int maxValue, int seedValue)
{
    if (seedValue != 0)
        _seed = seedValue;

    _seed = _seed * 134775813 + 1;
    _seed = (long)((int)_seed); // get lower 32 bits
    return (int)(((ulong)_seed * (ulong)maxValue) >> 32); // get upper 32 bits
}

最大值始终为254且第一次运行_nextRandom每次运行时,seedValue为1024,之后为0(在C#中)或null(在JS中)

此处C#的输出仅对正值正确,负值不正确

将值转换为byte会使值几乎匹配但不完全匹配。

有没有人知道为什么会这样?

1 个答案:

答案 0 :(得分:1)

有几个问题:

  • 您已将_seed声明为64位long。它应该是32位int
  • 在执行64位乘法之前,您需要将_seedmaxValue强制转换为uint

以下C#代码复制了Delphi PRNG:

private static int _seed = 0;

private static int _nextRandom(int maxValue, int seedValue)
{
    if (seedValue != 0)
        _seed = seedValue;
    _seed = _seed * 0x08088405 + 1;
    return (int)(((ulong)(uint)_seed * (uint)maxValue) >> 32);
}

显然这段代码不是线程安全的,但我相信你已经知道了。更清晰的实现是将它包装在一个类中,以便您可以使用自己的种子创建PRNG的不同实例。