C # / Java рандомизация чисел - PullRequest
9 голосов
/ 27 января 2010

Можно ли из .NET имитировать точную рандомизацию, которую использует Java? У меня есть начальное число, и я хотел бы иметь возможность получать одинаковые результаты как в C #, так и в Java при создании случайного числа.

Ответы [ 6 ]

6 голосов
/ 27 января 2010

Вам не нужно читать исходный код. Формула однострочная и приведена в документации для 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.

5 голосов
/ 27 января 2010

Если у вас есть исходный код класса java.util.Random для вашей реализации Java, вы можете легко перенести его на .NET.

Если вам требуется, чтобы оба приложения (Java и .NET) использовали определенный генератор случайных чисел, вам лучше реализовать его на обеих платформах и использовать его вместо этого, поскольку предоставленная системой версия может изменить свое поведение результат обновления. (похоже, спецификация Java точно описывает поведение своего PRNG.)

1 голос
/ 27 января 2010

Если вам не нужен криптографически безопасный генератор псевдослучайных чисел, я бы выбрал Mersenne twister . Вы можете найти исходный код для C # здесь и Java здесь .

0 голосов
/ 27 января 2010

Другой вариант может состоять в том, чтобы записать ваши случайные числа в файл один раз с одной платформы, а затем просто загрузить ваши случайные числа для обеих платформ из этого файла, или вы можете загрузить их из службы, например random.org

0 голосов
/ 27 января 2010

Может быть, имеет смысл реализовать собственный генератор псевдослучайных чисел? Таким образом, вы получаете полный контроль и можете гарантировать, что одно и то же семя дает одинаковые результаты в обеих средах. Возможно, немного больше работы, чем портирование одного на другое.

0 голосов
/ 27 января 2010

Хорошо, вы можете посмотреть в исходном коде файл Random.java и скопировать алгоритм, константы и т. Д., Но Random использует System.nanoTime в своем конструкторе, поэтому вы не получите те же результаты.

От java.util.Random

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

Я бы совсем не удивился, если бы источник в C # показал вам нечто подобное.

Редактировать: игнорировать, как уже указывалось, конструктор, который принимает входное начальное число, никогда не обращается ко времени.

...