Générer un réel aléatoire - C - Programmation
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.
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
Marsh Posté le 22-04-2006 à 00:05:18
donne un nombre dans l'intervalle [0;1]
chercher <<RAND_MAX>> sur le forum, tu trouvera d'autres exemples.
PS: [0;1] pseudo-uniforme
Marsh Posté le 22-04-2006 à 00:20:04
D'après le man:
Citation : |
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 : |
-> faire plusieurs appels à rand(), et garder les bits de poids fort.
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
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
Marsh Posté le 22-04-2006 à 09:11:22
jvous remercie jvé testé tout ca ds la journée et jvou tient o courant
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[
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 ...
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 : |
Marsh Posté le 22-04-2006 à 10:45:37
nargy a écrit : > Te donne un nb aléatoire dans l'intervalle [A; B[ |
Euh oui c'est vrai. Faut diviser par (ROUND_MAX + 1) pour avoir [A; B[...
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.
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.
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.
Marsh Posté le 22-04-2006 à 13:23:52
Cette partie du manuel de <<grand>>:
Citation : |
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 :
|
D'après Taz:
Citation : |
Il y a comme une incohérence...
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 !!!
Marsh Posté le 22-04-2006 à 13:39:32
superhoho a écrit : jsui dsl moi jécris ceci : |
Ton code est incomplet et abérrant...
Ceci fonctionne :
Code :
|
|
|
|
Ca me parait correct, non ?
Marsh Posté le 22-04-2006 à 17:52:56
nargy 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 ...
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.
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é ?
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.
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 !!
Marsh Posté le 22-04-2006 à 20:42:41
superhoho a écrit : voila mon code : |
Citation :
|
Mauvais choix de la fonction de saisie.
http://mapage.noos.fr/emdel/notes.htm#saisie
http://mapage.noos.fr/emdel/notes.htm#fichiers
Citation :
|
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 :
|
Le type attendu par malloc() est entier. 3.0 est un double.
Citation :
|
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 :
|
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
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 |
Je rappelle que la langue de ce forum est le français ...
Citation : |
Je t'ai donné une solution...
Montre ton dernier code qui ne fonctionne pas.
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;
}
Marsh Posté le 22-04-2006 à 23:31:49
superhoho a écrit : |
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
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é ? |
Tu as autre chose a proposer?
Marsh Posté le 25-04-2006 à 19:16:41
> Tu as autre chose a proposer?
- 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 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.
Marsh Posté le 26-04-2006 à 05:15:00
un générateur quantique en ligne, à base de photons:
http://www.randomnumbers.info/
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+,
Marsh Posté le 26-04-2006 à 15:04:30
ReplyMarsh Posté le 26-04-2006 à 15:10:38
thermocline a écrit : Merci pour vos reponses, |
Mersenne Twister, mais je crois que ça a déjà été évoqué... Sinon, les polynômes genre CRC4, CRC8 etc.
est ton ami
Au fait, c'est une question pour le forum ALGO. Le langage C n'est qu'un outil de réalisation...
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. |
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.
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 ?