5 votes

Quelle peut être la taille de l'argument du rand de Perl ?

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 ?

8voto

onteria_ Points 18947

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.

2voto

Michael Carman Points 21983

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.

0voto

yannis Points 55

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").

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X