Dans le cadre d'un exercice d'apprentissage, je dois créer 2 nombres
aléatoires.
J'ai utilisé 2 srand, mais la solution utilisée ne me semble pas très
élégante...
Si vous avez autre chose à suggérer, cela serait bienvenu. :-)
int main()
{
int a,b,c;
while (true)
{
srand(time(0));
a=rand()%10+1;
srand(time(0)/4);
b=rand()%10+1;
cout << "Combien font " << a << "x" << b << " ?" << endl;
cin >> c;
if (c==a*b)
cout << "Bravo ! Résultat exact !" << endl;
else
cout << "Désolé... Mauvaise réponse." << endl;
cout << endl;
}
Dans le cadre d'un exercice d'apprentissage, je dois créer 2 nombres aléatoires. J'ai utilisé 2 srand, mais la solution utilisée ne me semble pas très élégante... Si vous avez autre chose à suggérer, cela serait bienvenu. :-)
1) On n'appelle srand qu'une seule fois dans le programme. Plusieurs appels rendent la suite générée moins "aléatoire".
2) Pour des raisons techniques la "qualité" des nombres aléatoires générés par
a = (int)(rand()/(RAND_MAX+1.0)*10)+1;
est en général meilleure que celle des nombres généres par
a = rand()%10+1;
(cf.la FAQ)
Pour des applications du type "joujou" comme la tienne la méthode n'importe pas mais quand il s'agit de simulations "sérieuses" il faudrait préfèrer la premiere méthode.
Pour des simulations sérieuses, j'espère qu'on évite rand() et qu'on utilise à la place un générateur dont on connaît les propriétés.
Cela va de soi, mais même pour des simulation "sémi-sérieuses" avec le rand "out of the box" la différence entre les deux méthodes est assez intéressante. p.ex. la moyenne est moins déformée.
Est-ce que tu pourrais expliquer d'avantage ?
Parce qu'en fin de compte, quelque soit le moyen utiliser pour reduire l'intervale, rand() va renvoyer un de RAND_MAX valeurs différentes. Et que si RAND_MAX n'est pas un multiple de 10, il va y avoir forcemment certaines valeurs qui apparaissent plus souvent que d'autres.
Or, la seule différence que je vois ici, c'est que dans la première forme, ces valeurs seront les n premières valeurs, tandis que avec la deuxième, ces valeurs vont se répartir dans l'ensemble. Ce qui joue effectivement sur le moyen, mais sur rien d'autre.
J'ai vu deux solutions au problème (qui en fait reviennent au même) ; celle que j'utilise d'habitude est :
int nextRandom( int top ) { int const limit = (RAND_MAX + 1) - (RAND_MAX + 1) % top ; int result = rand() ; while ( result >= limit ) { result = rand() ; } return result % top ; }
Dans la pratique, pour un modulo 10, je doute que c'est la peine. Un bon rand() va avoir un u RAND_MAX d'au moins 2000000000, et la différence entre cette algorithme et le naïve rand()%10 est assez faible pour être acceptable dans la plupart des applications.
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Horst Kraemer wrote:
Richard Delorme <abulmo@nospam.fr> wrote:
Dudule <nospam_svdbg_nospam@free.fr> wrote:
Dans le cadre d'un exercice d'apprentissage, je dois créer
2 nombres aléatoires. J'ai utilisé 2 srand, mais la
solution utilisée ne me semble pas très élégante... Si
vous avez autre chose à suggérer, cela serait bienvenu.
:-)
1) On n'appelle srand qu'une seule fois dans le programme.
Plusieurs appels rendent la suite générée moins
"aléatoire".
2) Pour des raisons techniques la "qualité" des nombres
aléatoires générés par
a = (int)(rand()/(RAND_MAX+1.0)*10)+1;
est en général meilleure que celle des nombres généres par
a = rand()%10+1;
(cf.la FAQ)
Pour des applications du type "joujou" comme la tienne la
méthode n'importe pas mais quand il s'agit de simulations
"sérieuses" il faudrait préfèrer la premiere méthode.
Pour des simulations sérieuses, j'espère qu'on évite rand()
et qu'on utilise à la place un générateur dont on connaît
les propriétés.
Cela va de soi, mais même pour des simulation "sémi-sérieuses"
avec le rand "out of the box" la différence entre les deux
méthodes est assez intéressante. p.ex. la moyenne est moins
déformée.
Est-ce que tu pourrais expliquer d'avantage ?
Parce qu'en fin de compte, quelque soit le moyen utiliser pour
reduire l'intervale, rand() va renvoyer un de RAND_MAX valeurs
différentes. Et que si RAND_MAX n'est pas un multiple de 10, il
va y avoir forcemment certaines valeurs qui apparaissent plus
souvent que d'autres.
Or, la seule différence que je vois ici, c'est que dans la
première forme, ces valeurs seront les n premières valeurs,
tandis que avec la deuxième, ces valeurs vont se répartir dans
l'ensemble. Ce qui joue effectivement sur le moyen, mais sur
rien d'autre.
J'ai vu deux solutions au problème (qui en fait reviennent au
même) ; celle que j'utilise d'habitude est :
int
nextRandom(
int top )
{
int const limit
= (RAND_MAX + 1) - (RAND_MAX + 1) % top ;
int result = rand() ;
while ( result >= limit ) {
result = rand() ;
}
return result % top ;
}
Dans la pratique, pour un modulo 10, je doute que c'est la
peine. Un bon rand() va avoir un u RAND_MAX d'au moins
2000000000, et la différence entre cette algorithme et le naïve
rand()%10 est assez faible pour être acceptable dans la plupart
des applications.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Dans le cadre d'un exercice d'apprentissage, je dois créer 2 nombres aléatoires. J'ai utilisé 2 srand, mais la solution utilisée ne me semble pas très élégante... Si vous avez autre chose à suggérer, cela serait bienvenu. :-)
1) On n'appelle srand qu'une seule fois dans le programme. Plusieurs appels rendent la suite générée moins "aléatoire".
2) Pour des raisons techniques la "qualité" des nombres aléatoires générés par
a = (int)(rand()/(RAND_MAX+1.0)*10)+1;
est en général meilleure que celle des nombres généres par
a = rand()%10+1;
(cf.la FAQ)
Pour des applications du type "joujou" comme la tienne la méthode n'importe pas mais quand il s'agit de simulations "sérieuses" il faudrait préfèrer la premiere méthode.
Pour des simulations sérieuses, j'espère qu'on évite rand() et qu'on utilise à la place un générateur dont on connaît les propriétés.
Cela va de soi, mais même pour des simulation "sémi-sérieuses" avec le rand "out of the box" la différence entre les deux méthodes est assez intéressante. p.ex. la moyenne est moins déformée.
Est-ce que tu pourrais expliquer d'avantage ?
Parce qu'en fin de compte, quelque soit le moyen utiliser pour reduire l'intervale, rand() va renvoyer un de RAND_MAX valeurs différentes. Et que si RAND_MAX n'est pas un multiple de 10, il va y avoir forcemment certaines valeurs qui apparaissent plus souvent que d'autres.
Or, la seule différence que je vois ici, c'est que dans la première forme, ces valeurs seront les n premières valeurs, tandis que avec la deuxième, ces valeurs vont se répartir dans l'ensemble. Ce qui joue effectivement sur le moyen, mais sur rien d'autre.
J'ai vu deux solutions au problème (qui en fait reviennent au même) ; celle que j'utilise d'habitude est :
int nextRandom( int top ) { int const limit = (RAND_MAX + 1) - (RAND_MAX + 1) % top ; int result = rand() ; while ( result >= limit ) { result = rand() ; } return result % top ; }
Dans la pratique, pour un modulo 10, je doute que c'est la peine. Un bon rand() va avoir un u RAND_MAX d'au moins 2000000000, et la différence entre cette algorithme et le naïve rand()%10 est assez faible pour être acceptable dans la plupart des applications.
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Samuel Krempp
(16 May 2005 14:37,
Ce qui les diffère des autres messages, je crois, c'est qu'ils utilisent UTF-8, à la place de l'ISO 8859-1 ou 8859-15 qui est usuel ici, et qu'ils utilisent une forme de citation assez particulière dans l'en-tête. La ligne de sujet, par exmple :
ah d'accord. free bloque les posts UTF-8 (en tout cas vers fclc++). Quand j'ai essayé d'envoyer un message en UTF-8 news.free.fr le refuse.0 34
-- Sam
kanze@gabi-soft.fr (16 May 2005 14:37,
Ce qui les diffère des autres messages, je crois, c'est qu'ils
utilisent UTF-8, à la place de l'ISO 8859-1 ou 8859-15 qui est
usuel ici, et qu'ils utilisent une forme de citation assez
particulière dans l'en-tête. La ligne de sujet, par exmple :
ah d'accord. free bloque les posts UTF-8 (en tout cas vers fclc++). Quand
j'ai essayé d'envoyer un message en UTF-8 news.free.fr le refuse.0 34
Ce qui les diffère des autres messages, je crois, c'est qu'ils utilisent UTF-8, à la place de l'ISO 8859-1 ou 8859-15 qui est usuel ici, et qu'ils utilisent une forme de citation assez particulière dans l'en-tête. La ligne de sujet, par exmple :
ah d'accord. free bloque les posts UTF-8 (en tout cas vers fclc++). Quand j'ai essayé d'envoyer un message en UTF-8 news.free.fr le refuse.0 34
-- Sam
Fabien LE LEZ
On 17 May 2005 02:45:16 -0700, :
[time()]
La fonction time a accepté un pointeur nul comme paramètre depuis au moins vingt ans. La norme C l'exige. La norme Posix aussi. C'est même plutôt rare d'y voir d'autre chose.
On peut même se demander pourquoi time() a un argument...
-- Le grand site de la philosophie animale : <http://perso.edulang.com/philo/>
On 17 May 2005 02:45:16 -0700, kanze@gabi-soft.fr:
[time()]
La fonction time a accepté un pointeur nul comme paramètre
depuis au moins vingt ans. La norme C l'exige. La norme Posix
aussi. C'est même plutôt rare d'y voir d'autre chose.
On peut même se demander pourquoi time() a un argument...
--
Le grand site de la philosophie animale : <http://perso.edulang.com/philo/>
La fonction time a accepté un pointeur nul comme paramètre depuis au moins vingt ans. La norme C l'exige. La norme Posix aussi. C'est même plutôt rare d'y voir d'autre chose.
On peut même se demander pourquoi time() a un argument...
-- Le grand site de la philosophie animale : <http://perso.edulang.com/philo/>
Pierre THIERRY
Le Tue, 17 May 2005 02:45:16 -0700, kanze a écrit :
Et qu'est-ce qu'il dit au sujet d'un pointeur NULL ? (Il faut bien qu'il dise quelque chose, quand même.)
Il ne mentionne pas que le stockage dans le pointeur soit conditionnel, comme tu le disais, c'est tout.
Systématiquement, Nowhere man --
OpenPGP 0xD9D50D8A
Le Tue, 17 May 2005 02:45:16 -0700, kanze a écrit :
Et qu'est-ce qu'il dit au sujet d'un pointeur NULL ? (Il faut bien
qu'il dise quelque chose, quand même.)
Il ne mentionne pas que le stockage dans le pointeur soit conditionnel,
comme tu le disais, c'est tout.
Systématiquement,
Nowhere man
--
nowhere.man@levallois.eu.org
OpenPGP 0xD9D50D8A
Le Tue, 17 May 2005 02:45:16 -0700, kanze a écrit :
Et qu'est-ce qu'il dit au sujet d'un pointeur NULL ? (Il faut bien qu'il dise quelque chose, quand même.)
Il ne mentionne pas que le stockage dans le pointeur soit conditionnel, comme tu le disais, c'est tout.
Systématiquement, Nowhere man --
OpenPGP 0xD9D50D8A
kanze
Fabien LE LEZ wrote:
On 17 May 2005 02:45:16 -0700, :
[time()]
La fonction time a accepté un pointeur nul comme paramètre depuis au moins vingt ans. La norme C l'exige. La norme Posix aussi. C'est même plutôt rare d'y voir d'autre chose.
On peut même se demander pourquoi time() a un argument...
Des raisons historiques. Sous Unix, time() est, et a toujours été, une requête système. Et dans les premiers Unix (sur PDP-11), les conventions d'appel d'une requête système ne permettait pas de renvoyer un long (et la valeur de retour n'était pas définie). Quand on a ajouté la valeur de retour (il y a assez longtemp, quand même), on a pas voulu casser le code qui comptait sur le retour dans le pointeur.
En attendant, rien ne t'empèche en C++ de fournir une version sans paramètres :
time_t time() { return time( NULL ) ; }
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Fabien LE LEZ wrote:
On 17 May 2005 02:45:16 -0700, kanze@gabi-soft.fr:
[time()]
La fonction time a accepté un pointeur nul comme paramètre
depuis au moins vingt ans. La norme C l'exige. La norme Posix
aussi. C'est même plutôt rare d'y voir d'autre chose.
On peut même se demander pourquoi time() a un argument...
Des raisons historiques. Sous Unix, time() est, et a toujours
été, une requête système. Et dans les premiers Unix (sur
PDP-11), les conventions d'appel d'une requête système ne
permettait pas de renvoyer un long (et la valeur de retour
n'était pas définie). Quand on a ajouté la valeur de retour (il
y a assez longtemp, quand même), on a pas voulu casser le code
qui comptait sur le retour dans le pointeur.
En attendant, rien ne t'empèche en C++ de fournir une version
sans paramètres :
time_t
time()
{
return time( NULL ) ;
}
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
La fonction time a accepté un pointeur nul comme paramètre depuis au moins vingt ans. La norme C l'exige. La norme Posix aussi. C'est même plutôt rare d'y voir d'autre chose.
On peut même se demander pourquoi time() a un argument...
Des raisons historiques. Sous Unix, time() est, et a toujours été, une requête système. Et dans les premiers Unix (sur PDP-11), les conventions d'appel d'une requête système ne permettait pas de renvoyer un long (et la valeur de retour n'était pas définie). Quand on a ajouté la valeur de retour (il y a assez longtemp, quand même), on a pas voulu casser le code qui comptait sur le retour dans le pointeur.
En attendant, rien ne t'empèche en C++ de fournir une version sans paramètres :
time_t time() { return time( NULL ) ; }
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
kanze
Pierre THIERRY wrote:
Et qu'est-ce qu'il dit au sujet d'un pointeur NULL ? (Il faut bien qu'il dise quelque chose, quand même.)
Il ne mentionne pas que le stockage dans le pointeur soit conditionnel, comme tu le disais, c'est tout.
Mais alors, qu'est-ce qu'il dit ? Que le comportement est indéfini si tu lui passes NULL ? Ou quelque chose d'autre ?
La possibilité de passer NULL existe depuis que time() renvoie une valeur. Même avant, d'ailleurs, mais avant, c'était un comportement indéfini.
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Pierre THIERRY wrote:
Et qu'est-ce qu'il dit au sujet d'un pointeur NULL ? (Il
faut bien qu'il dise quelque chose, quand même.)
Il ne mentionne pas que le stockage dans le pointeur soit
conditionnel, comme tu le disais, c'est tout.
Mais alors, qu'est-ce qu'il dit ? Que le comportement est
indéfini si tu lui passes NULL ? Ou quelque chose d'autre ?
La possibilité de passer NULL existe depuis que time() renvoie
une valeur. Même avant, d'ailleurs, mais avant, c'était un
comportement indéfini.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Et qu'est-ce qu'il dit au sujet d'un pointeur NULL ? (Il faut bien qu'il dise quelque chose, quand même.)
Il ne mentionne pas que le stockage dans le pointeur soit conditionnel, comme tu le disais, c'est tout.
Mais alors, qu'est-ce qu'il dit ? Que le comportement est indéfini si tu lui passes NULL ? Ou quelque chose d'autre ?
La possibilité de passer NULL existe depuis que time() renvoie une valeur. Même avant, d'ailleurs, mais avant, c'était un comportement indéfini.
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
kanze
Samuel Krempp wrote:
(16 May 2005 14:37,
Ce qui les diffère des autres messages, je crois, c'est qu'ils utilisent UTF-8, à la place de l'ISO 8859-1 ou 8859-15 qui est usuel ici, et qu'ils utilisent une forme de citation assez particulière dans l'en-tête. La ligne de sujet, par exmple :
ah d'accord. free bloque les posts UTF-8 (en tout cas vers fclc++). Quand j'ai essayé d'envoyer un message en UTF-8 news.free.fr le refuse.0 34
Techniquement, je crois que c'est interdit. Au moins dans le temps, il y avait une règle pour toute l'hièrarchie fr.* que seulement ISO 8859-1 était permis. Mais je n'ai pas régardé depuis longtemps (au moins dix ans), et il se peut que la situation a évolué ; je ne peux guère imaginer qu'on n'accepte pas le ISO 8859-15, par exemple.
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Samuel Krempp wrote:
kanze@gabi-soft.fr (16 May 2005 14:37,
Ce qui les diffère des autres messages, je crois, c'est
qu'ils utilisent UTF-8, à la place de l'ISO 8859-1 ou
8859-15 qui est usuel ici, et qu'ils utilisent une forme de
citation assez particulière dans l'en-tête. La ligne de
sujet, par exmple :
ah d'accord. free bloque les posts UTF-8 (en tout cas vers
fclc++). Quand j'ai essayé d'envoyer un message en UTF-8
news.free.fr le refuse.0 34
Techniquement, je crois que c'est interdit. Au moins dans le
temps, il y avait une règle pour toute l'hièrarchie fr.* que
seulement ISO 8859-1 était permis. Mais je n'ai pas régardé
depuis longtemps (au moins dix ans), et il se peut que la
situation a évolué ; je ne peux guère imaginer qu'on n'accepte
pas le ISO 8859-15, par exemple.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Ce qui les diffère des autres messages, je crois, c'est qu'ils utilisent UTF-8, à la place de l'ISO 8859-1 ou 8859-15 qui est usuel ici, et qu'ils utilisent une forme de citation assez particulière dans l'en-tête. La ligne de sujet, par exmple :
ah d'accord. free bloque les posts UTF-8 (en tout cas vers fclc++). Quand j'ai essayé d'envoyer un message en UTF-8 news.free.fr le refuse.0 34
Techniquement, je crois que c'est interdit. Au moins dans le temps, il y avait une règle pour toute l'hièrarchie fr.* que seulement ISO 8859-1 était permis. Mais je n'ai pas régardé depuis longtemps (au moins dix ans), et il se peut que la situation a évolué ; je ne peux guère imaginer qu'on n'accepte pas le ISO 8859-15, par exemple.
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34