Является ли генератор случайных чисел из Delphi тем же расчетом, что и C #, если он питается тем же начальным числом? - PullRequest
8 голосов
/ 11 февраля 2009

Я перевожу некоторый код Delphi в код на c #, когда столкнулся с этим. У меня нет настройки среды для Delphi, поэтому я сам не могу ее протестировать.

Delphi:

RandSeed := var1;
Result := Random($FF);

C #:

Random RandSeed = new Random(var1);
Result = RandSeed.Next(255);

Приведут ли они одно и то же значение в Результат? Если нет, то есть идеи, как это сделать?

Ответы [ 4 ]

17 голосов
/ 12 февраля 2009

Delphi PRNG является детерминированным линейным конгруэнтным генератором с 134775813 как a и 1 как c, и возвращает старшие 32 бита для ограниченный диапазон номеров. Вот реализация в C #, которая возвращает те же значения, что и Delphi:

using System;

class DelphiRandom
{
    int _seed;

    public DelphiRandom(int seed)
    {
        _seed = seed;
    }

    int GetNext() // note: returns negative numbers too
    {
        _seed = _seed * 0x08088405 + 1;
        return _seed;
    }

    public int Next(int maxValue)
    {
        ulong result = (ulong) (uint) GetNext() * (ulong) (uint) maxValue;
        return (int) (result >> 32);
    }
}

class App
{
    static void Main()
    {
        DelphiRandom r = new DelphiRandom(42);
        for (int i = 0; i < 10; ++i)
            Console.WriteLine(r.Next(100));
    }
}
7 голосов
/ 11 февраля 2009

Конечно нет, потому что они используют разные ГСЧ. Возможно, вы могли бы использовать RNG из Windows API, создать свой собственный RNG или использовать некоторую библиотеку RNG для достижения этой цели.

Еще один способ убедиться, что ваш RNG создает одинаковые числа для заданного начального числа, - написать DLL и использовать ее как для Delphi, так и для C #.

Кстати, если вы хотите самостоятельно кодировать ГСЧ, Википедия является хорошей отправной точкой для получения имен некоторых обычных генераторов. После того, как вы закончите, вы должны выполнить его через статистический тест , чтобы убедиться, что он "случайный" достаточно для вас.

3 голосов
/ 11 февраля 2009

Только некоторые результаты с использованием Delphi 2009 и первых 10 каждого семени:

Seed:   0, result:   0,   8, 219,  51,  69, 171,  81,  41,  94, 108
Seed:   1, result:   8, 219,  51,  69, 171,  81,  41,  94, 108,  20
Seed:   2, result:  16, 176, 138,  87,  17, 246,   1, 148, 122, 188
Seed:   3, result:  24, 132, 225, 105, 119, 156, 216, 202, 135, 100
Seed:   4, result:  32,  89,  57, 123, 221,  66, 176,   0, 149,  13
Seed:   5, result:  40,  45, 145, 141,  67, 231, 136,  54, 163, 180
Seed:   6, result:  48,   2, 232, 159, 169, 141,  96, 108, 176,  92
Seed:   7, result:  56, 213,  64, 177,  16,  51,  56, 161, 190,   5
Seed:   8, result:  64, 170, 151, 195, 118, 216,  16, 215, 203, 172
Seed:   9, result:  72, 127, 238, 213, 219, 126, 231,  14, 217,  84
Seed:  10, result:  80,  83,  70, 231,  66,  36, 191,  67, 231, 252
Seed:  11, result:  88,  40, 157, 248, 168, 201, 151, 121, 244, 164
Seed:  12, result:  96, 251, 244,  11,  14, 111, 111, 175,   3,  76
Seed:  13, result: 104, 208,  76,  29, 116,  21,  71, 228,  17, 244
Seed:  14, result: 112, 164, 163,  47, 218, 186,  31,  27,  30, 156
Seed:  15, result: 120, 121, 250,  65,  64,  96, 246,  81,  44,  69
Seed:  16, result: 128,  78,  83,  83, 166,   6, 206, 134,  57, 236
Seed:  17, result: 136,  34, 170, 101,  13, 171, 166, 188,  71, 148
Seed:  18, result: 144, 246,   2, 119, 114,  81, 126, 242,  85,  61
Seed:  19, result: 152, 202,  89, 137, 216, 246,  86,  40,  98, 228
Seed:  20, result: 160, 159, 176, 155,  63, 156,  46,  94, 112, 140
Seed:  21, result: 168, 115,   8, 173, 164,  66,   6, 148, 126,  53
Seed:  22, result: 176,  72,  95, 191,  11, 231, 221, 201, 139, 220
Seed:  23, result: 184,  29, 182, 209, 113, 141, 181,   0, 153, 132
Seed:  24, result: 192, 240,  14, 227, 214,  51, 141,  54, 166,  45
Seed:  25, result: 200, 197, 101, 245,  61, 216, 101, 107, 180, 212

Я вижу образец; -).

1 голос
/ 18 августа 2011

Для разработчиков Java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.delphi;

/**
 *
 * @author ulmum
 * Using Code for C# from Barry Kelly http://stackoverflow.com/users/3712/barry-kelly
 */
class DelphiRandom {

    int _seed;

    public DelphiRandom(int seed) {
        _seed = seed;
    }

    int GetNext() // note: returns negative numbers too
    {
        _seed = _seed * 0x08088405 + 1;
        return _seed;
    }

    public int Next(int maxValue) {
        long result = (long) (int) GetNext() * (long) (int) maxValue;
        return ((int) (result >> 32) & 0xff); //Here Prevent Negative Numbers
    }
}

class App {

    public static void main(String[] args) {
        DelphiRandom r = new DelphiRandom(0);
        for (int i = 0; i < 10; ++i) {
            System.out.println(r.Next(256));
        }
    }
}
...