C#`Int32`如何正确限制范围?

时间:2017-03-23 08:38:57

标签: c# .net

我正在研究用于单元测试的优化XorShift32伪随机数生成器。它比System.Random快得多,unsafe优化速度更快。另外,我添加了服务器方便的方法,使我的单元测试更容易。但是,由于在使用接近Int32.MinValueInt32.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)。这段代码将在此失败。如何在不超出性能的情况下使其正确无误?

顺便说一句,我知道制作这样的PRNG并没有实际的理由,我只是出于学习目的而这样做。

1 个答案:

答案 0 :(得分:2)

看看微软为Random.Next(min, max)

做了些什么
long range = (long)max-min;

他们使用long: - )

然后

return min + (int)(Seed / Max * range);