IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

rand() modulo, pourquoi pas ?


Sujet :

C

  1. #1
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut rand() modulo, pourquoi pas ?
    Salut !

    Je viens de penser un truc.
    Pour être honnête, je trouve le code dans la FAQ assez lourd

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <stdlib.h>
     
    int rand_n(int n)
    {
        int partSize   = 1 + (n == RAND_MAX ? 0 : (RAND_MAX - n) / (n + 1));
        int maxUsefull = partSize * n + (partSize - 1);
        int draw;
     
        do {
            draw = rand();
        } while (draw > maxUsefull);
     
        return draw / partSize;
    }
    Y a 3 variables, une boucle, bref bien trop lourd imo.

    Pourquoi ne pas simplement utiliser quelque chose de ce style ?:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int n = (rand() >> 8) % x;
    Cela permettrait d'éviter d'avantager les bits de poids le plus faible et me paraît plus performant en même temps.

    Qu'en pensez-vous ?

  2. #2
    Membre averti
    Avatar de Chatanga
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    211
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 211
    Points : 346
    Points
    346
    Par défaut
    Je pars du principe que tu as voulu écrire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int rand_n(int n)
    {
        return (rand() >> 8) % n;
    }
    Soit N = (RAND_MAX >> 8) :
    • si n > N, tu as un problème évident ;
    • si n n'est pas divisible par N, tu n'aura pas une distribution uniforme des résultats.

    Deux problèmes dont la version de la FAQ ne souffre pas.

  3. #3
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Ce sera sans doute néfaste : pour corriger une éventuelle imperfection du générateur sur les bits de poids faible, on va augmenter le biais lié à l'utilisation du modulo.

    Supposons ici le générateur de nombres pseudo-aléatoire parfait et qu'il délivre un nombre N , 0<= N <A, de façon équiprobable.

    Alors v = N%n n'est pas ,en général, équiprobable entre 0 et n-1 :
    En posant (division euclidienne) A = Qn+R avec 0<= R <n, les valeurs v obtenues lorsque N varie de 0 à A-1 sont en nombre de Q+1 pour 0<= v <R et de Q pour R<= v <n.
    La probabilité d'obtenir 0<= v <R est de (Q+1)/A et pour R<= v <n de Q/A. L'écart de probabilité est d'autant plus faible que Q est grand, donc A grand devant n.

    Continuons avec, pour simplifier mais je pense que c'est le cas le plus répandu, pour A une puissance de 2 : A = 2^P

    Avec N' = N >> m , soit N' = N/2^m, on obtient des valeurs N' équiprobables avec 0 <= N' < A' où A' = 2^(P-m)
    On est ramené au cas précédent avec A' plus petit que A

    Par exemple :

    - avec A = 32768 et n = 10, on a Q = 3276 et R = 8 .
    La probabilité d'obtenir une valeur de 0 à 7 est de 3277/32768 = 0.10006 et pour 8 ou 9 de 3276/32768 = 0.099976

    - Le même avec m=8 , N' = N>>8. On a A' = 128 , Q = 12 et R = 8.
    La probabilité d'obtenir une valeur de 0 à 7 est de 13/128 = 0.1016 et pour 8 ou 9 de 12/128 = 0.0938.

  4. #4
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Merci pour ces explications très précises

    D'ailleurs j'y ai pensé durant ma sieste

  5. #5
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Voir aussi cette discussion, qui peut t'éclairer un peu sur le sujet.

Discussions similaires

  1. La binaire et pourquoi pas le ternaire
    Par Chromatic dans le forum Ordinateurs
    Réponses: 34
    Dernier message: 09/07/2012, 15h28
  2. Pourquoi pas WinDev 9 ?
    Par nyarla01 dans le forum WinDev
    Réponses: 35
    Dernier message: 25/07/2006, 19h41
  3. JTreeTable pourquoi pas en standard?
    Par Antoine_1977 dans le forum AWT/Swing
    Réponses: 7
    Dernier message: 03/01/2006, 22h33
  4. [Language][DAO]Pourquoi pas des Singletons ?
    Par le Daoud dans le forum Langage
    Réponses: 11
    Dernier message: 04/05/2005, 09h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo