C#/ Java数字随机化

时间:2010-01-27 14:21:20

标签: c# java random

是否可以从.NET模仿Java使用的确切随机化?我有一个种子,我希望能够在创建随机数时在C#和Java中收到相同的结果。

6 个答案:

答案 0 :(得分:6)

您无需阅读源代码。公式是单线程,在documentation for java.util.Random.

中给出

以下是部分翻译:

[Serializable]
public class Random
{
    public Random(UInt64 seed)
    {
        this.seed = (seed ^ 0x5DEECE66DUL) & ((1UL << 48) - 1);
    }

    public int NextInt(int n)
    {
        if (n <= 0) throw new ArgumentException("n must be positive");

        if ((n & -n) == n)  // i.e., n is a power of 2
            return (int)((n * (long)Next(31)) >> 31);

        long bits, val;
        do
        {
            bits = Next(31);
            val = bits % (UInt32) n;
        }
        while (bits - val + (n - 1) < 0);

        return (int) val;
    }

    protected UInt32 Next(int bits)
    {
        seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);

        return (UInt32)(seed >> (48 - bits));
    }

    private UInt64 seed;
}

示例:

Random rnd = new Random(42);
Console.WriteLine(rnd.NextInt(10));
Console.WriteLine(rnd.NextInt(20));
Console.WriteLine(rnd.NextInt(30));
Console.WriteLine(rnd.NextInt(40));
Console.WriteLine(rnd.NextInt(50));

两个平台上的输出均为0, 3, 18, 4, 20

答案 1 :(得分:5)

如果您的Java实现具有java.util.Random类的源代码,则可以轻松地将其移植到.NET。

如果您需要两个应用程序(Java和.NET)使用某个随机数生成器,您最好在两个平台中实现一个并使用它,因为系统提供的版本可能会将其行为更改为更新的结果。(看起来Java规范准确地描述了其PRNG的行为。)

答案 2 :(得分:1)

如果您不需要加密安全的伪随机数生成器,那么我会选择Mersenne twister。您可以找到C# hereJava here的源代码。

答案 3 :(得分:0)

好吧,你可以查看Random.java的源代码并复制算法,常量等等,但Random在其构造函数中使用System.nanoTime,这样你就不会得到相同的结果。

来自java.util.Random

  

public Random(){   这个(++ seedUniquifier +   System.nanoTime()); }

如果C#中的源代码会显示类似内容,我一点都不会感到惊讶。

编辑:忽略,正如已经指出的那样,接受输入种子的构造函数永远不会访问时间。

答案 4 :(得分:0)

实现自己的简单伪随机数生成器可能有意义吗?通过这种方式,您可以完全控制并且可以获得相同的种子,从而在两种环境中都能获得相同的结果。可能比将一个移植到另一个更多的工作。

答案 5 :(得分:-2)

另一种选择可能是将随机数从一个平台写入文件,然后只从该文件加载两个平台的随机数,或者您可以从random.org等服务加载它们