2016-06-11 2 views
0

Mon problème est vraiment simple (idiot, peut-être). J'ai besoin d'un long nombre aléatoire en utilisant le langage C aussi simple que possible. J'ai fait des recherches sur internet et je n'ai rien trouvé qui puisse m'aider. La seule chose que j'ai pu trouver était que la fonction rand() ne peut pas gérer les nombres supérieurs à 32 767.Long nombres aléatoires dans C

Voici une partie de mon code, et le nombre long devrait se situer entre 0 et 1000000:

#include <stdio.h> 
#include <time.h> 
#include <conio.h> 

#define MAX 999999 

void main() 
{ 
    int i; 

    printf("\n Just a test with random numbers."); 

    printf("\n ------------------------------------\n\n"); 

    srand(time(NULL)); 

    for(i = 0; i < 50; i++) 
    { 
     printf(" %li\n", rand() % MAX+1); 
    } 

    printf("\n ====================================\n"); 
    getch(); 
} 

Répondre

-1

Une mauvaise solution mais travailler serait de multiplier le résultat de rand() avec MAX/RAND_MAX (I croire qu'il y avait une constante pour cela, sinon, 32767).

Je pense toujours qu'il devrait y avoir un rand pour les plus grands nombres là-bas cependant.

EDIT: Vous avez besoin de transcrire la division en float (ou en double), puis revenir en arrière.

3

Vous pouvez générer des nombres plus grands en effectuant plusieurs appels à rand().

#include <stdbool.h> 
#include <stdio.h> 
#include <stdint.h> 
#include <stdlib.h> 

#define LIMIT (1000000) 

static uint16_t highest_bit(uint64_t v) { 
    uint16_t out = 0; 
    while (v > 0) { 
     v >>= 1; 
     ++out; 
    } 
    return out; 
} 

uint32_t myrand() { 
    static bool init = 0; 
    static uint16_t n; 
    static uint16_t shift; 
    if (!init) { 
     uint16_t randbits = highest_bit(RAND_MAX + (uint64_t)1L); 
     uint16_t outbits = highest_bit(LIMIT); 
     n = (outbits + randbits - 1)/randbits; 
     shift = randbits; 
     init = 1; 
    } 
    uint32_t out = 0; 
    for (uint16_t i=0; i<n; ++i) { 
     out |= rand() << (i*shift); 
    } 
    return out % LIMIT; 
} 

Il convient de noter que cette méthode sera biaisée (à savoir tous les numéros ne seront pas la même probabilité), et il est certainement pas sécurisé cryptographiquement. Si vous le souhaitez, vous ne devriez pas utiliser rand().

Voici une petite fonction principale pour vérifier que tous les chiffres sont au moins possible pour obtenir:

int main() { 
    bool* seen = calloc(LIMIT, sizeof(bool)); 
    if (!seen) { 
     fprintf(stderr, "failed to malloc 'seen' array\n"); 
     return 1; 
    } 
    uint32_t nseen = 0; 
    uint32_t ntries = 0; 
    // this could take a long time -- you can use Ctrl-C to abort a command-line program 
    while (nseen < LIMIT) { 
     if ((ntries & 0xffff) == 0) { 
      printf("after %u tries, we've seen %u different numbers.\n", ntries, nseen); 
     } 
     ++ntries; 
     uint32_t r = myrand(); 
     if (!seen[r]) { 
      seen[r] = true; 
      ++nseen; 
     } 
    } 
    printf("Found them all after %u tries!\n", ntries); 
    return 0; 
} 
1

Je suppose que vous voulez un nombre aléatoire dans la gamme [0, 1000000 [qui est dans une plage longueur de 10 . C'est exactement la même chose que de choisir deux nombres aléatoires dans la plage [0, 1000 [, un pour les chiffres d'ordre supérieur (décimal), un pour les plus petits. Mais il est beaucoup plus facile de travailler dans cette plage ...

Si vous voulez une génération aléatoire correcte, vous devez vous soucier de la probabilité de chaque nombre possible et essayer de le garder aussi égal que possible. Donc, vous devez d'abord rechercher la plus grande puissance de 1000 en dessous de RAND_MAX, rejeter tout nombre supérieur à celui-ci et prendre le module 1000 de chaque valeur conservée.

// Find the max number to keep 
int period = 1000 
unsigned int max = period; 
while (max < (unsigned long) RAND_MAX) { 
    unsigned long t = max * period; 
    if (t < max) break; // test for a possible overflow 
    max = t; 
} 

Vous pouvez ensuite utiliser

for(;;) { 
    unsigned long randnum = rand(); 
    if (randnum < max) { 
     randnum %= period; 
     break; 
    } 
} 

Et quand vous avez deux nombres aléatoires dans la gamme [0, 1000 [, disons n1 et n2, il suffit de faire:

n = period * n1 + n2; 

Bien sûr ci-dessus supposons que vous avez une fonction rand correcte. Si l'utilisation incertain random-rand page de manuel sur mon système indique qu'il utilise même algorythme que random qui est la raison pour laquelle je suppose que je peux l'utiliser en toute sécurité, mais il dit aussi:

implémentations

Cependant, le rand plus(), et implémentations actuelles sur des systèmes différents, les bits d'ordre inférieur sont beaucoup moins aléatoires que les bits d'ordre supérieur.N'utilisez pas cette fonction dans des applications destinées à être portables lorsqu'une bonne répartition aléatoire est nécessaire. (Utilisez random (3) à la place.)

+0

'max' devrait probablement être' long non signé 'aussi, ne devrait pas? – Kundor