我正在研究用于单元测试的优化XorShift32
伪随机数生成器。它比System.Random快得多,unsafe
优化速度更快。另外,我添加了服务器方便的方法,使我的单元测试更容易。但是,由于在使用接近Int32.MinValue
和Int32.MaxValue
的范围时出现溢出,我的正确性存在问题。
这是方法(我知道它不正确):
/// <summary>
/// Returns a random integer that is within a specified range.
/// </summary>
/// <param name="min">The inclusive lower bound of the random number returned.</param>
/// <param name="max">The exclusive upper bound of the random number returned. maxValue must be greater than or equal to minValue.</param>
/// <returns>A 32-bit signed integer greater than or equal to minValue and less than maxValue; that is, the range of return values includes minValue but not maxValue. If minValue equals maxValue, minValue is returned.</returns>
public int Next(int min, int max) {
if (min == max) return min;
Seed ^= Seed << 13;
Seed ^= Seed >> 17;
Seed ^= Seed << 5;
if (min == int.MinValue && max == int.MaxValue) return unchecked((int)Seed);
return min + (int)(Seed / Max * (max - min));
}
当Math.Abs(max - min) < Int32.MaxValue
返回正确的数字时,否则数字会溢出。首先,上述条件似乎对人类有意义,但不一定对编译器或IL有意义。除Int32.MaxValue
之外的任何内容都小于Int32.MaxValue
,因此在代码中使用它是毫无意义的。然后我再次将最大值和最小值转换为Int64
,然后进行计算,但问题是它会在这里击败所有优化增益。
任何想法如何限制输出范围FAST?
让我们考虑一下测试用例:var x = R.Next(-1, Int32.MaxValue)
。这段代码将在此失败。如何在不超出性能的情况下使其正确无误?
答案 0 :(得分:2)
long range = (long)max-min;
他们使用long
: - )
然后
return min + (int)(Seed / Max * range);