subtilité de rand VG5000

Cette catégorie traite de développements récents pour nos vieilles machines, applications, jeux ou démos... Amis programmeurs, c'est ici que vous pourrez enfin devenir célèbres!

Modérateurs : Papy.G, fneck, Carl

joaopa
Messages : 500
Enregistré le : 14 sept. 2013 12:17

subtilité de rand VG5000

Message par joaopa » 05 mai 2020 20:32

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

__sam__
Messages : 5161
Enregistré le : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: subtilité de rand VG5000

Message par __sam__ » 05 mai 2020 21:02

Truc simple:

Code : Tout sélectionner

10 R=int(6*RND): iIF R=6 THEN 10
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

Code : Tout sélectionner

R=int(6*RND) MOD 6
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).
Modifié en dernier par __sam__ le 06 mai 2020 00:42, modifié 2 fois.
Samuel.
A500 Vampire V2+ ^8^, A1200(030@50mhz/fpu/64mb/cf 8go),
GVP530 (MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.

hlide
Messages : 1601
Enregistré le : 29 nov. 2017 10:23

Re: subtilité de rand VG5000

Message par hlide » 05 mai 2020 21:21

0 <= n*RND(1) <= n OU 0<= n*RND(1) < n ?

Avatar du membre
Carl
Modérateur
Messages : 11129
Enregistré le : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: subtilité de rand VG5000

Message par Carl » 05 mai 2020 22:26

rnd2.jpg
rnd2.jpg (55.78 Kio) Vu 329 fois
rnd.jpg
rnd.jpg (42.38 Kio) Vu 329 fois

joaopa
Messages : 500
Enregistré le : 14 sept. 2013 12:17

Re: subtilité de rand VG5000

Message par joaopa » 06 mai 2020 20:24

Carl, mon problème est dans la signification du mot <<compris>>

Markerror
Messages : 1585
Enregistré le : 31 oct. 2011 19:21
Localisation : Orléans
Contact :

Re: subtilité de rand VG5000

Message par Markerror » 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.

hlide
Messages : 1601
Enregistré le : 29 nov. 2017 10:23

Re: subtilité de rand VG5000

Message par hlide » 06 mai 2020 21:53

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.

Guillaume
Messages : 45
Enregistré le : 26 avr. 2020 15:24
Localisation : Nice

Re: subtilité de rand VG5000

Message par Guillaume » 06 mai 2020 22:29

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

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
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!

Guillaume
Messages : 45
Enregistré le : 26 avr. 2020 15:24
Localisation : Nice

Re: subtilité de rand VG5000

Message par Guillaume » 06 mai 2020 22:31

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.
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.

joaopa
Messages : 500
Enregistré le : 14 sept. 2013 12:17

Re: subtilité de rand VG5000

Message par joaopa » 06 mai 2020 22:37

@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)

Avatar du membre
Mokona
Messages : 515
Enregistré le : 17 déc. 2016 22:01
Localisation : Nord Est des Yvelines
Contact :

Re: subtilité de rand VG5000

Message par Mokona » 07 mai 2020 00:01

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)

Avatar du membre
Carl
Modérateur
Messages : 11129
Enregistré le : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: subtilité de rand VG5000

Message par Carl » 07 mai 2020 00:18

un peu plus de 900 000 tirages....pas de zéro...pas de 1
LPRINT > Minitab
stats.jpg
stats.jpg (72.15 Kio) Vu 240 fois
Carl

__sam__
Messages : 5161
Enregistré le : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: subtilité de rand VG5000

Message par __sam__ » 07 mai 2020 01:21

Guillaume a écrit :
06 mai 2020 22:29
Et des 0.999981 pour la borne haute.
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),
GVP530 (MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.

Avatar du membre
Xavier_
Messages : 150
Enregistré le : 24 avr. 2020 21:20

Re: subtilité de rand VG5000

Message par Xavier_ » 07 mai 2020 01:58

:shock:

Code : Tout sélectionner

 10 FOR i=1 TO 999999
 20 a=RND(1):IF a=0 THEN PRINT i:END
 30 NEXT I
Pareil pour Zéro !
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]

hlide
Messages : 1601
Enregistré le : 29 nov. 2017 10:23

Re: subtilité de rand VG5000

Message par hlide » 07 mai 2020 02:18

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.

Répondre