rand(n)
renvoie un nombre entre 0
y n
. Will rand
fonctionne comme prévu, en ce qui concerne le "caractère aléatoire", pour tous les arguments jusqu'à la limite des nombres entiers sur ma plate-forme ?
Réponses
Trop de publicités?Cela va dépendre de votre randbits
valeur :
rand appelle le générateur de nombres aléatoires de votre système (ou celui qui a été désigné par compilé dans votre copie de Perl). Pour cette discussion, j'appellerai ce générateur générateur RAND pour le distinguer de rand, la fonction de Perl. RAND produit un entier de 0 à 2**randbits - 1, inclus, où randbits est un petit entier. entier. Pour voir ce que c'est dans votre perl, utilisez la commande 'perl -V:randbits'. Les valeurs courantes sont 15, 16 ou 31.
Lorsque vous appelez rand avec un argument arg, perl prend cette valeur en tant que entier et calcule cette valeur.
arg * RAND rand(arg) = --------------- 2**randbits
Cette valeur se situera toujours dans la fourchette requise.
0 <= rand(arg) < arg
Mais lorsque arg devient grand par rapport à 2**randbits, les choses deviennent problématique. Imaginons une machine où randbits = 15, donc RAND varie de 0..32767. C'est-à-dire que chaque fois que nous appelons RAND, nous obtenons une des 32768 valeurs possibles. Par conséquent, lorsque nous appelons rand(arg), nous obtenons une des 32768 valeurs possibles.
Cela dépend du nombre de bits utilisés par le générateur de nombres (pseudo)aléatoires de votre système. Vous pouvez trouver cette valeur via
perl -V:randbits
ou à l'intérieur d'un programme via
use Config;
my $randbits = $Config{randbits};
rand
peut générer des nombres aléatoires distincts de 2^randbits. Bien que vous puissiez générer des nombres plus grands que 2^randbits, vous ne pouvez pas générer toutes les valeurs entières de l'intervalle [0, N] lorsque N > 2^randbits.
Les valeurs de N qui ne sont pas une puissance de deux peuvent également poser problème, car la distribution des valeurs aléatoires (tronquées en entier) ne sera pas tout à fait plate. Certaines valeurs seront légèrement surreprésentées, d'autres légèrement sous-représentées.
Il est intéressant de noter que randbits est un maigre 15 sous Windows. Cela signifie que vous ne pouvez obtenir que 32768 (2**15) valeurs distinctes. Vous pouvez améliorer la situation en faisant plusieurs appels à rand
et en combinant les valeurs :
use Config;
use constant RANDBITS => $Config{randbits};
use constant RAND_MAX => 2**RANDBITS;
sub double_rand {
my $max = shift || 1;
my $iv =
int rand(RAND_MAX) << RANDBITS
| int rand(RAND_MAX);
return $max * ($iv / 2**(2*RANDBITS));
}
En supposant que les randbits = 15, double_rand
imite randbits = 30, fournissant 1073741824 (2**30) valeurs distinctes possibles. Cela atténue (mais ne peut jamais éliminer) les deux problèmes mentionnés ci-dessus.
Nous parlons de grands entiers aléatoires et de la possibilité de les obtenir. Il convient de noter que la concaténation de deux entiers aléatoires est également un entier aléatoire. Donc si votre système, pour une raison quelconque, ne peut pas aller au-delà de 999999999999, il suffit d'écrire
$bigrand = int(rand(999999999999)).int(rand(999999999999));
et vous obtiendrez un entier aléatoire de (au maximum) deux fois la longueur.
(En fait, il ne s'agit pas d'une réponse numérique à la question "quelle taille peut avoir un nombre aléatoire" mais plutôt de la réponse "vous pouvez obtenir la taille que vous voulez, il suffit de concaténer des petits nombres").