2011-11-11 2 views
2

Je tente de convertir une fonction pseudo rand de C++ en C# mais cela ne semble pas retourner les valeurs correctes. Il est important que j'utilise un ensemble cohérent pour le cryptage, donc je ne peux pas utiliser un nombre aléatoire.Pseudo aléatoire incohérent entre C++ et C#

c'est la fonction en C++.

int get_pseudo_rand() 
{ 
    return(((_last_rand = _last_rand * 214013L 
    + 2531011L) >> 16) & 0x7fff); 
} 

et ceci est mon C# autre

int get_pseudo_rand() 
{ 
    return (((_last_rand = (_last_rand * 214013 + 2531011) >> 16) & 0x7fff)); 
} 

j'ai enlevé les Ls depuis C# de type de données int est de 4 octets comme C++ désire ardemment alors que c les positions longues N ° sont 8 octets.

la première fois que la fonction est exécutée à partir de la graine, la réponse est cohérente avec la version C++, mais commence alors à diverger.

Des idées?

+2

Le code C++ manque une parenthèse quelque part. Aussi, pouvez-vous préciser quel type '_last_rand' est dans chaque langue. (Et pour C++, la taille de ce type sur votre paltform.) Aussi, si possible, la graine que vous utilisez et les deux premiers nombres aléatoires sur chaque plate-forme. –

+0

Certainement, La graine est 1274653591 et son correctement réglé les deux fois. Dans le code C++, les deux premières réponses sont 28818 et 20295. Elles sont correctes. En C#, les deux premiers résultats sont 28818 et 28610. _last_rand est un int (4 octets) dans les deux langues. J'utilise un programme 32 bits donc la taille des entiers et des longs dans C++ devrait être de 4 octets. (La parenthèse manquante est sans conséquence pour le calcul) – Steve

+2

Vous savez, si vous utilisez des variables temporaires, cela rendrait votre intention plus claire, et rendrait cela moins sujet aux erreurs que vous avez trouvées ici. Aussi, un bon compilateur (gigue) * devrait * l'optimiser de toute façon. –

Répondre

9

Vous avez mis entre parenthèses les deux instructions d'une manière différente qui en change la signification. Le code C++ met à jour _last_rand, puis fait un décalage à droite du résultat, le code C# effectue le décalage vers la droite avant la mise à jour _last_rand. J'ai aligné les déclarations ci-dessous pour faire la différence plus évidente.

C++:

return (((_last_rand = _last_rand * 214013L + 2531011L) >> 16) & 0x7fff); 

C#:

return (((_last_rand = (_last_rand * 214013 + 2531011) >> 16) & 0x7fff)); 
+0

+1 Confirmé. Avec le décalage avant le magasin, j'obtiens une série de réponses. Avec le décalage après le magasin, je reçois l'autre. Cela explique la différence. –

+0

Oui, cela semble fonctionner. Merci – Steve

+1

@Steve: Je tiens à souligner que je pense que le code 'C++' est plus correct. Si vous mettez à droite avant __ la mise à jour de votre variable, les bits "aléatoires" sont tronqués à chaque itération. – Blastfurnace

0

Le problème est que vous avez parenthésée differentyl ce qui conduit à stocker des valeurs différentes dans _last_rand ... avec votre code _last_rand magasins 28818 après la première run ... avec le code C++ il stocke 1888663550 qui est la valeur BEFORE >> et avant &. Ainsi, il startes divergeant de la deuxième course sur ...

Pour obtenir le même comportement que dans C++ utiliser en C#

return (((_last_rand = _last_rand * 214013 + 2531011) >> 16) & 0x7fff);