Comment obtenir un plus grand nombre aléatoire à partir de la fonction c rand ()

Je suis dans un environnement de codage où je n’ai access qu’à certaines fonctions c les plus élémentaires. # inclure d’autres lib n’est pas faisable.

Dans cet environnement, je peux appeler rand (), ce qui me donne un nombre aléatoire compris entre 0 et 32767 inclus (je pense) dans mon environnement. Le code suivant est-il la bonne logique pour obtenir un nombre aléatoire plus grand et uniformément dissortingbué comme / en tant que rand ()?

rnum = rand() * (32767 + 1) + rand();

rnum = (rand() << 15) | rand() rnum = (rand() << 15) | rand() peut-être plus rapide, mais si vous avez besoin de nombres aléatoires de bonne qualité, vous devriez rechercher une bibliothèque externe. Les fonctions aléatoires intégrées ne conviennent généralement que pour les applications les plus simples.

 static unsigned long next = 1; int my_rand(void) { next = next * 1103515245 + 12345; return((unsigned)(next/65536) % (RAND_MAX+1)); } void my_srand(unsigned int seed) { next = seed; } 

sur linux

 #define RAND_MAX 2147483647 

votre environnement RAND_MAX est probablement 32767

référence: http://en.wikipedia.org/wiki/Linear_congruential_generator

Si vous n’êtes pas limité en mémoire, vous pouvez également consulter http://en.wikipedia.org/wiki/Mersenne_twister le code est intégrable comme dans l’exemple ci-dessus.

Avant d’utiliser TOUT générateur de nombres aléatoires pour une utilisation non sortingviale, il convient de le tester de manière approfondie. Voici un lien vers un article sur ce sujet.

Un récit amusant sur les faiblesses des nombres aléatoires, même vrais, est disponible dans les divers historiques des codes-briseurs de Bletchley Park pendant la Seconde Guerre mondiale. Les Allemands et Hitler pendant presque toute la guerre présumèrent que leurs codes étaient incassables en raison de leur chiffrement avec des nombres aléatoires, alors que les Britanniques les supprimaient complètement en quelques mois à cause de diverses faiblesses dans la mise en œuvre du “caractère aléatoire” par l’Allemagne. De nombreux codes étaient suffisamment “tordus”, voire carrément brisés, en quelques jours ou quelques mois, suffisamment pour être utilisés même s’ils n’étaient pas complètement brisés.

Outre les autres excellentes solutions proposées ici, vous pouvez également augmenter la puissance dans RAND_MAX, tronquer une position définie par l’utilisateur, MY_RAND_MAX, et éliminer les solutions qui entraîneraient la destruction de l’uniformité.

 int myrand(int MY_RAND_MAX) { int j = 0, num = 0; // Generate digits for expansion in powers of RAND_MAX, up to acceptable range. while (pow(RAND_MAX + 1, j) <= MY_RAND_MAX){ num = num + rand() * (int)pow(RAND_MAX + 1, j); j++; } //compute remainder to determine truncation int remainder = ((int)pow(RAND_MAX + 1, j)) % (MY_RAND_MAX + 1); // If number is within accepted bounds, mod and return if (num <= ( (int)pow(RAND_MAX + 1, j) - remainder ) ){ return (num % (MY_RAND_MAX + 1)); // Else, if number generated exceeds allowed bounds, rerun method. }else if (num > ( (int)pow(RAND_MAX + 1, j) - remainder ) ){ return myrand(MY_RAND_MAX); }else{ exit(-1); } } 

Vous pouvez vérifier empiriquement que cette méthode vous donne une sortie statistiquement uniforme dans la plage donnée.

Je l’ai fait pour plusieurs essais avec différentes gammes, chacune avec une taille d’échantillon de 100 000, et j’ai obtenu un accord entre la variance de l’échantillon et la variance attendue à au moins 3 sig. fig.s à chaque fois.

ps Je ne suis pas un codeur, mais un mathématicien / physicien qui a récemment appris à coder. Tous les commentaires sur la qualité de mon code seraient donc appréciés.