subtilité de rand VG5000
Modérateurs : Papy.G, fneck, Carl
subtilité de rand VG5000
Bonsoir à tous. Comment faîtes-vous en basic VG5000 pour tirer un nombre au hasard (probabilité uniforme....) compris entre 0 et n inclus. Par exemple, supposons qu'on veuille tirer un nombre entre 0 et 5
Si on fait un int(rnd(1)*5), alors la seule possibilité d'obtenir 5 est que rnd=1. Pas beaucoup de chance. Et encore je suppose que 1 peut être atteint. Ce n'est pas dit dans la documrntation du VG5000. C'est écrit <<compris>>. Mais n'est pas précisé au sens large ou au sens strict.
Si on fait int(rnd(1)*6), on peut tirer un 6.
Avez-vous une astuce pour éviter ça?
Je pose cette question car dans le lode-runner de Guillaume, on voit int(rnd(1)*3) pour le changement de mode des ennemis. Au final, je ne sais pas si il y a même probabilité pour 2 ou 3 changements de mode
Si on fait un int(rnd(1)*5), alors la seule possibilité d'obtenir 5 est que rnd=1. Pas beaucoup de chance. Et encore je suppose que 1 peut être atteint. Ce n'est pas dit dans la documrntation du VG5000. C'est écrit <<compris>>. Mais n'est pas précisé au sens large ou au sens strict.
Si on fait int(rnd(1)*6), on peut tirer un 6.
Avez-vous une astuce pour éviter ça?
Je pose cette question car dans le lode-runner de Guillaume, on voit int(rnd(1)*3) pour le changement de mode des ennemis. Au final, je ne sais pas si il y a même probabilité pour 2 ou 3 changements de mode
-
- Messages : 7964
- Inscription : 18 sept. 2010 12:08
- Localisation : Brest et parfois les Flandres
Re: subtilité de rand VG5000
Truc simple:
Le cas R=6 étant extrêmement rare, fait qu'on ne fait en pratique qu'un seul appel à RND.
Si on ne veut pas du test à 6, et qu'on n'accepte d'avoir 0 un tout petit peu plus souvent que les autres, on peut faire donne un entier entre 0 et 5 avec la proba 1/6 pour tous sauf le 0 qui apparaîtra un pouième plus souvent en fonction de la probabilité que RND donne 1, ce qui est négligeable (1/32767 probablement, ou même 0 si toujours RND(1)<1).
Code : Tout sélectionner
10 R=int(6*RND): iIF R=6 THEN 10
Si on ne veut pas du test à 6, et qu'on n'accepte d'avoir 0 un tout petit peu plus souvent que les autres, on peut faire
Code : Tout sélectionner
R=int(6*RND) MOD 6
Dernière modification par __sam__ le 06 mai 2020 00:42, modifié 2 fois.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Re: subtilité de rand VG5000
0 <= n*RND(1) <= n OU 0<= n*RND(1) < n ?
- Carl
- Modérateur
- Messages : 13290
- Inscription : 08 avr. 2007 13:21
- Localisation : http://www.doledujura.fr
- Contact :
Re: subtilité de rand VG5000
Carl, mon problème est dans la signification du mot <<compris>>
Re: subtilité de rand VG5000
Bon, si je comprends bien la question, tu as peur que un INT(RND(1))*3 puisse retourner quatre possibilités : 0 1 2 ou de façon extrêment faible 3.
Technique totalement primitive, un listing Basic pour répondre à cette question existentielle .
10 FOR i=1 TO 999999
20 a=RND(1):IF a=1 THEN PRINT i:END
30 NEXT I
Sachant que la routine RND est tout sauf aléatoire, le programme ne retourne aucun résultat. On peut en déduire vu la quantité de tests effectués que 1 n'est jamais atteint. Donc la documentation du VG5000 aurait dû dire entre 0 et 1 non compris.
Technique totalement primitive, un listing Basic pour répondre à cette question existentielle .
10 FOR i=1 TO 999999
20 a=RND(1):IF a=1 THEN PRINT i:END
30 NEXT I
Sachant que la routine RND est tout sauf aléatoire, le programme ne retourne aucun résultat. On peut en déduire vu la quantité de tests effectués que 1 n'est jamais atteint. Donc la documentation du VG5000 aurait dû dire entre 0 et 1 non compris.
Re: subtilité de rand VG5000
Et la nécessité de considérer que ce qui est dit dans les documents n'est pas parole évangélique. La raison pour laquelle j'avais un doute sur la borne, c'est qu'un nombre réelle encodé en fixe ou en float ne sait pas en général représenter une borne max entière. Par exemple, [0.00b, 1.11b] => [0.00d, 1.75d] : pour pouvoir tendre vers 2, il faudrait une infinité de bit après le point. Après je n'ai aucune idée de comment est représenté un nombre réel par le BASIC du VG5000.
Re: subtilité de rand VG5000
Salut,
En fait les nombres réels sont stockés avec 6 chiffres significatifs dans le VG5000.
Logiquement on pourrait penser que RND devrait sortir un nombre parmi 1 million possible.
Si le 1.00000 fait partie des possibilités, alors on ne devrait avoir qu'une chance sur un million pour qu'il sorte.
Mais je pense que quand la doc précise entre 0 et 1, c'est peut être en fait entre 0 et .999999
Pour tester on peut faire tourner un bout de code
et le stopper au bout d'un temps assez long pour afficher I (le nombre de test), L la valeur la plus basse (LOWER) et U (UPPER) la valeur la plus haute sortie.
Un nombre suffisant de fois serait de l'ordre de 100 millions de fois (une chance sur 100 que nous n'ayons pas obtenu un seul 1.00000 si c'est une possibilité).
Pour 100 millions de tests, il faut 9 jours à vitesse normale. 20 heures en mode boost sur l'émulateur. A condition que l'émulateur fasse bien les memes RND...
J'ai fait tourner deux fois pour environ 1 millions de tests à chaque fois. Et sur l'un des deux j'ai déjà obtenu un 0 pour la borne basse. Et des 0.999981 pour la borne haute.
Donc le 0 est une possibilité apparement. Le 1 je ne sais pas encore!
En fait les nombres réels sont stockés avec 6 chiffres significatifs dans le VG5000.
Logiquement on pourrait penser que RND devrait sortir un nombre parmi 1 million possible.
Si le 1.00000 fait partie des possibilités, alors on ne devrait avoir qu'une chance sur un million pour qu'il sorte.
Mais je pense que quand la doc précise entre 0 et 1, c'est peut être en fait entre 0 et .999999
Pour tester on peut faire tourner un bout de code
Code : Tout sélectionner
10 I=0:L=1:U=0
20 A=RND(1):I=I+1
30 IF L>A THEN L=A
40 IF A>U THEN U=A
60 GOTO 20
Un nombre suffisant de fois serait de l'ordre de 100 millions de fois (une chance sur 100 que nous n'ayons pas obtenu un seul 1.00000 si c'est une possibilité).
Pour 100 millions de tests, il faut 9 jours à vitesse normale. 20 heures en mode boost sur l'émulateur. A condition que l'émulateur fasse bien les memes RND...
J'ai fait tourner deux fois pour environ 1 millions de tests à chaque fois. Et sur l'un des deux j'ai déjà obtenu un 0 pour la borne basse. Et des 0.999981 pour la borne haute.
Donc le 0 est une possibilité apparement. Le 1 je ne sais pas encore!
Re: subtilité de rand VG5000
Je viens de lire ton message après avoir posté le mien (je l'avais en brouillon pendant mes petits essais sans voir que tu avais lancé un test). On arrive au même conclusion, pas de 1.Markerror a écrit : ↑06 mai 2020 21:14 Bon, si je comprends bien la question, tu as peur que un INT(RND(1))*3 puisse retourner quatre possibilités : 0 1 2 ou de façon extrêment faible 3.
Technique totalement primitive, un listing Basic pour répondre à cette question existentielle .
10 FOR i=1 TO 999999
20 a=RND(1):IF a=1 THEN PRINT i:END
30 NEXT I
Sachant que la routine RND est tout sauf aléatoire, le programme ne retourne aucun résultat. On peut en déduire vu la quantité de tests effectués que 1 n'est jamais atteint. Donc la documentation du VG5000 aurait dû dire entre 0 et 1 non compris.
Re: subtilité de rand VG5000
@Markerror. Merci de confirmer mes doutes.
@Guillaume: du coup, dans to programme Rode Lunner, qu'espérais-tu des intructions du type int(rnd(1)*5) (par exemple ligne 218)
@Guillaume: du coup, dans to programme Rode Lunner, qu'espérais-tu des intructions du type int(rnd(1)*5) (par exemple ligne 218)
- Mokona
- Messages : 1041
- Inscription : 17 déc. 2016 22:01
- Localisation : Nord Est des Yvelines
- Contact :
Re: subtilité de rand VG5000
Un émulateur sortira la même séquence. La suite du générateur est toujours la même et initialisée pareil.
C'est aussi strictement le même code si je compare avec un autre BASIC Microsoft (Le NASCOM). Donc d'autres docs de BASIC Microsoft sont peut-être plus précises.
D'après ce que je lis rapidement du code de génération (de $090d à $0970 dans la ROM), la séquence générée n'est prise que pour des chiffres après la virgule.
Et je vois aussi qu'il y a un cas non documenté (sur la doc VG5000 en tout cas), lorsque le paramètre est négatif (re-seed)
C'est aussi strictement le même code si je compare avec un autre BASIC Microsoft (Le NASCOM). Donc d'autres docs de BASIC Microsoft sont peut-être plus précises.
D'après ce que je lis rapidement du code de génération (de $090d à $0970 dans la ROM), la séquence générée n'est prise que pour des chiffres après la virgule.
Et je vois aussi qu'il y a un cas non documenté (sur la doc VG5000 en tout cas), lorsque le paramètre est négatif (re-seed)
- Carl
- Modérateur
- Messages : 13290
- Inscription : 08 avr. 2007 13:21
- Localisation : http://www.doledujura.fr
- Contact :
Re: subtilité de rand VG5000
un peu plus de 900 000 tirages....pas de zéro...pas de 1
LPRINT > Minitab Carl
LPRINT > Minitab Carl
-
- Messages : 7964
- Inscription : 18 sept. 2010 12:08
- Localisation : Brest et parfois les Flandres
Re: subtilité de rand VG5000
0.99998=65535 / 65536
Ce qui laisse penser que le générateur est sur 16 bits (classique sur les ordis d'époque) et ils obtiennent un nombre entre 0 et 1 (exclus) en divisant par 2^16 ce qui est direct dans la représentation des nombres flottant en mémoire. Bref la borne sup "1" n'est jamais atteinte à mon avis. Donc INT(RND(1)*6) doit retourner tous les nombres entre 0 et 5 avec la même proba si RND(1) est bien uniforme.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Re: subtilité de rand VG5000
Code : Tout sélectionner
10 FOR i=1 TO 999999
20 a=RND(1):IF a=0 THEN PRINT i:END
30 NEXT I
Donc, "compris entre 0 et 1"... ils sont dans les clous.
(exclus 0 et 1 pas compris dedans…)
[comme Carl il a déjà dit]
Re: subtilité de rand VG5000
Mouais, pour moi, l'expression "une valeur comprise entre X et Y" implique une inclusion des deux bornes. Les documentations ne sont pas exemptes d'approximation pouvant induire en erreur. Un "0 < RND(1) < 1" ou "RND(1) ∈ ]0, 1[" aurait été plus juste.