Division
Die Division erfordert mehrerer Fallunterscheidungen. Die offensichtlichste ist die Überprüfung, ob der Divisor (b) 0 ist, denn dies ist keine gültige Operation. Aus diesem Grund liefert diese Berechnung in einer separaten Speicherzelle (hier: error) einen von Null abweichenden Wert, wenn die Berechnung fehlgeschlagen ist.
Ohne diese Fallüberprüfung, würde die JASm Maschine bei der Berechnung des Quotienten in eine Endlosschleife laufen.
Die nächste Überprüfung ist dahingehend, ob der Dividend (a) gleich null ist. In diesem Fall können die weiteren Rechenschritte ausbleiben und das Ergebnis (0) sogleich festgeschrieben werden.
Nach diesen beiden Fällen, wird eine Überprüfung der Vorzeichen von a und b erforderlich. Der Fall, dass a oder b gleich null ist, kann an dieser Stelle schon ausgeschlossen werden. Sind die Vorzeichen gleich, ist das Ergebnis positiv, andernfalls Negativ.
Für einen möglichen Rest bei der Division, ist das Vorzeichen des Dividenden (a) relevant, insbesondere aus dem Grund, weil von a und b nun die Vorzeichen entfernt werden (a = |a| und b = |b|).
@Start -3 REM Parameter und Variablen a: 10 # Dividend, später Rest b: 3 # Divisor c: 0 # Quotient error: 0 # Fehlermarker tmp: 0 # Puffer zur Vorzeichenkonvertierung minusc: 0 # Puffer für Ergebnisvorzeichen minusa: 0 # Puffer für Restvorzeichen mina: 0 # a negiert minb: 0 # b negiert one: -1 # Konstante -1 minone: 1 # Konstante +1 REM Programmbeginn Start: # c = a / b, Rest bleibt in a SUB @mina @a # mina = -a SUB @minb @b # minb = -b REM Prüfung, ob b = 0 JA @b @vorzTest JA @minb @vorzTest SUB @error @one # Fehler (Division durch 0) SUB 0 0 # Programmausstieg error = 1 REM Fallunterscheidung bzgl. Gleichheit der Vorzeichen von a und b vorzTest: JA @a @aistpos # a > 0 JA @mina @aistneg # a < 0 SUB 0 0 # a ist 0, daher kann hier bereits die # Berechnung mit c = 0 enden aistneg: SUB @minusa @one # merken, dass das Vorzeichen des Rests # gedreht werden muss SUB @a @a # Vorzeichen von a entfernen SUB @a @mina JA @b @vorzUngleich # a < 0 && b > 0 SUB @b @b # Vorzeichen von b entfernen SUB @b @minb JA 0 @vorzGleich aistpos: JA @b @vorzGleich SUB @b @b # Vorzeichen von b entfernen SUB @b @minb vorzUngleich: SUB @minusc @one # merken, dass das Vorzeichen gedreht # werden muss REM Beginn der tatsächliche Division REM Ab hier gilt: REM a > 0 && b > 0 REM minus = 1, wenn das Vorzeichen gedreht werden muss REM c = 0 vorzGleich: loop: JA @a @subb # while a>0 do @subb SUB @mina @mina SUB @mina @a JA @mina @korrektur JA 0 @vorzKorr korrektur: SUB @minb @minb SUB @minb @b SUB @a @minb # um den Rest zu ermitteln, muss auch der # Wert von a um ein b korrigiert werden SUB @c @minone # c = c - 1, Zähler korrigieren, da von a # ein b zu viel abgezogen wurde vorzKorr: JA @minusc @vorzCDreh # Vorzeichenkorrektur erforderlich? JA 0 @End vorzCDreh: SUB @tmp @tmp # Vorzeichen von c (= Quotient) tauschen SUB @tmp @c SUB @c @c SUB @c @tmp JA @a @rest # existiert ein Rest? JA 0 @End rest: JA @minusa @vorzADreh # Vorzeichenkorrektur des Rests # erforderlich? JA 0 @End vorzADreh: SUB @tmp @tmp # Vorzeichen von a (= Rest) tauschen SUB @tmp @a SUB @a @a SUB @a @tmp End: SUB 0 0 # Programmausstieg, c beinhaltet den # Quotienten und a den Rest der Division # (Modulus) subb: SUB @a @b # a = a - b SUB @c @one # c = c + 1 JA 0 @loop
Nach diesen Vorbereitungen wird b so oft von a abgezogen, bis a nicht mehr größer als null ist. Sollte der Rest von a nun kleiner als null sein, muss ein Schritt rückgängig gemacht werden. Abschließend gilt es noch die Vorzeichen des Rests und des Quotienten basierend auf den eingangs festgehaltenen Erkenntnissen anzupassen.
Bei dem hier dargestellten Code wird der Quotient von 10 und 3 (10 : 3) ermittelt. Das Ergebnis befindet sich abschließend in Zelle @c, der Rest der Division in @a. Zudem ist in der Zelle @error eine 1 hinterlegt, wenn eine Division durch null versucht wurde.
Dieser Code funktioniert auch mit Gleitkommazahlen für a und b, ist also nicht beschränkt auf ganze Zahlen. Allerdings wird als Ergebnis für die Division nur eine natürliche Zahl geliefert. Der Rest hingegen (Modulus) kann durchaus eine reelle Zahl beinhalten.
Ähnlich wie bei der bereits vorgestellten Multiplikation wären auch hier Optimierungen möglich, die vor allem zum Tragen kommen, wenn Divisor und Dividend sich in ihrer Größenordnung massiv unterscheiden. Ein Ansatz hierzu wäre eine Implementierung analog zur schriftlichen Division zweier Zahlen. Dies erhöht die Komplexität des Codes deutlich, allerdings sollte es die Laufzeit erheblich verkürzen. Für den theoretischen Nachweis, dass eine Division mit JASm realisierbar ist, soll dieser Code allerdings zunächst genügen.