我正在将一些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会使值几乎匹配但不完全匹配。
有没有人知道为什么会这样?
答案 0 :(得分:1)
有几个问题:
_seed
声明为64位long
。它应该是32位int
。_seed
和maxValue
强制转换为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的不同实例。