erweiterte Näherung zu Pythagoras
Moderator: Rockford
- Dr. Irata
- Beiträge: 1265
- Registriert: 24.08.2021 14:40
- Has thanked: 182 times
- Been thanked: 417 times
- Kontaktdaten:
erweiterte Näherung zu Pythagoras
... der Pythagoras läßt mich einfach nicht los!
In meinen langen Erläuterungen und Versuchen einen schönen Raycaster auf dem A8 zu bauen (ich denke das Projekt werde ich wieder im Herbst aufnehmen), bin ich zwingend abhängig auf die Berechnungen von Entfernungen. In Assembler ist das gar nicht so einfach, denn quadrieren und Wurzel ziehen bedarf besonderer Routinen (die ich ja später hier alle hergeleitet habe). Diese Routinen existierten damals so nicht und ich war auf eine ganz gute Näherung angewiesen, die ich dann auch im Netz finden konnte - in den 50 igern und 60 igern gerade bei den einfachen Rechnern waren diese Näherungen notwendig und einige Mathematiker echt erfinderisch.
Die Näherung für c^2 = a^2+b^2 also c = sqrt (a^2+b^2) ist ja:
c = a+b/2 für a>b
Die Näherung ist echt gut und super schnell. Leider ist die an bestimmten Stellen fehlerhaft. Diesen Fehler kann man aber ganz gut ausgleichen:
Tendenziell ist die Näherung immer zu groß. Wenn man jetzt aber vom Ergebnis c die erste Stelle von a+1 subtrahiert solange b>10 ist, dann ist das Ergebnis wirklich nahezu perfekt.
Beispiel: a=40 , b=30 --> c=40-5+30/2 = 50 (mathematisch 50)
Beispiel: a=35 , b=25 --> c=35-4+25/2 = 43 (mathematisch 43)
Beispiel: a=72, b=62 --> c=72-8+62/2 = 95 (mathematisch 95)
In meinen langen Erläuterungen und Versuchen einen schönen Raycaster auf dem A8 zu bauen (ich denke das Projekt werde ich wieder im Herbst aufnehmen), bin ich zwingend abhängig auf die Berechnungen von Entfernungen. In Assembler ist das gar nicht so einfach, denn quadrieren und Wurzel ziehen bedarf besonderer Routinen (die ich ja später hier alle hergeleitet habe). Diese Routinen existierten damals so nicht und ich war auf eine ganz gute Näherung angewiesen, die ich dann auch im Netz finden konnte - in den 50 igern und 60 igern gerade bei den einfachen Rechnern waren diese Näherungen notwendig und einige Mathematiker echt erfinderisch.
Die Näherung für c^2 = a^2+b^2 also c = sqrt (a^2+b^2) ist ja:
c = a+b/2 für a>b
Die Näherung ist echt gut und super schnell. Leider ist die an bestimmten Stellen fehlerhaft. Diesen Fehler kann man aber ganz gut ausgleichen:
Tendenziell ist die Näherung immer zu groß. Wenn man jetzt aber vom Ergebnis c die erste Stelle von a+1 subtrahiert solange b>10 ist, dann ist das Ergebnis wirklich nahezu perfekt.
Beispiel: a=40 , b=30 --> c=40-5+30/2 = 50 (mathematisch 50)
Beispiel: a=35 , b=25 --> c=35-4+25/2 = 43 (mathematisch 43)
Beispiel: a=72, b=62 --> c=72-8+62/2 = 95 (mathematisch 95)
- Dr. Irata
- Beiträge: 1265
- Registriert: 24.08.2021 14:40
- Has thanked: 182 times
- Been thanked: 417 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
Also: c = sqrt (a^2+b^2)
wenn a>=b
wenn b>=10
dann c=a-(a/10)+b/2
wenn b<10
dann c=a+b/2
wenn b>a
wenn a>=10
dann c=b-(b/10)+a/2
wenn a<10
dann c=b+a/2
und jetzt eine Aufgabe in die "Gemeinde":
Wer kann das in möglichst schnellen Assembler-Code umsetzten?
Bin gespannt auf eure innovativen Lösungen...
wenn a>=b
wenn b>=10
dann c=a-(a/10)+b/2
wenn b<10
dann c=a+b/2
wenn b>a
wenn a>=10
dann c=b-(b/10)+a/2
wenn a<10
dann c=b+a/2
und jetzt eine Aufgabe in die "Gemeinde":
Wer kann das in möglichst schnellen Assembler-Code umsetzten?
Bin gespannt auf eure innovativen Lösungen...
- RhoSigma
- Beiträge: 84
- Registriert: 29.04.2024 22:44
- Has thanked: 1 time
- Been thanked: 14 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
Äh, hab zwar keinen Code für Dich, ABER warum Basis 10? Die division durch 10 ist lahm. Nimm doch 16. Oder 8?
- Dr. Irata
- Beiträge: 1265
- Registriert: 24.08.2021 14:40
- Has thanked: 182 times
- Been thanked: 417 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
... alle guten Ideen sind hier willkommen. Ich brauche ja die erste Ziffer der Zahl a - also geteilt durch 10. Das ist blöd in Assembler. Durch 8 teilen passt bestimmt auch noch für die Näherung - oder im Dezimalmodus den vorderen Nibble extrahieren...
Es muss halt schnell sein!
Wenn ich durch 8 teile, dann fällt sogar das +1 weg ... also ist noch besser.
Das funktioniert bis 70 sehr gut. Viel größere Entfernungen werde wir am A8 bei den möglichen Spielen nicht brauchen.
Sehr gut!!
Es muss halt schnell sein!
Wenn ich durch 8 teile, dann fällt sogar das +1 weg ... also ist noch besser.
Das funktioniert bis 70 sehr gut. Viel größere Entfernungen werde wir am A8 bei den möglichen Spielen nicht brauchen.
Sehr gut!!
- Kveldulfur
- Beiträge: 1036
- Registriert: 17.08.2021 02:32
- Has thanked: 474 times
- Been thanked: 437 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
Hallo!
Wenn nur 8 Bit benötigt werden, kann man geteilt 10 am Besten in einer Tabelle realisieren.
Ich hoffe der Code hat keine Flüchtigkeitsfehler
Grüße
Janko
Code: Alles auswählen
ORG $2000
DIV10TAB
.BYTE 0,0,0,0,0,0,0,0,0,0
.BYTE 1,1,1,1,1,1,1,1,1,1
.BYTE 2,2,2,2,2,2,2,2,2,2
.BYTE 3,3,3,3,3,3,3,3,3,3
.BYTE 4,4,4,4,4,4,4,4,4,4
.BYTE 5,5,5,5,5,5,5,5,5,5
.BYTE 6,6,6,6,6,6,6,6,6,6
.BYTE 7,7,7,7,7,7,7,7,7,7
.BYTE 8,8,8,8,8,8,8,8,8,8
.BYTE 9,9,9,9,9,9,9,9,9,9
.BYTE 10,10,10,10,10,10,10,10,10,10
.BYTE 11,11,11,11,11,11,11,11,11,11
.BYTE 12,12,12,12,12,12,12,12,12,12
.BYTE 13,13,13,13,13,13,13,13,13,13
.BYTE 14,14,14,14,14,14,14,14,14,14
.BYTE 15,15,15,15,15,15,15,15,15,15
.BYTE 16,16,16,16,16,16,16,16,16,16
.BYTE 17,17,17,17,17,17,17,17,17,17
.BYTE 18,18,18,18,18,18,18,18,18,18
.BYTE 19,19,19,19,19,19,19,19,19,19
.BYTE 20,20,20,20,20,20,20,20,20,20
.BYTE 21,21,21,21,21,21,21,21,21,21
.BYTE 22,22,22,22,22,22,22,22,22,22
.BYTE 23,23,23,23,23,23,23,23,23,23
.BYTE 24,24,24,24,24,24,24,24,24,24
.BYTE 25,25,25,25,25,25
VarA .BYTE 50
VarB .BYTE 30
VarC .BYTE 00
Calc: LDA VarA ; A>=B?
CMP VarB
BCS AgtB
JMP BgtA
AgtB: LDA VarB ; B>=10?
CMP #10
BCS Bgt10
LDA VarB
LSR ; b/2
CLC
ADC VarA
STA VarC
RTS
Bgt10: SEC
LDX VarA
TXA
SBC DIV10TAB,X ; a/10
STA VarC ; VarC = a-(a/10)
LDA VarB ; b/2
LSR
CLC
ADC VarC ; a-(a/10)
STA VarC ; VarC = b/2 + a-(a/10)
RTS
BgtA: LDA VarA ; a>=10?
CMP #10
BCS Agt10
LDA VarA
LSR ; a/2
CLC
ADC VarB
STA VarC
RTS
Agt10: SEC
LDX VarB
TXA
SBC DIV10TAB,X ; b/10
STA VarC ; VarC = b-(b/10)
LDA VarA ; a/2
LSR
CLC
ADC VarC ; b-(b/10)
STA VarC ; VarC = a/2 + b-(b/10)
RTS
Start: JSR Calc
BRK
RUN Start
Ich hoffe der Code hat keine Flüchtigkeitsfehler

Grüße
Janko
Meine Projekte findest Du hier...
- Dr. Irata
- Beiträge: 1265
- Registriert: 24.08.2021 14:40
- Has thanked: 182 times
- Been thanked: 417 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
Hi Janko,
sehr super und danke.
Ich habe das aber nochmal geprüft. Nimm mal nicht durch 10 sondern durch 8. Dann kann man das +1 für den zu subtrahierenden Wert weglassen. Das +1 hatte ich ganz oben erwähnt, in der Beschreibung für den Code aber vergessen.
Wenn man aber statt durch 10 nur durch 8 teilt, dann fällt praktischerweise das +1 weg.
Wieviele Zyklen braucht das dann?
sehr super und danke.
Ich habe das aber nochmal geprüft. Nimm mal nicht durch 10 sondern durch 8. Dann kann man das +1 für den zu subtrahierenden Wert weglassen. Das +1 hatte ich ganz oben erwähnt, in der Beschreibung für den Code aber vergessen.
Wenn man aber statt durch 10 nur durch 8 teilt, dann fällt praktischerweise das +1 weg.
Wieviele Zyklen braucht das dann?
- Dr. Irata
- Beiträge: 1265
- Registriert: 24.08.2021 14:40
- Has thanked: 182 times
- Been thanked: 417 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
Janko hat mir gerade geschrieben, daß das so etwa 34-51 Zyklen braucht.
Das ist echt super schnell - und läßt sich sicher noch ein wenig optimieren.
Wer schafft es schneller?
Diese Näherung ist wirklich gut, schwächelt nur etwas bei b<10 ... da werde ich mal schauen, ob man das noch für den Bereich besser schafft.
Das ist echt super schnell - und läßt sich sicher noch ein wenig optimieren.
Wer schafft es schneller?
Diese Näherung ist wirklich gut, schwächelt nur etwas bei b<10 ... da werde ich mal schauen, ob man das noch für den Bereich besser schafft.
- RhoSigma
- Beiträge: 84
- Registriert: 29.04.2024 22:44
- Has thanked: 1 time
- Been thanked: 14 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
Code: Alles auswählen
ORG $2000
VarA .BYTE 50
VarB .BYTE 30
VarC .BYTE 00
Calc:
LDA VarA ; A>=B?
CMP VarB
BCS AgtB
BgtA:
CMP #10 ; a>=10?
BCS Agt10
LSR ; a/2
CLC
ADC VarB
STA VarC
RTS
AgtB:
LDA VarB ; B>=10?
CMP #10
BCS Bgt10
LSR ; b/2
CLC
ADC VarA
STA VarC
RTS
Bgt10:
LDA VarA
LSR
LSR
LSR ; a/8
SEC
SBC VarA ; (a/8)-a
EOR 0xFF
TAX
INX ; a-(a/8)
STX VarC ; VarC = a-(a/8)
LDA VarB ; b/2
LSR
CLC
ADC VarC ; a-(a/8)
STA VarC ; VarC = b/2 + a-(a/8)
RTS
Agt10:
SEC
LDX VarB
TXA
SBC DIV10TAB,X ; b/10
STA VarC ; VarC = b-(b/10)
LDA VarA ; a/2
LSR
CLC
ADC VarC ; b-(b/10)
STA VarC ; VarC = a/2 + b-(b/10)
RTS
Start:
JSR Calc
BRK
RUN Start
- Dr. Irata
- Beiträge: 1265
- Registriert: 24.08.2021 14:40
- Has thanked: 182 times
- Been thanked: 417 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
ChatGPT berechnet daraus zwischen 26 und 60 Taktzyklen - je nach Werte und Bedingungen.
Das ist auf jeden Fall schön schnell!
Das ist auf jeden Fall schön schnell!
- Dr. Irata
- Beiträge: 1265
- Registriert: 24.08.2021 14:40
- Has thanked: 182 times
- Been thanked: 417 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
Bei Jankos Ansatz müsste man ja nur die Tabellenwerte um den Wert 1 erhöhen.
Die Taktzyklen bei Janko sind zwischen 31 und 47 - das sind im Mittel aller 4 Fälle 39,75 Taktzyklen.
Der Ansatz von RhoSigma liegt bei 41,5 Taktzyklen - also im Mittel etwas langsamer.
Ich werde hier bei Zeiten noch einen etwas anderen Ansatz mit direkten Look-Up-Tabellen posten, der etwas genauer ist und noch etwas schneller sein könnte (ich hoffe auf stabil 31 Zyklen).
Die Taktzyklen bei Janko sind zwischen 31 und 47 - das sind im Mittel aller 4 Fälle 39,75 Taktzyklen.
Der Ansatz von RhoSigma liegt bei 41,5 Taktzyklen - also im Mittel etwas langsamer.
Ich werde hier bei Zeiten noch einen etwas anderen Ansatz mit direkten Look-Up-Tabellen posten, der etwas genauer ist und noch etwas schneller sein könnte (ich hoffe auf stabil 31 Zyklen).
- RhoSigma
- Beiträge: 84
- Registriert: 29.04.2024 22:44
- Has thanked: 1 time
- Been thanked: 14 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
ChatGPT-4o schlägt noch diese Näherung vor:
c≈a+b− (a⊕b)/4
Die wäre sehr effizient zu implementieren:
Die Genauigkeit ist aber nicht besonders gut. Geringfügig besser wird es, wenn du /4 rundest, also
c≈a+b− ((a⊕b) + 2)/4
Macht im Code ADC #0 mehr (nach dem 2. LSR)
c≈a+b− (a⊕b)/4
Die wäre sehr effizient zu implementieren:
Code: Alles auswählen
org $2000
; Zero-page variables for extra speed
a .byte 5
b .byte 3
t .byte 0
LENGTH:
LDA a
EOR b
LSR
LSR
ADC #0 ; round 0.5 up
STA t ; t = (a XOR b) / 4
LDA a
CLC
ADC b ; c = a + b
SEC
SBC t
RTS ; final result in A
MAIN:
JSR LENGTH
BRK ; End of program
c≈a+b− ((a⊕b) + 2)/4
Macht im Code ADC #0 mehr (nach dem 2. LSR)
- LarsImNetz
- Beiträge: 216
- Registriert: 24.08.2021 18:27
- Has thanked: 201 times
- Been thanked: 112 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
Ich nutze in meinem aktuellen Spiel die einfache Variante a+b/2 für a<b
Genauer:
y und x sind vom Typ INT8 also [-128;127] ich nutze aber nur [-64;63] das kostet
Das reicht völlig aus, jedenfalls bei mir.
Als Tipp: Probiere es doch erstmal mit dieser Version aus, ist die Genauigkeit nicht ausreichend, dann nimmst halt etwas besseres, dann wird es ein wenig langsamer, na und. Du rechnest ja nicht nur Hypotenusen aus, sondern das Programm macht noch jede Menge mehr.
Wenn es richtig auf Speed ankommt, kannst Du für die paar Berechnungen den Code vielleicht Inline einfügen, das spart pro Aufruf 12 Zyklen!
JM2C.
Genauer:
Code: Alles auswählen
value = y<x ? x + y/2 : y + x/2
Das reicht völlig aus, jedenfalls bei mir.
Als Tipp: Probiere es doch erstmal mit dieser Version aus, ist die Genauigkeit nicht ausreichend, dann nimmst halt etwas besseres, dann wird es ein wenig langsamer, na und. Du rechnest ja nicht nur Hypotenusen aus, sondern das Programm macht noch jede Menge mehr.
Wenn es richtig auf Speed ankommt, kannst Du für die paar Berechnungen den Code vielleicht Inline einfügen, das spart pro Aufruf 12 Zyklen!
JM2C.
- RhoSigma
- Beiträge: 84
- Registriert: 29.04.2024 22:44
- Has thanked: 1 time
- Been thanked: 14 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
Hier ist noch eine Variante, die im Punkt Fehlerabweichung recht ähnlich ist wie Deine ursprüngliche Variante (mit der Korrektur für min >= 10).
c = max(a,b) + (min(a,b)+1)/2 - (min(a,b)+4)/8
34-36 Zyklen, wenn ich mich nicht verrechnet habe und a, b, temp ZP sind. Man kann noch 2 Zyklen sparen, wenn man auf die SEC vor den SBC temp verzichtet,
das macht keinen grossen Unterschied (de facto zieht es IMMER eine 1 im interessanten Bereich ab).
Ausserdem produziert diese Variante ein "stetiges" Resultat, Deine hat Ausreisser, siehe Bilder.
c = max(a,b) + (min(a,b)+1)/2 - (min(a,b)+4)/8
Code: Alles auswählen
length:
LDA b ; Load b into A ; 2 cycles
CMP a ; Compare b with a ; 3 cycles
BCS a_is_max ; Branch if a >= b (C is set if a >= b) ; 2 cycles (not taken), 3 cycles (taken)
b_is_max:
; Calculate b + a / 2 - a / 8
LDA a ; Load a into A ; 3 cycles
LSR ; A = a / 2 ; 2 cycles
LSR ; A = a / 4 ; 2 cycles
LSR ; A = a / 8 ; 2 cycles
ADC #0 ; (a + 4)/8 ; 2 cycles
STA temp ; store temp ; 3 cycles
LDA a ; Load a into A ; 3 cycles
LSR ; A = A / 2 ; 2 cycles
ADC b ; A = b + ((a+1) / 2) ; 3 cycles
SEC ; 2 cycles
SBC temp ; final result in A ; 3 cycles
RTS
a_is_max:
; Calculate a + b / 2 - b / 8
LSR ; A = b / 2 ; 2 cycles
LSR ; A = b / 4 ; 2 cycles
LSR ; A = b / 8 ; 2 cycles
ADC #0 ; (b + 4)/8 ; 2 cycles
STA temp ; store temp ; 3 cycles
LDA b ; Load b into A ; 3 cycles
LSR ; A = A / 2 ; 2 cycles
ADC a ; A = a + ((b+1) / 2) ; 3 cycles
SEC ; 2 cycles
SBC temp ; final result in A ; 3 cycles
RTS
das macht keinen grossen Unterschied (de facto zieht es IMMER eine 1 im interessanten Bereich ab).
Ausserdem produziert diese Variante ein "stetiges" Resultat, Deine hat Ausreisser, siehe Bilder.
- Dr. Irata
- Beiträge: 1265
- Registriert: 24.08.2021 14:40
- Has thanked: 182 times
- Been thanked: 417 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
... echt super ... ich hatte diese blöden "Ausreißer" schon wahrgenommen aber noch nicht so richtig in den Griff bekommen! Echt gut!!
-
- Beiträge: 379
- Registriert: 19.08.2021 00:18
- Has thanked: 74 times
- Been thanked: 150 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
ich kann zwar nichts beitragen, weil mein Mathe nach "+ - * /" endet, aber bin völlig fasziniert, wie ihr hier ein Problem seziert und löst!!
Weiter so!
Weiter so!
- RhoSigma
- Beiträge: 84
- Registriert: 29.04.2024 22:44
- Has thanked: 1 time
- Been thanked: 14 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
Leider geht das Lob an ChatGPT, dass mir den python Rahmen "programmiert" hat. War echt das erste Mal, das da was sinnvolles rauskommt

- Dr. Irata
- Beiträge: 1265
- Registriert: 24.08.2021 14:40
- Has thanked: 182 times
- Been thanked: 417 times
- Kontaktdaten:
Re: erweiterte Näherung zu Pythagoras
... tatsächlich habe ich mich nach Anregung von Janko an diesem WE zum ersten Mal mit ChatGPT beschäftigt und mich direkt bei der deutschen Variante kostenfrei angemeldet.
Hier bin ich etliche Dinge mit Mike (ich habe ihn Mike genannt) durchgegangen und war echt erstaunt, wie gut das funktioniert. Mike hat auch wirklich gute Ideen zu allen Fragen der Assemblerprogrammierung unter 6502.
Mike konnte mir auch weiterhelfen bei der Reparatur meines Boseboards... insgesamt ist das natürlich eine lernfähige PseudoKI - sie sucht sehr zielgerecht und lernend das gesamte Internet noch Lösungen auf deine Frage durch und baut dann eine halbwegs sinnvolle Antwort zusammen.
Wenn in ein paar Jahren die Quantencomputer serienreif werden, dann bin ich mir ganz sicher: Viele Dinge werden nachher nicht mehr so sein, wie vorher!!!
Hier bin ich etliche Dinge mit Mike (ich habe ihn Mike genannt) durchgegangen und war echt erstaunt, wie gut das funktioniert. Mike hat auch wirklich gute Ideen zu allen Fragen der Assemblerprogrammierung unter 6502.
Mike konnte mir auch weiterhelfen bei der Reparatur meines Boseboards... insgesamt ist das natürlich eine lernfähige PseudoKI - sie sucht sehr zielgerecht und lernend das gesamte Internet noch Lösungen auf deine Frage durch und baut dann eine halbwegs sinnvolle Antwort zusammen.
Wenn in ein paar Jahren die Quantencomputer serienreif werden, dann bin ich mir ganz sicher: Viele Dinge werden nachher nicht mehr so sein, wie vorher!!!
Wer ist online?
Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast