Générer un réel aléatoire

Générer un réel aléatoire - C - Programmation

Marsh Posté le 21-04-2006 à 23:18:38    

Comment faire pour générer un chiffre réel de manière aléatoire ??
Doit on utiliser rand() comment faire ?

Reply

Marsh Posté le 21-04-2006 à 23:18:38   

Reply

Marsh Posté le 21-04-2006 à 23:29:45    

si t'as la glib, utilise double g_random_double(void)  sinon regarde comment c'est foutu.

Reply

Marsh Posté le 21-04-2006 à 23:33:03    

je trouve po la bibliothèque glib
ds le dossier include de mon compilateur jvé essayé de l'installé déja

Reply

Marsh Posté le 21-04-2006 à 23:33:48    

laisse tomber ...

Reply

Marsh Posté le 21-04-2006 à 23:37:46    

comment puis je faire alors ??

Reply

Marsh Posté le 22-04-2006 à 00:05:18    

  • (double)rand()/(double)RAND_MAX

donne un nombre dans l'intervalle [0;1]
chercher <<RAND_MAX>> sur le forum, tu trouvera d'autres exemples.
PS: [0;1] pseudo-uniforme


Message édité par nargy le 22-04-2006 à 00:06:10
Reply

Marsh Posté le 22-04-2006 à 00:10:49    

drand48 fournie par la glibc, bien lire la doc

Reply

Marsh Posté le 22-04-2006 à 00:20:04    

D'après le man:

Citation :


CONFORMING TO
       SVID 3
 
NOTES
       These  functions  are  declared  obsolete  by SVID 3, which states that
       rand(3) should be used instead.


Il me semble que seul rand() soit 100% portable.
Ceci dit, la méthode que j'ai décrite ne profite pas de tous les bits disponibles avec le type double, donc le man peut être interessant en ce sens:

Citation :


       The value returned  by  any  of  the  functions  drand48(),  erand48(),
       lrand48(),  nrand48(), mrand48() or jrand48() is computed by first gen-
       erating the next 48-bit Xi in the sequence.  Then the appropriate  num-
       ber  of  bits,  according  to  the type of data item to be returned, is
       copied from the high-order bits of Xi and transformed into the returned
       value.


-> faire plusieurs appels à rand(), et garder les bits de poids fort.

Reply

Marsh Posté le 22-04-2006 à 00:24:47    

Citation :

Il me semble que seul rand() soit 100% portable.


 
j'ai bien dit glibc (et SVID à l'origine) et comme beaucoup roulent sous gcc...
 

Citation :

-> faire plusieurs appels à rand(), et garder les bits de poids fort.


 
des appels consecutif à rand n'augmente pas le pseudo alea puisque chaque appel de rand depend du precedent, il faut un generateur qui sortent plus de bits

Reply

Marsh Posté le 22-04-2006 à 00:30:42    

hum c'est chaud, je suis pas spécialiste, bien que je me suis déjà fait un générateur qui fonctionnait correctement.
 
il me semble que si ça n'augmente pas, ça ne diminue pas non plus.. quoique ça diminue la période de répétition, c'est ça?
 
PS: rand()/RAND_MAX c'est ok dans la plupart des cas

Reply

Marsh Posté le 22-04-2006 à 00:30:42   

Reply

Marsh Posté le 22-04-2006 à 09:11:22    

jvous remercie jvé testé tout ca ds la journée et jvou tient o courant

Reply

Marsh Posté le 22-04-2006 à 10:03:59    

superhoho a écrit :

comment puis je faire alors ??


1) tu commences par initialiser ton générateur aléatoire avec srand
Par ex: srand(time(NULL) ^ getpid())
 
2) Comme l'a dit nargy, tu utilises
(double)rand() / RAND_MAX * (B - A) + A => Te donne un nb aléatoire dans l'intervalle [A; B[


Message édité par Sve@r le 22-04-2006 à 10:04:34

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 22-04-2006 à 10:23:19    

2) sous certaines conditions. dans le cas qui nous intéresse, ça ne marche pas. y a personne d'intelligent pour trouver une implémentation et l'utiliser ... toujours réinventer la roue carrée, toujours ...

Reply

Marsh Posté le 22-04-2006 à 10:41:06    

> Te donne un nb aléatoire dans l'intervalle [A; B[
[A; B]
 
Taz> peut-tu expliquer? ou donner un exemple de roue carré?
Quand j'avais essayé cette méthode, l'histogramme des fréquences est quasi plat.
 
man rand:

Citation :


              "If  you want to generate a random integer between 1 and 10, you
              should always do it by using high-order bits, as in
 
                     j=1+(int) (10.0*rand()/(RAND_MAX+1.0));
 
              and never by anything resembling
 
                     j=1+(rand() % 10);
 
              (which uses lower-order bits)."

Message cité 1 fois
Message édité par nargy le 22-04-2006 à 10:45:04
Reply

Marsh Posté le 22-04-2006 à 10:45:37    

nargy a écrit :

> Te donne un nb aléatoire dans l'intervalle [A; B[
[A; B]


Euh oui c'est vrai. Faut diviser par (ROUND_MAX + 1) pour avoir [A; B[...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 22-04-2006 à 12:34:02    

mais bon sang, on s'en fiche tu 'pas de %' tout le monde le sait ça, on veut un double alératoire. avec la technique con, tu NE PEUX PAS GÉNÉRER UN DOUBLE ALÉATOIRE.

Reply

Marsh Posté le 22-04-2006 à 12:42:06    

franchement, regardez un peu comment sont fait des bibli célèbres, ça sert à rien de triturer jusqu'à que ça ait l'air de. Et avec le rand() de base, on va vraiment pas loin. Si encore ça donnait du [0; 2^32[ on pourrait bosser un peu, mais là, c'est trop peu. Surtout que comme l'implémentation est triviale, on peut pas l'utiliser plusieurs fois à la suite sans tout fausser.

Reply

Marsh Posté le 22-04-2006 à 12:42:10    

Si ça fonctionne pour un entier, pourquoi pas avec un réel?
double j=1.0+ (10.0*rand()/(RAND_MAX+1.0));
La précision n'est certes pas de 52 bits, mais drand48 non plus.

Reply

Marsh Posté le 22-04-2006 à 13:23:52    

Cette partie du manuel de <<grand>>:

Citation :


The g_rand*_range functions will return high quality equally distributed random numbers, whereas for example the (g_random_int()%max) approach often doesn't yield equally distributed numbers.


indique que l'algorithme de base, bien que un poil plus élaboré que celui de rand(), possède les même inconvénients.
 
Le code pour g_random_double fait appel à cette fonction:

Code :
  1. /* transform [0..2^32] -> [0..1] */
  2. #define G_RAND_DOUBLE_TRANSFORM 2.3283064365386962890625e-10
  3. gdouble
  4. g_rand_double (GRand* rand)
  5. {   
  6.   /* We set all 52 bits after the point for this, not only the first
  7.      32. Thats why we need two calls to g_rand_int */
  8.   gdouble retval = g_rand_int (rand) * G_RAND_DOUBLE_TRANSFORM;
  9.   retval = (retval + g_rand_int (rand)) * G_RAND_DOUBLE_TRANSFORM;
  10.   /* The following might happen due to very bad rounding luck, but
  11.    * actually this should be more than rare, we just try again then */
  12.   if (retval >= 1.0)
  13.     return g_rand_double (rand);
  14.   return retval;
  15. }


 
D'après Taz:

Citation :


franchement, regardez un peu comment sont fait des bibli célèbres, ça sert à rien de triturer jusqu'à que ça ait l'air de. Et avec le rand() de base, on va vraiment pas loin. Si encore ça donnait du [0; 2^32[ on pourrait bosser un peu, mais là, c'est trop peu. Surtout que comme l'implémentation est triviale, on peut pas l'utiliser plusieurs fois à la suite sans tout fausser.


Il y a comme une incohérence...

Reply

Marsh Posté le 22-04-2006 à 13:26:19    

jsui dsl moi jécris ceci :  
 
for(j=0;j<3;j++)
               
              {tabcolor[i][j]= (double)rand() / RAND_MAX * (0 - 1) + 1 ;
               printf("%lf\n",tabcolor[i]);
              }
 
et j'obtiens 0.0000
                0.0000
                0.0000 et idem pour les autres méthodes énoncés est ce ke jai fé kkchoz po com il fo jarrive po a générer ce chiffre réel !!!

Reply

Marsh Posté le 22-04-2006 à 13:39:32    

superhoho a écrit :

jsui dsl moi jécris ceci :  
 
for(j=0;j<3;j++)
               
              {tabcolor[i][j]= (double)rand() / RAND_MAX * (0 - 1) + 1 ;
               printf("%lf\n",tabcolor[i]);
              }
 
et j'obtiens 0.0000
                0.0000
                0.0000 et idem pour les autres méthodes énoncés est ce ke jai fé kkchoz po com il fo jarrive po a générer ce chiffre réel !!!


Ton code est incomplet et abérrant...
 
Ceci fonctionne :  

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. int main (void)
  5. {
  6.    double tabcolor[3];
  7.    int j;
  8.    srand ((unsigned) time(NULL));
  9.    for (j = 0;j < 3;j++)
  10.    {
  11.       tabcolor[j] = (double)rand() / RAND_MAX * (0 - 1) + 1 ;
  12.    }
  13.    for (j = 0;j < 3;j++)
  14.    {
  15.       printf("%f\n", tabcolor[j]);
  16.    }
  17.    return 0;
  18. }



0.732963
0.728629
0.257271



0.731071
0.496353
0.899045



0.729575
0.576098
0.721458


Ca me parait correct, non ?


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 22-04-2006 à 13:39:33    

(double)rand() / RAND_MAX * (0.0 - 1.0) + 1.0 ;

Reply

Marsh Posté le 22-04-2006 à 17:52:56    

nargy a écrit :


Il y a comme une incohérence...


non. d'un côté on a rand() tout pourri qui donne 16bits. de l'autre on a un générateur de mersenne qui va donner 2 x 32 bits ... étaler 16bits sur 64, ça donne rien de bien bon ...

Reply

Marsh Posté le 22-04-2006 à 18:10:56    

Taz a écrit :

non. d'un côté on a rand() tout pourri qui donne 16bits. de l'autre on a un générateur de mersenne qui va donner 2 x 32 bits ... étaler 16bits sur 64, ça donne rien de bien bon ...


Un générateur de mersenne est tout aussi <<pourri>>: il a une période et la qualité se dégrade pour les bits de poids faible.

Reply

Marsh Posté le 22-04-2006 à 18:26:44    

le rapport avec les bits de poids faible ? t'es entrain de nous dire que mersonne et un simple truc par congruence, c'est la meme qualité ?

Reply

Marsh Posté le 22-04-2006 à 18:33:02    

> t'es entrain de nous dire que mersonne et un simple truc par congruence, c'est la meme qualité ?
- non, ils ont le même inconvénient: ils ont une période. si tu me dit qu'il n'est pas possible d'utiliser plusieurs nombres pour en générer un autre, ça vaut pour les deux algos.

Reply

Marsh Posté le 22-04-2006 à 20:24:50    

voila mon code :
 
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
int main()
{
    double **tabcolor;
    int pixels;
    int i,j;
    char menu;
     
    srand ((unsigned) time(NULL));
     
do {
    printf("          ********** Bienvenue **********\n"
           "Que desirez vous faire :\n"
           "- Gerer un tableau tapez 1\n"
           "- Rendre un tableau monochrome tapez 2\n"  
           "- Lisser un tableau tapez 3\n"
           "- Quittez tapez 4\n\n" );
    scanf(" %c",&menu);
   }while(menu!='1' && menu!='2' && menu!='3' && menu!='4');
     
     if (menu=='1')
         
        {printf("\n***** Gerer un tableau *****\n" );
         do {
             printf("\nSaisir le nombre de pixels que vous desirez (0<N<100): " );
             scanf("%d",&pixels);
             }while(pixels<0 || pixels>100);
             
     tabcolor=(double **)malloc(sizeof(double *)*pixels);
 
     for (i=0;i<pixels;i++)
     {tabcolor[i]=(double *)malloc(3.0*sizeof(double));}
     
     for (i=0;i<pixels;i++)
           
         { for(j=0;j<3;j++)
               
              {tabcolor[j] = (double)rand() / RAND_MAX * (0 - 1) + 1 ;
               printf("%lf\n",tabcolor[i]);
              }
              }
         
         } /* Fin du if(menu=='1') */
         
   
  system("PAUSE" );  
  return 0;
}
 
 
Bon précision on se limite juste au niveau du choix n°1 pour le moment pour le menu mais écris comme ca j'ai un message d'erreur :
 
incompatible types in assignment  
 
j'imagine que il y a un souci au niveau des mes types de variables mais sincèrement je vois pas !!

Reply

Marsh Posté le 22-04-2006 à 20:42:41    

superhoho a écrit :

voila mon code :


 

Citation :


Code :
  1. scanf(" %c",&menu);
  2.              scanf("%d",&pixels);




Mauvais choix de la fonction de saisie.
 
http://mapage.noos.fr/emdel/notes.htm#saisie
http://mapage.noos.fr/emdel/notes.htm#fichiers
 

Citation :


Code :
  1. tabcolor=(double **)malloc(sizeof(double *)*pixels);




Cast inutile. Codage inutilement complexe... Par contre, il manque l'essentiel : malloc() peut echouer, pas de libération.
 
http://mapage.noos.fr/emdel/notes.htm#malloc
 

Citation :


Code :
  1. tabcolor[i]=(double *)malloc(3.0*sizeof(double));




Le type attendu par malloc() est entier. 3.0 est un double.

Citation :


Code :
  1. for (i=0;i<pixels;i++)
  2.          
  3.          { for(j=0;j<3;j++)
  4.              
  5.               {tabcolor[j] = (double)rand() / RAND_MAX * (0 - 1) + 1 ;
  6.                printf("%lf\n",tabcolor[i]);



Visiblement, tu n'a pas compris que tu avais construit un tableau dynamique à 2 dimensions. Tu codes au hasard ou tu recopies du code sans le comprendre ? Il faut[i][j] ...

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. int main(void)
  5. {
  6.    char menu;
  7.    srand ((unsigned) time(NULL));
  8.    do
  9.    {
  10.       printf("          ********** Bienvenue **********\n"
  11.              "Que desirez vous faire :\n"
  12.              "1 - Gerer un tableau\n"
  13.              "2 - Rendre un tableau monochrome\n"
  14.              "3 - Lisser un tableau\n"
  15.              "4 - Quittez\n\n" );
  16.       scanf(" %c", &menu);
  17.    }
  18.    while (menu != '1' && menu != '2' && menu != '3' && menu != '4');
  19.    if (menu == '1')
  20.    {
  21.       int pixels;
  22.       printf("\n***** Gerer un tableau *****\n" );
  23.       do
  24.       {
  25.          printf("\nSaisir le nombre de pixels que vous desirez (0<N<100): " );
  26.          scanf("%d", &pixels);
  27.       }
  28.       while (pixels < 0 || pixels > 100);
  29.       {
  30.          double **tabcolor = malloc(sizeof * tabcolor * pixels);
  31.          if (tabcolor != NULL)
  32.          {
  33.             int err;
  34.             int i, j;
  35.             for (i = 0;i < pixels;i++)
  36.             {
  37.                tabcolor[i] = malloc(3 * sizeof(double));
  38.                err = tabcolor[i] == NULL;
  39.             }
  40.             if (!err)
  41.             {
  42.                for (i = 0;i < pixels;i++)
  43.                {
  44.                   for (j = 0;j < 3;j++)
  45.                   {
  46.                      tabcolor[i][j] = (double) rand() / RAND_MAX * (0 - 1) + 1 ;
  47.                      printf("%lf\n", tabcolor[i][j]);
  48.                   }
  49.                }
  50.                for (i = 0;i < pixels;i++)
  51.                {
  52.                   free (tabcolor[i]), tabcolor[i] = NULL;
  53.                }
  54.             }
  55.             free(tabcolor), tabcolor = NULL;
  56.          }
  57.       }
  58.    } /* Fin du if(menu=='1') */
  59.    system("PAUSE" );
  60.    return 0;
  61. }


Message édité par Emmanuel Delahaye le 22-04-2006 à 20:49:26

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 22-04-2006 à 22:25:58    

je cherche a faire un tableau dynamique a 2dimensions ca tinket po ok j'ai oublié [i] mais jai bien écris ce ke l'on m'a donné mé j'obtiens toujours rien
a moins ke mon malloc soit po correctement réalisé !!
 
Je souhaite crée un tableau a 2 dimensions de 3 colonnes et n lignes

Reply

Marsh Posté le 22-04-2006 à 22:37:32    

superhoho a écrit :

je cherche a faire un tableau dynamique a 2dimensions ca tinket po ok j'ai oublié [i] mais jai bien écris ce ke l'on m'a donné mé j'obtiens toujours rien
a moins ke mon malloc soit po correctement réalisé !!


Je rappelle que la langue de ce forum est le français ...

Citation :


Je souhaite crée un tableau a 2 dimensions de 3 colonnes et n lignes


Je t'ai donné une solution...
Montre ton dernier code qui ne fonctionne pas.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 22-04-2006 à 23:01:19    

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
int main()
{
    double **tabcolor;
    int pixels;
    int i,j;
    char menu;
     
    srand ((unsigned) time(NULL));
     
do {
    printf("          ********** Bienvenue **********\n"
           "Que desirez vous faire :\n"
           "- Gerer un tableau tapez 1\n"
           "- Rendre un tableau monochrome tapez 2\n"  
           "- Lisser un tableau tapez 3\n"
           "- Quittez tapez 4\n\n" );
    scanf(" %c",&menu);
   }while(menu!='1' && menu!='2' && menu!='3' && menu!='4');
     
     if (menu=='1')
         
        {printf("\n***** Gerer un tableau *****\n" );
         do {
             printf("\nSaisir le nombre de pixels que vous desirez (0<N<100): " );
             scanf("%d",&pixels);
             }while(pixels<0 || pixels>100);
             
     tabcolor=(double **)malloc(sizeof(double *)*pixels);
 
     for (i=0;i<pixels;i++)
     {tabcolor[i]=(double *)malloc(3.0*sizeof(double));}
     
     for (i=0;i<pixels;i++)
           
         { for(j=0;j<3;j++)
               
              {tabcolor[i][j] = (double)rand() / RAND_MAX * (0 - 1) + 1 ;
               printf("%lf\n",tabcolor[i]);
              }
              }
         
         } /* Fin du if(menu=='1') */
         
   
  system("PAUSE" );  
  return 0;
}

Reply

Marsh Posté le 22-04-2006 à 23:31:49    

superhoho a écrit :


     {tabcolor[i]=(double *)malloc(3.0*sizeof(double));}
 
              {tabcolor[i][j] = (double)rand() / RAND_MAX * (0 - 1) + 1 ;
 
               printf("%lf\n",tabcolor[i]);


 

  • Déjà dit : utiliser les balises code...
  • Déjà dit : ne pas mettre de flottant dans le paramètre de malloc()...
  • Le cast (double) est mal placé. Il devrait concerner un des opérandes de la division.
  • Déjà dit : dans le dernier printf(), c'est aussi [i][j]


Message édité par Emmanuel Delahaye le 22-04-2006 à 23:58:01

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 22-04-2006 à 23:46:37    

c bon ca fonctionne enfin jvou remercie tous c t bien ca c t mon dernier printf qui fesait tout planter

Reply

Marsh Posté le 25-04-2006 à 18:43:43    

nargy a écrit :

> t'es entrain de nous dire que mersonne et un simple truc par congruence, c'est la meme qualité ?
- non, ils ont le même inconvénient: ils ont une période. si tu me dit qu'il n'est pas possible d'utiliser plusieurs nombres pour en générer un autre, ça vaut pour les deux algos.


 
Tu as autre chose a proposer?

Reply

Marsh Posté le 25-04-2006 à 19:16:41    

> Tu as autre chose a proposer?
- lol :lol: toute la question est là. je peut te renvoyer aux discussions sur les wikis, notamment wiikipedia. Mais en gros, la prochaine étape, après augmenter la période, est d'utiliser seed(time(NULL)) plus judicieusement, les algo les plus interessants utilisent un accumulateur d'entropie (entropie=désordre), qui fonctionne en accumulant le plus de données disparates possibles (l'utilisateur appuye sur une touche, une connexion internet arrive, ...). Le top du top serait d'avoir un accélérateur de particules à disposition :D en pratique, linux utilise /dev/random qui accumule de l'entropie suivant l'état des processus, des drivers, de la mémoire etc...
 
- ce que je dis, c'est que finalement, même si la méthode proposée par Taz est certainement plus précise (période plus grande) elle possède les même caractéristiques.
 
- les méthodes de cryptage utilisent une période immense, notamment en utilisant une multiplication de deux nombres entiers très gands, de façon à rendre le décryptage (trouver les nombres premiers à partir du résultat de leur multiplication) très long (plusieurs années sur un super-calculateur). voir algo cryptage PGP.

Reply

Marsh Posté le 26-04-2006 à 05:15:00    

un générateur quantique en ligne, à base de photons:
http://www.randomnumbers.info/

Reply

Marsh Posté le 26-04-2006 à 08:50:31    

http://www.intel.com/design/softwa [...] curity.htm  
http://www.idquantique.com/products/quantis.htm  
http://qrbg.irb.hr/  
http://www.true-random.com/
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 26-04-2006 à 15:04:30    

Merci pour vos reponses,  
 
mais en soft, vous ne connaissez rien d'autre?

Reply

Marsh Posté le 26-04-2006 à 15:10:38    

thermocline a écrit :

Merci pour vos reponses,  
 
mais en soft, vous ne connaissez rien d'autre?


Mersenne Twister, mais je crois que ça a déjà été évoqué... Sinon, les polynômes genre CRC4, CRC8 etc.
 
[:google] est ton ami
 
Au fait, c'est une question pour le forum ALGO. Le langage C n'est qu'un outil de réalisation...

Message cité 1 fois
Message édité par Emmanuel Delahaye le 26-04-2006 à 15:12:03

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 26-04-2006 à 15:31:47    

Emmanuel Delahaye a écrit :

Mersenne Twister, mais je crois que ça a déjà été évoqué... Sinon, les polynômes genre CRC4, CRC8 etc.
 
[:google] est ton ami
 
Au fait, c'est une question pour le forum ALGO. Le langage C n'est qu'un outil de réalisation...


 
Merci de nous avoir etaler toute ta science dans le domaine (de la generation aleatoire), je vais en retour me permettre de te donner un conseil sur google: jamais un bete moteur de recherche ne remplacera l'experience (surtout sur un domaine aussi "sensible" ) que certains etres humains peuvent avoir.  
 
 
Quand a crc4 et crc8 etc., no comment.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed