Générer de l'aléatoire uint
J'ai besoin de générer des nombres aléatoires avec la gamme de byte
, ushort
, sbyte
, short
, int
, et uint
. Je suis en mesure de générer pour tous ces types à l'aide de la méthode Aléatoire en C# (par exemple values.Add((int)(random.Next(int.MinValue + 3, int.MaxValue - 2)));
), sauf pour les uint depuis Random.Next
accepte jusqu'à int valeurs seulement.
Est-il un moyen facile de générer de l'aléatoire uint
?
- Pourquoi ne pas simplement utiliser NextBytes() pour obtenir 4 octets, et de le jeter?
- Certes possible, mais environ deux fois plus lent(génère des 4 nombres aléatoires, un pour chaque octet) par rapport à la combinaison de deux valeurs à l'aide des quarts de travail.
Vous devez vous connecter pour publier un commentaire.
L'approche la plus simple serait probablement de l'utilisation de deux appels: l'un pour les de 30 bits et l'autre pour les deux derniers. Une version antérieure de cette réponse suppose que
Random.Next()
avait un inclusive limite supérieure deint.MaxValue
, mais il s'avère qu'elle est exclusive de sorte que nous pouvons obtenir que 30 uniforme bits.(Vous pourriez prendre deux valeurs de 16 bits, bien sûr, comme une alternative... ou différentes options dans l'entre-deux.)
Sinon, vous pouvez utiliser
NextBytes
pour remplir un 4-tableau d'octets, puis utilisezBitConverter.ToUInt32
.José de la Lumière du jour Dés
Je l'avoue, ce n'est pas la qualification opérationnelle. Il deviendra clair qu'il y a des manières plus rapides pour générer des nombres uint compris qui ne sont pas vraies. Néanmoins je suppose que personne n'est trop intéressé à générer ces, sauf en cas de non-distribution à plat est nécessaire pour une raison quelconque. Nous allons commencer avec quelques recherche à obtenir, il est facile et rapide en C#. Facile et rapide, se comportent souvent comme des synonymes quand j'écris du code.
Premier: Quelques propriétés importantes
Voir MSDN.
Random
constructeurs:Random()
: Initialise une nouvelle instance de laRandom
classe, à l'aide d'un temps dépendant de la valeur par défaut valeur de départ.Random(int seed)
: Initialise une nouvelle instance de laRandom
classe, à l'aide des graines de valeur.Pour améliorer les performances, créer un
Random
objet pour générer les nombres aléatoires dans le temps, au lieu, à plusieurs reprises, la création de nouveauxRandom
objets pour générer un nombre aléatoire, de sorte que:Random
méthodes:rand.Next()
: Renvoie un nombre aléatoire positive, supérieure ou égale à zéro, à moins deint.MaxValue
.rand.Next(int max)
: Renvoie un nombre aléatoire positive, supérieure ou égale à zéro, à moins de max, max doit être supérieure ou égale à zéro.rand.Next(int min, int max)
: Renvoie un nombre aléatoire positive, supérieure ou égale à min, à moins de max, max doit être supérieure ou égale à min.Devoirs montre que
rand.Next()
est deux fois plus rapide querand.Next(int max)
.Deuxième: Une solution.
Supposons que positif de l'int a seulement deux bits, oubliez le bit de signe, c'est nul,
rand.Next()
renvoie les trois valeurs différentes avec la même probabilité:Pour un true random number le bit de poids faible est de zéro, comme souvent, car c'est un, même chose pour le bit le plus élevé.
Pour le faire fonctionner pour le bit de poids faible utilisation:
rand.Next(2)
Supposons qu'un int a trois bits,
rand.Next()
retourne sept des valeurs différentes:Pour le faire fonctionner pour le moins deux bits d'utilisation:
rand.Next(4)
Supposons qu'un int a n bits.
Pour le faire fonctionner pour n bits utilisation:
rand.Next(1 << n)
Pour le faire fonctionner pour un maximum de 30 bits utilisation:
rand.Next(1 << 30)
C'est le maximum, 1 << 31 est plus grande que
int.MaxValue
.Qui conduit à un moyen de générer un vrai uint aléatoire:
1 << 2 = 4 = 22, 1 << 30 = 230
La chance de zéro est: 1/22 * 1/230 = 1/232
Le nombre total de nombres uint compris, y compris zéro: 232
Il est aussi clair que la lumière du jour, pas d'alerte au smog, n'est-ce pas?
Enfin: Une fausse idée.
Est-il possible de le faire plus rapidement en utilisant
rand.Next()
Quand
rand.Next()
est utilisé deux fois et les résultats sont ajoutés, la plus grande valeur possible est:La différence avec uint.MaxValue est:
Pour atteindre
uint.MaxValue
, une autre valeur,rand.Next(4)
doit être ajouté, ainsi, nous obtenons:rand.Next() + rand.Next() + rand.Suivant(4)
Environ: 1/231 * 1/231 * 1/4 = 1/264, il devrait être 1/232
Attendez une seconde, ce sujet de:
Environ: 1/231 * 1/4 = 1/233, trop petit pour être vraiment au hasard.
Un autre exemple facile:
rand.Next(2) + rand.Next(2)
, tous les résultats possibles:L'égalité des probabilités? No way José.
Ensemble de la Gamme, " uint u0 <= la valeur de retour <= uint u1 ", en utilisant le Système.Aléatoire
Il est plus facile de commencer avec une gamme de "zéro" (inclus) de "u" (inclus).
Vous pouvez prendre un coup d'oeil à mes autres
réponse.
Si vous êtes intéressé par un plus rapide/plus efficace:
Uniforme pseudo-aléatoire de nombres dans une plage. (Il est tout à fait beaucoup de code/texte).
Ci-dessous "rnd32(uint u)" retourne: 0 <= valeur <= u .
Le cas le plus difficile est: "u = int.MaxValue". Puis la chance que la première itération de la boucle"
(une seule itération à la fois l'extérieur et l'intérieur "boucle"), retourne une valeur valide est de 50%.
Après deux itérations, la chance est de 75%, etc.
La chance est de petite taille que l'extérieur de "faire" en boucle itère plus d'une fois.
Dans le cas de "u = int.MaxValue": 0%.
Il est évident que: "rnd32(uint u0, uint u1)" renvoie une valeur comprise entre u0 (y) et u1 (incl).