views:

754

answers:

3

I'm translating some Delphi code into c# code when I ran into this. I don't have an environment setup for Delphi so I can't test it myself.

Delphi:

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

c#:

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

Would these put the same value in Result? If not, any ideas on a way to do so?

+7  A: 

Certainly not, because they use different RNGs. You could perhaps use a RNG from the Windows API, create your own RNG or use some RNG library to achieve this.

Another way to make sure your RNG creates the same numbers for a given seed would be to write a DLL and use it for both Delphi and C#.

By the way, if you want to code a RNG yourself, Wikipedia is a good starting point to get the names of some usual generators. After you're done, you should run it through some statistical test to make sure it's "random" enough for you.

schnaader
+3  A: 

Just some results using Delphi 2009 and the first 10 of each seed:

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

I see a pattern ;-).

Gamecat
Is this from the C# or Delphi RNG?
schnaader
Delphi, he has no delphi environment. But I corrected it. Thanks.
Gamecat
Yes, Delphi 5 indeed gives the same. Tested it here, too. Guess that's why you should throw away the first random values for most RNGs.
schnaader
Yup, or use a variable for the seed. For example (part of) the system time.
Gamecat
+6  A: 

The Delphi PRNG is a deterministic linear congruential generator with 134775813 as a and 1 as c, and returning the high 32 bits for range-limited numbers. Here's an implementation in C# that returns the same values as 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)
    {
        long result = (uint) GetNext() * 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));
    }
}
Barry Kelly