2009-02-11 4 views
8

Je suis en train de traduire du code Delphi en code C# quand je suis tombé dessus. Je n'ai pas de configuration d'environnement pour Delphi, donc je ne peux pas le tester moi-même.Le générateur aléatoire de Delphi a-t-il le même calcul que C# s'il est alimenté par la même graine?

Delphi:

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

C#:

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

Est-ce que ceux-ci portent la même valeur dans Résultat? Si non, des idées sur un moyen de le faire?

Répondre

16

Le Delphi PRNG est un linear congruential generator déterministe avec 134.775.813 comme a et 1 c, et le retour des 32 bits de poids fort pour les numéros de portée limitée. Voici une implémentation en C# qui retourne les mêmes valeurs que 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

Certainement pas, car ils utilisent différents RNG. Vous pourriez peut-être utiliser un RNG de l'API Windows, créer votre propre RNG ou utiliser une bibliothèque RNG pour y parvenir. Une autre façon de s'assurer que votre RNG crée les mêmes nombres pour une graine donnée serait d'écrire une DLL et de l'utiliser pour Delphi et C#. À propos, si vous voulez vous-même coder un RNG, Wikipedia est un bon point de départ pour obtenir les noms de certains générateurs habituels. Une fois que vous avez terminé, vous devriez le faire passer à travers statistical test pour vous assurer qu'il est assez "aléatoire" pour vous.

3

Juste quelques résultats en utilisant Delphi 2009 et les 10 premiers de chaque graine:

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 

Je vois un modèle ;-).

+0

Est-ce du C# ou Delphi RNG? – schnaader

+0

Delphi, il n'a pas d'environnement Delphi. Mais je l'ai corrigé. Merci. –

+0

Oui, Delphi 5 donne en effet la même chose. Testé ici aussi. Supposons que vous devriez jeter les premières valeurs aléatoires pour la plupart des RNG. – schnaader

1

Pour les développeurs 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)); 
     } 
    } 
} 
Questions connexes