Delphi的随机生成器与C#的计算方法是否相同?

时间:2009-02-11 16:59:42

标签: c# delphi random

当我遇到这个时,我正在将一些Delphi代码翻译成c#代码。我没有Delphi的环境设置,所以我不能自己测试它。

的Delphi:

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

C#:

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

这些会在Result中输入相同的值吗?如果没有,有任何想法可以这样做吗?

4 个答案:

答案 0 :(得分:17)

Delphi PRNG是确定性的linear congruential generator,其中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));
    }
}

答案 1 :(得分:7)

当然不是,因为他们使用不同的RNG。您也许可以使用Windows API中的RNG,创建自己的RNG或使用一些RNG库来实现此目的。

确保RNG为给定种子创建相同数字的另一种方法是编写DLL并将其用于Delphi和C#。

顺便说一句,如果你想自己编写一个RNG代码,Wikipedia是一个很好的起点,可以获得一些常用生成器的名称。完成后,您应该通过一些statistical test来运行它,以确保它对您来说足够“随机”。

答案 2 :(得分:3)

使用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

我看到了一种模式; - )。

答案 3 :(得分:1)

对于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));
        }
    }
}