斐波那契随机数生成器返回负数

3
我尝试使用以下公式实现减法滞后斐波那契随机数生成器: = ([−] − [−])
但有时它会生成负数。在搜索了几天互联网后,我找不到任何答案或我的代码中的错误。你们谁能帮我理解我做错了什么?
class LaggedFibonaci_RNG : IRandomNUmberGenerator
{
    private double[] initArray = null;
    private int j = 1029;
    private int k = 2281;
    private int n = 0;
    private double m = Math.Pow(2, 32);
    private double Xn = DateTime.Now.Millisecond;
    Random rand = new Random();

    public LaggedFibonaci_RNG()
    {
        n = k;
        initArray = new double[n];
        // create initial array 
        for (int i = 0; i < initArray.Length; i++)
        {
            initArray[i] = rand.Next();
        }
    }


    public double GenerateNextRandomNumber()
    {
        double randomNumber = 0;
        //decrement j or set to optimal
        if (j <= 1)
        {
            j = 1029;
        }
        else
        {
            j--;
        }
        // decrement k or set to optimal
        if (k <= 1)
        {
            k = 2281;
        }
        else
        {
            k--;
        }

        ////  apply the fibonacci formula
        //randomNumber = (Xn * (n - j) - Xn * (n - k)) % m;

        //// update the initial array at position n - k to hold the random number generated
        //initArray[n - k] = randomNumber;
        //Xn = randomNumber;

        double firstElement = initArray[n - j];
        double secondElement = initArray[n - k];

        randomNumber = (firstElement - secondElement) % m;
        initArray[n - k] = randomNumber;

        //return the generated number
        return randomNumber;
    }
}

1
负数出现在这里是有道理的,因为并没有说X[n-f]始终大于X[n-k]。我认为你需要使用mod而不是rem,所以应该是(((X[n-f] - X[n-k])%m)+m)%m - Willem Van Onsem
为什么在构造函数中n被重新赋值,还要将其初始化为0 - Rufus L
@WillemVanOnsem 对不起,我不明白你的意思,为什么在函数Xn=(X(n-j)-X(n-k) ) mod m中要使用%m)+m)%m? - Claudio Corchez
@ClaudioCorchez:嗯,modrem很容易混淆。mod通常采用除数的符号,而不是被除数的符号。C#中的%是一个余数操作,而不是模运算。 - Willem Van Onsem
@ClaudioCorchez 如果 X[n-f] - X[n-k] 是正数,那么 ((X[n-f] - X[n-k]) % m + m) % m 将返回与您的代码相同的结果。但如果是负数,则会返回 m 加上负数的结果。举个例子:((5 - 6) % 7 + 7) % 7 = 6((6 - 5) % 7 + 7) % 7 = 1 - Rufus L
显示剩余6条评论
1个回答

7
这篇维基百科文章关于模运算表明,对于模和余数的定义并没有完全一致。通常情况下,运算会采用除数的符号,而余数则常常取被除数的值。例如,参见这个数学答案:

要找到-b mod N,只需要不断加上N直到数字位于0N之间即可。

因此,-5 mod 31,而-5 rem 3-2

在这个定义的基础上,C#的% 运算符 [语言参考]是一个余数运算符,而不是一个运算符。

假设m为一个正数,我们可以利用余数来计算模运算。对于一个正的m

a mod m = ((a rem m)+m) rem m

因此我们可以将它应用在本公式中,写成:

randomNumber = (((firstElement - secondElement) % m) + m) % m;

1
非常感谢您清晰的解释。这解决了我的问题。 - Claudio Corchez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接