【问题标题】:Is the Random Generator from Delphi the same calculation as C# if fed the same seed?如果输入相同的种子,Delphi 的随机生成器是否与 C# 的计算相同?
【发布时间】:2009-02-11 16:59:41
【问题描述】:

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

德尔福:

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

c#:

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

这些会将相同的值放入 Result 中吗?如果没有,有什么想法吗?

【问题讨论】:

    标签: c# delphi random


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        【解决方案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
        

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

        【讨论】:

        • 这是来自 C# 还是 Delphi RNG?
        • Delphi,他没有delphi环境。但我纠正了它。谢谢。
        • 是的,Delphi 5 确实提供了相同的功能。也在这里测试过。猜猜这就是为什么你应该丢弃大多数 RNG 的第一个随机值。
        • 是的,或者为种子使用变量。例如(部分)系统时间。
        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-08-17
          • 1970-01-01
          • 2013-04-05
          • 1970-01-01
          • 1970-01-01
          • 2020-04-24
          • 2015-11-23
          • 1970-01-01
          相关资源
          最近更新 更多