Seite 1 von 2
Zufallszahlen in Assembler
Verfasst: 21.09.2022 16:10
von Olix
Wie erzeuge ich auf dem Atari in Assembler Zufallszahlen für einen bestimmten Zahlenbereich?
Konkret brauche ich eine Routine, die eine Zufallszahl zwischen 0-5 und zwischen 0-23 erzeugt.
Re: Zufallszahlen in Assembler
Verfasst: 21.09.2022 16:48
von pps
0 - 5:
0-23:
Mehr sollte dazu nicht nötig sein. Im Akku steht dann die gewünschte Zufallszahl.
Re: Zufallszahlen in Assembler
Verfasst: 21.09.2022 17:38
von Dr. Irata
... oder man schreibt besser gleich
lda random
Re: Zufallszahlen in Assembler
Verfasst: 21.09.2022 17:57
von Kveldulfur
Hallo!
Wirklich nur AND #5 ?
Damit dürfte als Ergebnis nur 0,1,4 und 5 herauskommen, oder?
Hab es jetzt nicht getestet aber 5 sind %0101 und nur diese Kombinationen wären erlaubt:
%0000 = 0
%0001 = 1
%0100 = 4
%0101 = 5
Grüße
Janko
Re: Zufallszahlen in Assembler
Verfasst: 21.09.2022 18:21
von Olix
... also so einfach ist es dann doch nicht.
Das mit dem AND funktioniert nur mit mehfachen von zwei.
Also z.B. wenn ich eine Zufallszahl zw. 0-7 suchen , dann
LDA RANDOM
AND #%00000111
oder bei 0-127
AND #%01111111
aber bei meinem 0-5 und 0-23 klappt das so einfach nicht.
Weitere Vorschläge?
Re: Zufallszahlen in Assembler
Verfasst: 21.09.2022 18:34
von pps
Ja. Da habe ich zu schnell geschossen. War noch nicht ganz wach
Aber mit einem CMP #6 und BCC oder BCS sollte es dann gehen
Re: Zufallszahlen in Assembler
Verfasst: 21.09.2022 18:45
von Olix
Ja, das war mein erster Gedanke:
Code: Alles auswählen
Loop:
LDA RANDOM
AND #%00000111
CMP #6
BCC ....
JMP Loop
... Zahl im Akku 0-5
Einfach die Schleife so lange laufen lassen bis es passt.
Aber das muss doch auch eleganter gehen, oder?
Re: Zufallszahlen in Assembler
Verfasst: 21.09.2022 22:38
von Dr. Irata
also ich mache es in MADS so:
in zufall steht jetzt eine Zahl zwischen 0 und 5
Re: Zufallszahlen in Assembler
Verfasst: 21.09.2022 23:53
von Irgendwer
Ein interessantes Thema mit mehr Tiefe als man denkt:
- Wie kann ich eine bestimmte (evt. sogar gleiche) Laufzeit garantieren? (Also keine Schleife, die arbeitet, bis der Wert 'passt')
- Wenn ich Werte ignoriere, ist die Verteilung noch fair? (Abgesehen davon, dass RANDOM auch nicht gleichverteilt ist, verschlechtert sich die Fairness weiter.)
Hier mal ein andere Herangehensweise:
Code: Alles auswählen
; Zufallszahl von 0-5 im Akku
ldx #0
ldy #6
loop:
lda RANDOM
asl
bcc next
inx
next:
dey
bne loop
txa
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 05:44
von Dr. Irata
... ich hätte da auch noch einen Ansätze:
Code: Alles auswählen
sec
lda random
sbc #95
ror
clc
ror
clc
ror
clc
ror
clc
ror
im Akkumulator steht jetzt eine Zahl zwischen 0 und 5!
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 07:16
von Dr. Irata
ich stelle nochmal eine weitere Alternative zur Diskussion, wo die Zahlen besser verteilt sind - ist allerdings auch eine Näherung, wo die 0 etwas öfters kommt als zB die 5 … will man es gleich verteilt haben, kann man mit einer Tabelle arbeiten und die Werte von Random (0-255) auf (0-5) gleichmäßig verteilen!
Hier jetzt aber die Näherung:
Code: Alles auswählen
lda random
ror
clc
ror
clc
ror
clc
ror
clc
inc
inc
ror
inc
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 08:34
von Olix
... mal ne Verständnis Frage:
wenn du vor dem ROL Befehl ein CLC setzt, könntest du nicht einfach statt der beiden Befehle nur ein LSR verwenden? Oder stehe ich da irgendwie auf dem Schlauch?
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 08:55
von Olix
Irgendwer hat geschrieben: ↑21.09.2022 23:53
Hier mal ein andere Herangehensweise:
Code: Alles auswählen
; Zufallszahl von 0-5 im Akku
ldx #0
ldy #6
loop:
lda RANDOM
asl
bcc next
inx
next:
dey
bne loop
txa
... finde ich eine "sympathische " Herangehensweise, zumindest für kleinere Zufallszahlen Bereiche.
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 08:57
von Kveldulfur
Die Methode von Irgendwer gefällt mir sehr gut, jedoch je größer der Zufallszahlenbereich ist, desto länger wird die Ermittlung dauern.
Bei Peter weiß ich nicht, ob ich es richtig sehe aber "INC" ohne Parameter? Geht dass?
Grüße
Janko
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 08:59
von Olix
Prodehl hat geschrieben: ↑22.09.2022 07:16
... und die Werte von Random (0-255) auf (0-5)
gleichmäßig verteilen!
... ja aber das Problem ist doch gerade, dass sich 256 nicht auf 6 gleichmäßige verteilen lässt

Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 09:22
von Dr. Irata
... ich muss zugeben, daß ich heute um ca. 4.45 aufgewacht bin und dann im Bett (im Kopf) mir diese Näherung ausgedacht habe und dann aufgestanden bin und es gepostet habe...
inc geht nicht so einfach, hier müsste man wohl über die Register gehen...
Die Näherung ist auch nicht besonders gut, da die 0 viel zu oft kommt!
Im Grunde ist die Lösung ja mathematisch ganz einfach:
Ich habe (hoffentlich) gleich verteilte Zufallszahlen zwischen 0 und 256 - will daraus Zahlen von 0-5 machen.
Also teile ich die Zufallszahlen durch 43 und schneide die Nachkommastellen ab - thats it!
In Basic wäre das so zu lösen (ich definiere jetzt mal Random als eine Zufallszahl zwischen 0-255, was ja bekanntlich in real anders in Basic ist):
zufall= int(Random/43)
In Zufall steht jetzt eine gleichverteilte Zufallszahl von 0-5
Das Problem ist nun allerdings: Wie teile in in Assembler eine Zahl durch 43?
Das geht, ist aber echt aufwendig.
Es muss also eine möglichst gut Näherung her mit folgenden Kriterien:
1. Keine Schleife
2. Die Näherung muss eine Zufallszahl durch Random generiert zwischen 0 und ca. 43 auf 0 setzen (ab ca. 43 muss dann 1 rauskommen)
3. Die gleiche Näherung muss eine Zufallszahl durch Random generiert zwischen ca. 212 und 255 auf 5 setzen.
4. Alle Bereiche dazwischen sind wohl zunächst gar nicht wichtig, denn wenn man 2. und 3. gut hinbekommt, dann werden sich die Bereiche dazwischen auch harmonisch verteilen!
Los gehts.... wer bekommt diese Näherung ohne Schleife am besten mit möglichst wenig Zyklen hin?
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 09:24
von Dr. Irata
@Olix
Mit einer Tabelle oder mit z.B. #if ... #end Abfragen bekomme ich das super verteilt von 0-255 auf 0-5 hin!
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 09:40
von Olix
Prodehl hat geschrieben: ↑22.09.2022 09:24
Mit einer Tabelle oder mit z.B. #if ... #end Abfragen bekomme ich das super verteilt von 0-255 auf 0-5 hin!
... Aber nicht zu gleichen Teilen.
Von den 256 Wehren kannst du 252 (42*6) in einer Tabelle verteilen. Bleiben noch 4. Dann muss ich mich für 4 Zahlen entscheiden, die etwas häufiger vorkommen als die übrigen 2
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 09:45
von Dr. Irata
... das stimmt zwar, ist aber irrelevant, da die Wahrscheinlichkeiten für das Auftreten der Zahlen nahezu identisch ist nach Umformung. Der kleine "Rundungsfehler" geht in der normalen Ungleichverteilung der Zahlen durch den vom Rechner ebenfalls nicht gleichförmig erzeugten Zufallszahlen unter.
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 09:50
von Dr. Irata
wenn ich z.B. die 4 mittleren Zahlen etwas häufiger anwähle bekomme ich folgende Verteilung:
die 0 und die 5 kommen in 16,42% der Fälle
die 1,2,3,4 kommen jeweils in 16,79% der Fälle
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 10:01
von Olix
... Also gut, du hast mich überzeugt.
Wenn man sich dir Prozentzahlen anschaut, dann wird man in den meisten Fällen mit dieser Unschärfe gut leben können.
... auch wenn sich ein Spielkasino sicherlich nicht damit zufrieden geben würde.

Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 10:05
von Irgendwer
Olix hat geschrieben: ↑22.09.2022 08:55
... finde ich eine "sympathische " Herangehensweise, zumindest für kleinere Zufallszahlen Bereiche.
Es geht noch ein Tickchen "sympathischer" mit konstanterer Laufzeit:
Code: Alles auswählen
; Zufallszahl von 0-5 im Akku
ldy #6
lda random
sta tmp
lda #0
loop:
asl tmp
adc #0
dey
bne loop
Werden die Zahlen größer, kann man eine Kombination von direkten Interpretationen und/oder gezählten Bits nehmen.
( z.B. 23 = random & 15 + random & 7 + 1 gezähltes random bit)
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 10:21
von Dr. Irata
... und wie machst du dann Zufallszahlen z.B. zwischen 11 und 43 ?
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 10:26
von Irgendwer
11 + random & 31 + ein gezähltes random bit
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 10:34
von Olix
... geht sogar etwas kürzer und schneller:
Code: Alles auswählen
; Zufallszahl von 0-5 im Akku
ldy #6
ldx #0
lda random
loop:
asl
bcc nocarry
inx
nocarry:
dey
bne loop
Deine Routine ist 16 Byte lang (Temp-Variable in Zero-Page) und dauert immer 69 Zyklen
Meine Routine ist 2 Bytes kürzer (14 Byte) und dauert zwischen 59 und 64 Zyklen (Je nachdem wie oft ein Carry auftaucht)
Deine Routine wäre also von Vorteil, falls eine garantierte Laufzeit gewünscht wird.
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 10:35
von Dr. Irata
ok, sieht wirklich sehr eloquent aus und ist bestimmt auch relativ schnell!
Da ich kein Profi bin und noch von damals aus der BASIC Ecke komme, liebe ich natürlich die schönen #if Anweisungen. Daher kommt mir auch MADS voll zugute.
Ich würde es ohne groß nachdenken zu müssen so machen (ähnlich wie oben)
Code: Alles auswählen
zufall .by 00
random = 53770
@ mva random zufall
#if .byte zufall<#11 .and .byte zufall>#43
jmp @-
#end
... schlank und übersichtlich

Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 10:42
von Olix
.... und falls die Zeit und vor allem mögliche Laufzeitschwankungen keine Rolle spielen (z.B. bei der Verteilung von zufälligen Gegenständen am Anfang eines Spieles o.ä.) aber dafür auf die Programmlänge geachtet wird, dann doch einfach die If... Then Variante:
Code: Alles auswählen
Loop:
LDA RANDOM
AND #%00000111
CMP #6
BCS Loop
... Zahl im Akku 0-5
9 Byte lang / mindestens 10 Zyklen (+ weitere 11 pro Durchlauf)
hat sich gerade mit dem letzten Beitrag Überschnitten, ist aber im Grunde vermutlich das Selbe, das der MADS beim Assemblieren dann erzeugt (bei Zahlen 0-5)
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 10:54
von Dr. Irata
hmmm - ich habe jetzt mal beide Routinen getestet und beide stimmen nicht genau!
Bei der Routine von irgendwer kommen bei mir Zahlen von 0-6 raus und bei der Routine von Olix kommen nur 0,1 korrekt, ansonsten kommen Sonderzeichen...
Beim ersten Fall muss man ldy#5 nehmen, dann passt es...
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 10:55
von Irgendwer
Olix hat geschrieben: ↑22.09.2022 10:34
... geht sogar etwas kürzer und schneller:
Meine Routine ist 2 Bytes kürzer (14 Byte) und dauert zwischen 59 und 64 Zyklen (Je nachdem wie oft ein Carry auftaucht)
Falls der Kommentar im Code noch stimmen soll, musst Du noch ein Byte ("txa") hinzufügen...

Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 10:59
von Irgendwer
Irgendwer hat geschrieben: ↑22.09.2022 10:05
Olix hat geschrieben: ↑22.09.2022 08:55
... finde ich eine "sympathische " Herangehensweise, zumindest für kleinere Zufallszahlen Bereiche.
Es geht noch ein Tickchen "sympathischer" mit konstanterer Laufzeit:
Code: Alles auswählen
; Zufallszahl von 0-5 im Akku
ldy #5
lda random
sta tmp
lda #0
loop:
asl tmp
adc #0
dey
bne loop
Werden die Zahlen größer, kann man eine Kombination von direkten Interpretationen und/oder gezählten Bits nehmen.
( z.B. 23 = random & 15 + random & 7 + 1 gezähltes random bit)
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 11:00
von Dr. Irata
stimmt - mit txa geht auch der Code von Olix - hier bekomme ich aber Werte von 0-7
bei Olix Code braucht es ldy#4
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 11:01
von Irgendwer
Prodehl hat geschrieben: ↑22.09.2022 10:54
Beim ersten Fall muss man ldy#5 nehmen, dann passt es...
Sehr gut! Danke. Theoretisch hat es funktioniert - nur praktisch nicht!

Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 11:01
von Dr. Irata
ja - kleiner Fehler.. aber der Code ist echt super!!
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 11:29
von Dr. Irata
... da ich heute ja gar nichts anderes zu tun habe (Ironie

) - habe ich das jetzt mal mehrfach getestet und muss nun leider "Euren" Ansatz komplett verwerfen!!
Bei meinem Ansatz mit der #if -Lösung kommt man für die Zahlen 0-5 auf eine recht gute prozentuale Verteilung von ca. 12% - 20%
Bei Eurem Ansatz komme ich relativ stabil auf Verteilungswerte von knapp 3% bis 33% wobei hier die Zahlen 5 und 0 auffällig unterdurchschnittlich repräsentiert werden - irgendwas stimmt hier nicht. Das sieht fast schon aus wie eine Gaußsche Normalverteilung...
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 11:40
von Olix

... ich muss zu meiner Schande gestehen, dass ich meinen zweiten Ansatz gar nicht getestet habe, sondern nur hingeschrieben.
Aber der ganz Einfache (Die If ... Then Schleife) hat jetzt den Weg in mein Programm gefunden und funktioniert.

Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 11:41
von Dr. Irata
.. hast du in deinem Assembler auch eine If - Option??
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 11:58
von Olix
ne, so tolle moderne Dinge kann meiner natürlich nicht, ich programmiere doch noch total Oldschool auf dem Atari um mich ein wenig zu quälen
Ich nenne meine Programm-Variante nur so, weil sie ja das Selbe macht:
Code: Alles auswählen
ITSL1: LDA RANDOM ; ZUFALLSZAHL LADEN
AND #%00000111 ; NUR 0-7
CMP #6
BCS ITSL1 ; NUR 0-5
sollte im Ergebnis ja genau deiner IF...Then Lösung entsprechen. Nur mit dem Unterschied, dass ich durch die AND Funktion den Zufallsbereich von 256 schon mal vorab auf 8 mögliche Werte verringere.
oder?
... du kannst das ja mal spaßerhalber compilieren lassen und dann den Assemblercode mit meinerm vergleichen....
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 12:02
von LarsImNetz
Moin,
viele coole Routinen, aber irgendwie, ich weiß noch nicht.
Eigentlich wollen wir RANDOM mod 5 haben, also als Ergebnis etwas zwischen 0 und 4.
Code: Alles auswählen
lda #5
sta modvalue
lda RANDOM
and #$07 ; hier etwas grob vorfiltern, damit die Schleife nicht zu häufig rotiert.
sec
modulus
sbc modvalue
bcs modulus
adc modvalue
Im Akku steht jetzt ein Wert zwischen 0 und 4.
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 12:04
von LarsImNetz
ok, RANDOM mod 6 und RANDOM mod 24
Aber die richtigen Werte in den Code einbinden kann jeder selbst.
Re: Zufallszahlen in Assembler
Verfasst: 22.09.2022 12:53
von Dr. Irata
Hi Lars,
schöne Routine, aber die läuft nur von 0-7
Die Zufallszahl 8 kann man schon nicht mehr generieren...
schade
