2009-11-04 5 views
5

Je veux générer des nombres aléatoires de -n à n en excluant 0. Quelqu'un peut-il me fournir le code en C? Comment exclure 0?Générer des nombres aléatoires de -n à n dans C

+1

Pourquoi le vote à la baisse? Je souhaite que ce site force les gens à ajouter un commentaire quand ils voteront. –

Répondre

9

Une idée pourrait être de générer un nombre aléatoire x dans la gamme [1,2n], inclusivement. Puis retournez -(x - n) pour x plus grand que n, sinon il suffit de retourner x.

Cela devrait fonctionner:

int my_random(int n) 
{ 
    const int x = 1 + rand()/(RAND_MAX/(2 * n) + 1); 

    return x > n ? -(x - n) : x; 
} 

Voir la comp.lang.c FAQ pour plus d'informations sur l'utilisation de rand() en toute sécurité; cela explique l'utilisation ci-dessus.

+0

Merci. Chris vient de poster la réponse avant que je fasse ça. – avd

3

La chose la plus simple que je peux suggérer à faire est de générer un nombre aléatoire entre 0 et 2n, puis faire le tour de mathématiques:

result= n - randomNumber 

Bien que 0 peut être très peu probable que vous pouvez vérifier que l'utilisation d'un Si et refaire la génération de nombre aléatoire.

1
int random(int N) 
{ 
    int x; 
    do{ 
    x=rand()%(N*2+1)-N; 
    }while(x==0); 
    return x; 
} 

Il choisit un certain nombre de N à N, mais continue à le faire si elle est 0.

Une alternative, comme suggéré dans les commentaires, génère un nombre entre -N et N-1 et l'incrémente si son positif ou 0:

int random(int N) 
{ 
    int x;  
    x=rand()%(N*2)-N; 
    if(x>=0) x++; 
    return x; 
} 
+1

Un do-while dépendant d'une valeur aléatoire pourrait s'exécuter très longtemps! Mais vous pouvez vous débarrasser du temps d'exécution non déterministe en réduisant la plage du résultat aléatoire de 1, puis en convertissant artificiellement tout résultat 0 en résultat de limite manquant. Aucune boucle nécessaire. –

+0

Je ne suis pas d'accord avec votre affirmation que cela prendrait un "long, long temps": La chance de x étant 0 (et donc, la boucle se répétant) est 1/(2N + 1), ce qui est assez petit pour Valeurs de N. Néanmoins, j'ai incorporé votre suggestion dans ma réponse, ce qui, selon moi, donne une meilleure solution pour ce problème particulier, alors merci :) – Wernsey

+0

Ah ... je n'ai pas dit que ça "prendrait" longtemps temps, mais plutôt que cela "pourrait" prendre beaucoup de temps. Il existe une différence! :) Je m'excuse si cela semble effronté. Je travaille dans un logiciel en temps réel, où tout ce qui ne peut être absolument garanti pour finir dans un temps déterministe "pourrait prendre beaucoup de temps". Techniquement parlant, votre première version est O (?) Et votre deuxième version est O (1) (ou au pire, pas plus complexe que "rand"). Donc, en termes de déterminisme, votre deuxième version est une grande amélioration. Bien fait, btw. Ma suggestion de "convertir le 0 à la frontière" n'aurait pas été aussi belle. –

Questions connexes