Logeleien (Teil 1)
In vielen Basic-Programmen tauchen sie auf, die logischen Operatoren wie NOT, AND und 0R. Bei sinnvollem Einsatz kann man eine Menge Basic-Speicherplatz sparen. Aber auch Ausdrücke wie IF A THEN … bringen nicht nur den Anfänger manchmal ins Schleudern. Was steckt eigentlich im Endefekt dahinter?
Das hätte sich der »Vater der Logik«, Aristoteles, vor 2200 Jahren nicht träumen lassen können, was aus seinen Gedankengängen einmal werden würde. Man kann aber mit einiger Berechtigung behaupten, daß es ohne seine Werke und die von Leibniz (vor etwa 300 Jahren hat dieser die Logik modernisiert) keine Computer gäbe. Die Arbeiten der Begründer der mathematischen Logik, Boole (1815-64) und Frege (1848-1925), basieren auf dem jahrtausende alten Fundament. Wie für den Computer geschaffen — aber eigentlich ist es umgekehrt: Die logische Maschine ist ein Produkt der mathematischen Logik — ist die sogenannte zweiwertige Logik. Hier geht es um »Wahr« und »Falsch«, ein drittes gibt es nicht (tertium non datur, wie die alten Philosophen zu sagen pflegten). Die Verwandtschaft liegt auf der Hand: Die elektronische Maschine kennt die Zustände Strom an/Strom aus oder Ladung vorhanden/nicht vorhanden oder eben einfach 1 und 0, die Ziffern der Binärarithmetik.
Dazu noch eine technische Bemerkung: Sollten Sie mit dem System der binären Zahlen noch nicht vertraut sein, dann lesen Sie den beigefügten Kasten, in dem die wichtigsten Begriffe erklärt sind.
1. Wahrheitswerte und Aussagen
Was sind Aussagen? Am besten sehen wir uns einfach einige Beispiele an:
- Rosen sind rot
- Die Zahl ist größer als 100.
Das sind einfache Aussagen. Eine zusammengesetzte Aussage ist beispielsweise:
Rosen sind rot UND Veilchen sind blau. Hier wurden zwei Aussagen UND-verknüpft. Keine Aussage ist:
- Wohin gehst Du?
Ich hoffe, daß auf diese Weise ohne tiefschürfende philosophische Erörterungen (denn die gibt es natürlich) das Wesen von Aussagen klar geworden ist.
Aussagen können wahr sein. Sie enthalten dann den Wahrheitswert »Wahr«. Sie können aber auch statt dessen falsch sein, was ihnen den Wahrheitswert »Falsch« verleiht. Der Wahrheitswert von zusammengesetzten Aussagen hängt zum einen von den Wahrheitswerten der Einzelaussagen ab und zum anderen von der Art ihrer Verknüpfung. Wir werden im folgenden für die Wahrheitswerte die Buchstaben W (für Wahr) und F (für Falsch) verwenden.
In der binären Arithmetik entspricht die 1 dem W und die 0 dem F. Keine Angst, falls Ihnen das noch unverständlich erscheint, wir werden noch allerlei Logeleien mit Binärzahlen treiben. Dann wird Ihnen das ganz geläufig sein. Was uns momentan interessiert, ist, wie der Computer Wahrheitswerte angibt. Dazu machen wir einen kleinen Test mit dem folgenden Programm:
10 INPUTA,B
20 C=(A=B)
30 PRINTA,B,C
In Zeile 20 ist eine Aussage enthalten: A = B. Wenn Sie A und B so eingegeben haben, daß beide gleich sind, dann ist diese Aussage wahr (W), und in C finden Sie den Wahrheitswert, den der Computer für W verwendet. Probieren Sie dies mal aus: Sie finden —1! Wenn aber A und B verschiedene Zahlen waren, ist die Aussage A = B falsch, und in C steht 0, was die Computerform von F ist. Weshalb —1 als Wahrheitswert des Commodore 64 für W? Das liegt daran, daß unser Computer für den Wahrheitswert ein ganzes Byte reserviert. Das schreibt er im Falle W voller Einsen:
1111 1111
Nach den Regeln von vorzeichenbehafteten Binärzahlen ist das aber die Erscheinungsform von —1.
2. Das merkwürdige IF A THEN …
Bei IF..THEN-Verzweigungen wird vom Computer der gesamte Ausdruck zwischen IF und THEN auf seinen Wahrheitswert untersucht (das kann dann eine Aussage sein, aber auch etwas anderes, zum Beispiel eine Variable). Dabei nimmt der C 64 alles für wahr an, was bei dieser Untersuchung ungleich Null ist.
Wenn also in einer Verzweigung der Form:
IF A THEN …
A schon irgendeinen Wert angenommen hat, der ungleich Null ist, wird die Bedingung als erfüllt angesehen. Probieren Sie mal mit verschiedenen Eingaben für A:
10 INPUT A
20 IF A THEN PRINT "TEST"
30 PRINT A
In der uns geläufigeren Form dieser Verzweigung tauchen zwischen IF und THEN Aussagen in mathematischer Form auf, in denen die Vergleichssymbole verwendet werden, zum Beispiel:
IF A > = 100 THEN GOTO …
3. Rechnen mit Wahrheitswerten
Außerhalb solch einer Verzweigung ist es manchmal gar nicht so einfach festzustellen, ob es sich bei einem Ausdruck um eine Aussage dreht oder vielleicht nur um eine Zuweisung. Es kommt hier sehr auf den Zusammenhang mit dem übrigen Programmtext an. Beispielsweise kann A = B sowohl eine Zuweisung sein (LET A = B) als auch eine Aussage (C = (A = B)). In Programmen, in denen viel mit logischen Operatoren gearbeitet wird, empfiehlt sich deshalb — um mehr Klarheit zu schaffen —, die vom C 64 verstandene, aber so gut wie nie verwendete Basic-Vokabel LET bei Zuweisungen zu verwenden.
Ein noch eklatanteres Beispiel ist enthalten in A = 5 + 2. Das ist offensichtlich keine Aussage, könnte deutlicher aber noch als LET A = 5 + 2 geschrieben werden. In einem anderen Zusammenhang ist es eine Aussage:
C=4+(A=5+2)
Ist hier A=5+2 wahr (wenn A=7), ergibt sich ein C von 3, weil ja der Wahrheitswert der Aussage —1 beträgt. Im anderen Fall ist C=4. Man kann mit Aussagen — besser gesagt, mit ihren Wahrheitswerten — also auch rechnen.
Im folgenden Programmbeispiel sind gleich fünf Wahrheitswerte miteinander rechnerisch verknüpft. Es handelt sich um eine kurze Routine zur Umrechnung von ASCII-Code in Bildschirmcode:
10 INPUT"ASCII-WERT";A
20 C=A-161-33*(A<255)-64*(A<192)-32*(A<160)+32*(A<96)-64*(A<64)
30 PRINT"ASCII="A,"POKE-CODE="C
Beispiel: ASCII = 65, Bildschirmcode = 1
Aussagen können auch mit Strings gebildet werden. Auch dabei ergeben sich die Wahrheitswerte —1 oder 0. Allerdings lassen sich hier sinnvoll nur die Vergleichsrelationen »=« und »ungleich« einsetzen. Alle anderen »größer als«, »kleiner als« etc. sind mit Vorsicht zu genießen. Zur Ermittlung des Wahrheitswertes werden nämlich von links nach rechts alle Buchstaben beider Strings in Form ihrer ASCII-Werte miteinander verglichen. Die erste auf diese Weise gefundene Abweichung führt dann zum Ergebnis. Ein Beispiel soll das Problem verdeutlichen:
Die Aussage (A$<B$) soll uns einen Wahrheitswert liefern. Wenn nun A$ = "DZZZ" und B$ = "EAAA" definiert wurden, ergibt sich —1 als Wahrheitswert, weil der ASCII-Wert von D kleiner ist als der von E. Der Rest der Strings spielt keine Rolle mehr.
4. Die logischen Operatoren in Basic
Drei Operatoren haben wir im Normalfall zur Verfügung für die sogenannte Boolesche Algebra, wie man manchmal auch das Rechnen mit logischen Operatoren nennt:
NOT, AND, OR
Die Tabelle 1 zeigt, wo in der Prioritätenreihenfolge aller Operatoren diese drei einzuordnen sind. Ebenso wie bei den arithmetischen Operatoren ( + ,*,↑ etc.) kann auch hier die Reihenfolge durch sinnvolle Anwendung von Klammern verändert werden.
Bemerkung | Operatoren | Beispiel |
Höchste Priorität | ↑ | A↑B |
*, / | A*B, A/B | |
+ ,— | A+B, A-B | |
NOT | NOT A | |
AND | A AND B | |
Niedrigste Priorität | OR | A OR B |
5. Wahrheitstabellen
Jede Verkoppelung von Aussagen (beziehungsweise ihren Wahrheitswerten) mittels logischer Operatoren ergibt ebenfalls wieder Wahrheitswerte. Wir hatten vorhin schon erwähnt, daß das Ergebnis abhängt:
- von den Wahrheitswerten der zu verknüpfenden Aussagen und
- von der Art der Verknüpfung.
Das kann manchmal schon reichlich schwer zu durchschauen sein, was welche Kombination ergibt. Deshalb schreibt man sich eine Übersicht, die alle möglichen Ausgangs-Wahrheitswerte enthält und die nach der Verknüpfung entstandenen Wahrheitswerte. Solche Tabellen nennt man Wahrheitstabellen. Wir werden diese Tabellen im folgenden bei der Erklärung der logischen Operatoren verwenden. Wie man sie erstellt und liest, wird Ihnen schnell geläufig sein.
Noch eine Bemerkung: Die Anwendung der logischen Operatoren auf Aussagen und auf Zahlen wird bei uns — aus Gründen der besseren Verständlichkeit — getrennt behandelt werden. Das ist eigentlich nicht nötig, denn im Grunde genommen sind ja die Wahrheitswerte von Aussagen auch nur Zahlen.
6. Die Anwendung von NOT auf Aussagen
Der NOT-Operator erzeugt immer das Gegenteil des Wahrheitswertes der Ausgangsaussage. Wenden wir also NOT auf eine Aussage mit dem Wahrheitswert W an, dann ergibt das den Wert F. Dasselbe geschieht im umgekehrten Fall.
Dazu wollen wir uns eine Wahrheitstabelle schreiben (Tabelle 2). In der linken Spalte sind die beiden möglichen Wahrheitswerte einer Aussage A aufgeführt. Die rechte Spalte ergibt sich durch Anwendung von NOT auf die Werte der linken Spalte:
- NOT W = F
- NOT F = W
A | NOT A |
W | F |
F | W |
Das ist gar nicht so schwer, nicht wahr? An einem Beispiel wollen wir uns das auch noch mal ansehen. Die Zeile:
10 A = (3 = 5):PRINT NOT A
ergibt den Wert —1. Die Aussage 3=5 ist ja falsch (F oder für den Computer 0) und A deshalb 0. NOT A ergibt dann das Gegenteil, also W oder —1.
Eine Basic-Zeile wie die folgende:
10 A = NOT A
kann man wie einen Flip-Flop-Schalter einsetzen, falls man den Wahrheitswert von A zuvor als 0 oder —1 definiert hat. Jedesmal, wenn das Programm über diesen Ausdruck läuft, kippt der Wert von A.
7. NOT auf Zahlen angewendet
Zahlen oder Variable, auf die der NOT-Operator angewandt wird, verkehren sich in ihr Einerkomplement. Falls Sie mit den Begriffen »Einerkomplement« und »Zweierkomplement« Schwierigkeiten haben, weise ich Sie nochmal auf den hier abgedruckten Kasten mit Erläuterungen hin. Jedes Bit wird also »gekippt«. Aus einer 0 wird 1 und umgekehrt. Die Wahrheitstabelle kann hier ähnlich aufgestellt werden wie für Aussagen, nur tauchen hier anstelle von W und F nun 1 und 0 (also die Bitwerte) auf (siehe Tabelle 3).
A | NOT A |
1 | 0 |
0 | 1 |
Eine Anwendung von NOT wäre beispielsweise das gezielte Kippen von Bytes oder 2-Byte-Werten. Besonders bei Sprite-Programmen ist sowas denkbar. Nehmen wir mal an, wir hätten acht Sprites definiert, von denen vier bis zu einem bestimmten Ereignis sichtbar sein sollen. Die anderen vier sind solange abgeschaltet. Wenn das Ereignis (Tastendruck oder Zusammenstoß…) eintritt, werden die obersten vier ab- und gleichzeitig die anderen vier angeschaltet. Register 21 (53269) des VIC-II-Chip stellt für jedes Sprite ein Schalt-Bit zur Verfügung (0 steht dort für ein ausgeschaltetes und 1 für ein aktiviertes Sprite). Sollen also zuerst die Sprites 0,2,4,6 an- und 1, 3, 5, 7 abgeschaltet sein, dann enthält Register 21 das Bit-Muster:
0101 0101
Darauf nun eine NOT-Operation angewendet ergäbe genau das erwünschte Kippen:
1010 1010 nach NOT.
Es läge daher nahe, etwa so zu programmieren:
POKE 53269,NOT PEEK(53269)
Leider ist das nicht möglich. Versucht man es trotzdem, erhält man einen ILLEGAL QUANTITY ERROR. Woran liegt das? Die Ursache dafür liegt wieder in der Eigenart, wie der C 64 Integer-Zahlen interpretiert. Zwar erzeugt die NOT-Operation das Einerkomplement der Ausgangszahl, verstanden wird dieses Ergebnis aber als Zweierkomplementzahl. Daraus folgt, daß man mit der obigen Anweisung versucht, eine negative Zahl in die Speicherstelle zu POKEn, und da streikt unser Computer. Die Binärzahl 1010 1010 wird als —86 verstanden. Was kann man tun, daß der wahre Wert, also 170, in den Speicher gePOKEt wird? Bei 1-Byte-Zahlen ist das relativ einfach: Man wandelt sie durch Abziehen von 256 in eine 2-Byte-Zahl um, also NOT(A-256). In Bild 2 ist zu sehen, was dabei geschieht.
Ein anderer Weg für 1-Byte-Zahlen (also Zahlen, die kleiner als 255 sind) ist NOT A AND 255, was wir aber erst später verstehen werden, wenn wir die AND-Operation kennengelernt haben. Vorsicht muß man walten lassen, wenn auch negative A-Werte auftreten. Negative A können ohne Probleme der NOT-Operation unterzogen werden, weil das Ergebnis in jedem Fall positiv ist. Verwendet man NOT(A-256), kommt es zu Fehlern. Der Weg über NOT A AND 255 ist auch mit negativen 1-Byte-Zahlen möglich. Am sichersten wäre also diese Basic-Zeile:
POKE53269,NOTPEEK(53269)AND255
2-Byte-Zahlen spielen bei POKEs keine Rolle, weshalb wir auf die Umwandlung der negativen Zahl in den vorzeichenfreien Ausdruck hier nicht eingehen werden. Eine andere Sache muß bei der Anwendung von NOT noch bedacht werden: Diese Operation arbeitet mit Integer-Zahlen. Treten nun als Argumente »Komma-Zahlen« auf, dann führt der C 64 zuerst eine INT-Operation aus, die unter Umständen zu Fehlern führen kann: 3999 ergibt dann ein deutlich anderes Ergebnis als 4001.
Die NOT-Operation kann nur auf Zahlen, nicht aber auf Strings angewendet werden. Allerdings erfolgt die computerinterne Speicherung von Buchstaben ja als ASCII-Werte, also auch als Zahlen. Wenn wir daher die ASCII-Codes eines Textes der NOT-Verknüpfung unterziehen, haben wir auch Strings dieser Operation zugänglich gemacht. Genau das tut ein kleines Demo-Programm (Programm Logik-1): Es ver- und entschlüsselt Texte mittels NOT.
In diesem Demo-Programm wird Text Buchstabe für Buchstabe in die ASCII-Werte übertragen und diese dann durch NOT komplementiert und in C$ gespeichert. Der Ausdruck ist dann ein unverständliches Kauderwelsch, das aber durch eine zweite NOT-Operation wieder lesbar wird.
8. Eine kleine Hilfe
Als Programm Logik-2 finden Sie eine kleine Denk- und Rechenhilfe hier abgedruckt. Dieses Programm kann Zahlen zwischen —32767 und +32767 den logischen Verknüpfungen unterziehen und zeigt Ihnen dabei, was sich im Binärformat abspielt und wie die Argumente — falls negative Zahlen auftreten — im vorzeichenfreien Format aussehen. Nach dem RUN bietet Ihnen ein Menü fünf Möglichkeiten an: NOT, AND, OR, EOR und Programmende. NOT kennen Sie ja schon, die anderen logischen Operatoren werden Ihnen in der nächsten Folge geläufig werden. Dort wird Ihnen dieses Programm dann einige Hilfestellungen geben für etwas kompliziertere Sachverhalte. Wenn Sie eine Option angewählt haben, werden zwei Zahleneingaben verlangt (bei NOT nur eine) und dann die entsprechenden Binärzahlen, die vorzeichenfreien Formen und das Ergebnis der Verknüpfung ausgedruckt. Innerhalb der gesteckten Grenzen sind alle Zahleneingabe-Formate möglich. Ein Tastendruck bringt Sie wieder ins Menü zurück.
In der nächsten Folge werden wir uns die Operatoren AND und OR ansehen. Ein in dem WAIT-Befehl versteckter weiterer Operator EOR soll aufgespürt werden, und wir werden wieder einige Anwendungen der Boole’schen Algebra in unserem Computer kennenlernen.
(Heimo Ponnath/gk)10 rem--------------------------------- 20 rem logik - 1 30 rem--------------------------------- 40 : 50 print"{clr} geheimcode mit not" 60 print:print 70 print" geben sie ein wort ein"; 100 inputa$:l=len(a$):dima(l),b(l),b$(l):k=0 110 c$="" 120 fori=1tol:a(i)=asc(mid$(a$,i,1)):b(i)=nota(i)-257:b$(i)=chr$(b(i)):nexti 130 fori=1tol:c$=c$+b$(i):nexti 140 ifk=0then:print:print"text = ";a$ 145 ifk=1then:print:print"geheimcode = ";a$ 150 k=k+1:ifk=1thena$=c$:goto110 160 print:print"entschluesselt = ";c$
10 REM --------------------------------- 20 REM LOGIK - 1 30 REM --------------------------------- 40 : 50 PRINT"{CLR,7SPACE}GEHEIMCODE MIT NOT" 60 PRINT:PRINT 70 PRINT" GEBEN SIE EIN WORT EIN"; 100 INPUTA$:L=LEN (A$):DIM A(L),B(L),B$(L):K=0 110 C$="" 120 FOR I=1 TOL:A(I)=ASC (MID$ (A$,I,1)):B(I)=NOT A(I)-257:B$(I)=CHR$ (B(I)):NEXT I 130 FOR I=1 TOL:C$=C$+B$(I):NEXT I 140 IF K=0 THEN:PRINT:PRINT"TEXT{11SPACE}= ";A$ 145 IF K=1 THEN:PRINT:PRINT"GEHEIMCODE{5SPACE}= ";A$ 150 K=K+1:IF K=1 THENA$=C$:GOTO 110 160 PRINT:PRINT"ENTSCHLUESSELT = ";C$
1 rem ********************************* 2 rem * * 3 rem * logische operationen * 4 rem * * 5 rem * zum verfolgen im binaerformat * 6 rem * not,and,or,eor * 7 rem * * 8 rem * heimo ponnath hamburg 1985 * 9 rem * * 10 rem********************************* 15 printchr$(147):goto200 20 rem ***** up-cursor setzen ***** 25 poke211,s:poke214,z:sys58640:return 30 rem ***** up-eingabetest ******* 35 e=abs(e):a=(e>=0):b=(e<255) 40 ifaandbthenm=8:return 45 a=(e>=255):b=(e<32768) 50 ifaandbthenm=16:return 55 m=0:return 60 rem ***** up-eingabe 1 ********* 65 s=1:z=5:gosub25:printchr$(28)"welche zahl solls denn sein?" 70 z=7:gosub25:print"sie muss zwischen -32767und +32767 sein" 75 z=9:gosub25:inputw:e=w:gosub35:ifm=0thenpoke781,9:sys59903:goto75 80 printchr$(30):return 85 rem ***** up-eingabe 2 ********* 90 s=1:z=5:gosub25:printchr$(28)"geben sie nun die beiden zahlen ein." 95 s=1:z=7:gosub25:print"sie muessen zw. -32767 u. +32767 sein!" 100 z=9:gosub25:input"erste zahl =";w1:e=w1:gosub35:m1=m 105 ifm=0thenpoke781,9:sys59903:goto100 110 z=11:gosub25:input"zweite zahl=";w2:e=w2:gosub35 115 ifm=0thenpoke781,11:sys59903:goto110 120 m=16+8*((m1=8)and(m=8)):printchr$(30):return 125 rem **** up-umrechnung dez/bin **** 130 bi$="":di=de 135 di=di/2:d$="0":ifdi<>int(di)thend$="1" 140 di=int(di):bi$=d$+bi$:ifdi>0then135 145 iflen(bi$)<mthenbi$="0"+bi$:goto145 150 return 155 rem **** up-umrechnung bin/dez **** 160 de=0:fori=1tom:ifmid$(a$,i,1)="1"thende=de+2^(m-i) 165 nexti:return 170 rem **** up-bildschirmausgabe ***** 175 printchr$(158)tab(5)de;tab(32-m)bi$;chr$(30):return 198 rem 199 rem **** hauptprogramm-variable *** 200 s=0:z=0:e=0:a=0:b=0:m=0:w=0:w1=0:w2=0:m1=0:i=0:k=0:x=0 205 di=0:de=0:c=0:v=0 210 bi$="":d$="":a$="":b$="":c$="":z$="-----------------":be$="" 220 dimde(3),bi$(3) 299 rem **** hauptprogramm-menue ****** 300 poke53280,0:poke53281,0:printchr$(147)chr$(30) 305 z=3:s=2:gosub25:printchr$(18)" die logischen befehle in binaerform " 310 z=7:gosub25:printtab(10)"not"tab(25)"1" 315 z=9:gosub25:printtab(10)"and"tab(25)"2" 320 z=11:gosub25:printtab(10)"or"tab(25)"3" 325 z=13:gosub25:printtab(10)"eor"tab(25)"4" 330 z=15:gosub25:printtab(10)"programmende"tab(25)"5" 335 poke646,10:z=20:gosub25:print"bitte waehlen sie einen menuepunkt..."chr$(30) 340 getb$:ifb$<"1"orb$>"5"then340 345 onval(b$)gosub400,500,600,700,800 350 z=23:s=1:gosub25:printchr$(3)"weiter durch tastendruck..." 355 poke198,0:wait198,1:goto300 399 rem **** option - not *********** 400 printchr$(147):z=2:s=1:gosub25:printchr$(18)" option not "chr$(146) 405 bi$="":be$="":d$="":w=0:de=0:k=0:gosub65:ifw<0then450 410 de=w:gosub130 412 z=15:s=0:gosub25:gosub175:printtab(15)z$+" not":be$="" 415 fori=1tom:d$=mid$(bi$,i,1):ifd$="1"thend$="0":goto420 417 d$="1" 420 be$=be$+d$:nexti:ifk=1thenreturn 425 bi$=be$:a$=be$:gosub160:z=17:s=0:gosub25:gosub175:be$="":return 440 rem **** up-negative binaerzahl *** 450 w=notw:de=w:gosub130:k=1:gosub415:a$=be$:gosub160:k=0:ifx=1thenreturn 455 bi$=be$:be$="":goto412 499 rem **** option - and *********** 500 printchr$(147):z=2:s=1:gosub25:printchr$(18)" option and "chr$(146) 502 rem **** up-eingabenverarbeitung ** 505 gosub90:ifw1<0thenw=w1:x=1:gosub450:x=0:bi$(1)=be$:de(1)=de:be$="":de=0 510 ifw2<0thenw=w2:x=1:gosub450:x=0:bi$(2)=be$:de(2)=de:be$="":de=0 515 ifw1>=0thende=w1:gosub130:de(1)=de:bi$(1)=bi$:de=0:bi$="" 520 ifw2>=0thende=w2:gosub130:de(2)=de:bi$(2)=bi$:de=0:bi$="" 525 z=15:s=0:gosub25:de=de(1):bi$=bi$(1):gosub175 530 z=16:gosub25:de=de(2):bi$=bi$(2):gosub175:ifv=1thenreturn 532 printtab(15)z$+" and":bi$(3)="" 535 fori=1tom:a=val(mid$(bi$(1),i,1)):b=val(mid$(bi$(2),i,1)):c=aandb 540 bi$(3)=bi$(3)+right$(str$(c),1):nexti:a$=bi$(3):gosub160:bi$=bi$(3) 545 z=18:gosub25:gosub175:return 599 rem **** option - or ************ 600 printchr$(147):z=2:s=1:gosub25:printchr$(18)" option or "chr$(146) 605 v=1:gosub505:v=0 610 printtab(15)z$+" or":bi$(3)="" 615 fori=1tom:a=val(mid$(bi$(1),i,1)):b=val(mid$(bi$(2),i,1)):c=aorb 620 bi$(3)=bi$(3)+right$(str$(c),1):nexti:a$=bi$(3):gosub160:bi$=bi$(3) 625 z=18:gosub25:gosub175:return 699 rem **** option - eor *********** 700 printchr$(147):z=2:s=1:gosub25:printchr$(18)" option eor "chr$(146) 705 v=1:gosub505:v=0 710 printtab(15)z$+" eor":bi$(3)="" 715 fori=1tom:a=val(mid$(bi$(1),i,1)):b=val(mid$(bi$(2),i,1)) 720 ifa+b=1thenc=1:goto730 725 c=0 730 bi$(3)=bi$(3)+right$(str$(c),1):nexti:a$=bi$(3):gosub160:bi$=bi$(3) 735 z=18:gosub25:gosub175:return 799 rem **** option-programmende **** 800 printchr$(147):s=8:z=12:gosub25:print"das war's...tschuess !" 805 z=22:s=0:gosub25:end
1 REM ********************************* 2 REM * * 3 REM * LOGISCHE OPERATIONEN * 4 REM * * 5 REM * ZUM VERFOLGEN IM BINAERFORMAT * 6 REM * NOT,AND,OR,EOR * 7 REM * * 8 REM * HEIMO PONNATH HAMBURG 1985 * 9 REM * * 10 REM ********************************* 15 PRINTCHR$ (147):GOTO 200 20 REM ***** UP-CURSOR SETZEN ***** 25 POKE 211,S:POKE 214,Z:SYS 58640:RETURN 30 REM ***** UP-EINGABETEST ******* 35 E=ABS (E):A=(E>=0):B=(E<255) 40 IF AAND B THENM=8:RETURN 45 A=(E>=255):B=(E<32768) 50 IF AAND B THENM=16:RETURN 55 M=0:RETURN 60 REM ***** UP-EINGABE 1 ********* 65 S=1:Z=5:GOSUB 25:PRINTCHR$ (28)"WELCHE ZAHL SOLLS DENN SEIN?" 70 Z=7:GOSUB 25:PRINT"SIE MUSS ZWISCHEN -32767UND +32767 SEIN" 75 Z=9:GOSUB 25:INPUTW:E=W:GOSUB 35:IF M=0 THENPOKE 781,9:SYS 59903:GOTO 75 80 PRINTCHR$ (30):RETURN 85 REM ***** UP-EINGABE 2 ********* 90 S=1:Z=5:GOSUB 25:PRINTCHR$ (28)"GEBEN SIE NUN DIE BEIDEN ZAHLEN EIN." 95 S=1:Z=7:GOSUB 25:PRINT"SIE MUESSEN ZW. -32767 U. +32767 SEIN!" 100 Z=9:GOSUB 25:INPUT"ERSTE ZAHL =";W1:E=W1:GOSUB 35:M1=M 105 IF M=0 THENPOKE 781,9:SYS 59903:GOTO 100 110 Z=11:GOSUB 25:INPUT"ZWEITE ZAHL=";W2:E=W2:GOSUB 35 115 IF M=0 THENPOKE 781,11:SYS 59903:GOTO 110 120 M=16+8*((M1=8)AND (M=8)):PRINTCHR$ (30):RETURN 125 REM **** UP-UMRECHNUNG DEZ/BIN **** 130 BI$="":DI=DE 135 DI=DI/2:D$="0":IF DI<>INT (DI) THEND$="1" 140 DI=INT (DI):BI$=D$+BI$:IF DI>0 THEN135 145 IF LEN (BI$)<M THENBI$="0"+BI$:GOTO 145 150 RETURN 155 REM **** UP-UMRECHNUNG BIN/DEZ **** 160 DE=0:FOR I=1 TOM:IF MID$ (A$,I,1)="1" THENDE=DE+2^(M-I) 165 NEXT I:RETURN 170 REM **** UP-BILDSCHIRMAUSGABE ***** 175 PRINTCHR$ (158)TAB( 5)DE;TAB( 32-M)BI$;CHR$ (30):RETURN 198 REM 199 REM **** HAUPTPROGRAMM-VARIABLE *** 200 S=0:Z=0:E=0:A=0:B=0:M=0:W=0:W1=0:W2=0:M1=0:I=0:K=0:X=0 205 DI=0:DE=0:C=0:V=0 210 BI$="":D$="":A$="":B$="":C$="":Z$="-----------------":BE$="" 220 DIM DE(3),BI$(3) 299 REM **** HAUPTPROGRAMM-MENUE ****** 300 POKE 53280,0:POKE 53281,0:PRINTCHR$ (147)CHR$ (30) 305 Z=3:S=2:GOSUB 25:PRINTCHR$ (18)" DIE LOGISCHEN BEFEHLE IN BINAERFORM " 310 Z=7:GOSUB 25:PRINTTAB( 10)"NOT"TAB( 25)"1" 315 Z=9:GOSUB 25:PRINTTAB( 10)"AND"TAB( 25)"2" 320 Z=11:GOSUB 25:PRINTTAB( 10)"OR"TAB( 25)"3" 325 Z=13:GOSUB 25:PRINTTAB( 10)"EOR"TAB( 25)"4" 330 Z=15:GOSUB 25:PRINTTAB( 10)"PROGRAMMENDE"TAB( 25)"5" 335 POKE 646,10:Z=20:GOSUB 25:PRINT"BITTE WAEHLEN SIE EINEN MENUEPUNKT..."CHR$ (30) 340 GET B$:IF B$<"1"OR B$>"5" THEN340 345 ON VAL (B$)GOSUB 400,500,600,700,800 350 Z=23:S=1:GOSUB 25:PRINTCHR$ (3)"WEITER DURCH TASTENDRUCK..." 355 POKE 198,0:WAIT 198,1:GOTO 300 399 REM **** OPTION - NOT *********** 400 PRINTCHR$ (147):Z=2:S=1:GOSUB 25:PRINTCHR$ (18)" OPTION{2SPACE}NOT{6SPACE}"CHR$ (146) 405 BI$="":BE$="":D$="":W=0:DE=0:K=0:GOSUB 65:IF W<0 THEN450 410 DE=W:GOSUB 130 412 Z=15:S=0:GOSUB 25:GOSUB 175:PRINTTAB( 15)Z$+" NOT":BE$="" 415 FOR I=1 TOM:D$=MID$ (BI$,I,1):IF D$="1" THEND$="0":GOTO 420 417 D$="1" 420 BE$=BE$+D$:NEXT I:IF K=1 THENRETURN 425 BI$=BE$:A$=BE$:GOSUB 160:Z=17:S=0:GOSUB 25:GOSUB 175:BE$="":RETURN 440 REM **** UP-NEGATIVE BINAERZAHL *** 450 W=NOT W:DE=W:GOSUB 130:K=1:GOSUB 415:A$=BE$:GOSUB 160:K=0:IF X=1 THENRETURN 455 BI$=BE$:BE$="":GOTO 412 499 REM **** OPTION - AND *********** 500 PRINTCHR$ (147):Z=2:S=1:GOSUB 25:PRINTCHR$ (18)" OPTION{2SPACE}AND{6SPACE}"CHR$ (146) 502 REM **** UP-EINGABENVERARBEITUNG ** 505 GOSUB 90:IF W1<0 THENW=W1:X=1:GOSUB 450:X=0:BI$(1)=BE$:DE(1)=DE:BE$="":DE=0 510 IF W2<0 THENW=W2:X=1:GOSUB 450:X=0:BI$(2)=BE$:DE(2)=DE:BE$="":DE=0 515 IF W1>=0 THENDE=W1:GOSUB 130:DE(1)=DE:BI$(1)=BI$:DE=0:BI$="" 520 IF W2>=0 THENDE=W2:GOSUB 130:DE(2)=DE:BI$(2)=BI$:DE=0:BI$="" 525 Z=15:S=0:GOSUB 25:DE=DE(1):BI$=BI$(1):GOSUB 175 530 Z=16:GOSUB 25:DE=DE(2):BI$=BI$(2):GOSUB 175:IF V=1 THENRETURN 532 PRINTTAB( 15)Z$+" AND":BI$(3)="" 535 FOR I=1 TOM:A=VAL (MID$ (BI$(1),I,1)):B=VAL (MID$ (BI$(2),I,1)):C=AAND B 540 BI$(3)=BI$(3)+RIGHT$ (STR$ (C),1):NEXT I:A$=BI$(3):GOSUB 160:BI$=BI$(3) 545 Z=18:GOSUB 25:GOSUB 175:RETURN 599 REM **** OPTION - OR ************ 600 PRINTCHR$ (147):Z=2:S=1:GOSUB 25:PRINTCHR$ (18)" OPTION{3SPACE}OR{6SPACE}"CHR$ (146) 605 V=1:GOSUB 505:V=0 610 PRINTTAB( 15)Z$+" OR":BI$(3)="" 615 FOR I=1 TOM:A=VAL (MID$ (BI$(1),I,1)):B=VAL (MID$ (BI$(2),I,1)):C=AOR B 620 BI$(3)=BI$(3)+RIGHT$ (STR$ (C),1):NEXT I:A$=BI$(3):GOSUB 160:BI$=BI$(3) 625 Z=18:GOSUB 25:GOSUB 175:RETURN 699 REM **** OPTION - EOR *********** 700 PRINTCHR$ (147):Z=2:S=1:GOSUB 25:PRINTCHR$ (18)" OPTION{2SPACE}EOR{6SPACE}"CHR$ (146) 705 V=1:GOSUB 505:V=0 710 PRINTTAB( 15)Z$+" EOR":BI$(3)="" 715 FOR I=1 TOM:A=VAL (MID$ (BI$(1),I,1)):B=VAL (MID$ (BI$(2),I,1)) 720 IF A+B=1 THENC=1:GOTO 730 725 C=0 730 BI$(3)=BI$(3)+RIGHT$ (STR$ (C),1):NEXT I:A$=BI$(3):GOSUB 160:BI$=BI$(3) 735 Z=18:GOSUB 25:GOSUB 175:RETURN 799 REM **** OPTION-PROGRAMMENDE **** 800 PRINTCHR$ (147):S=8:Z=12:GOSUB 25:PRINT"DAS WAR'S...TSCHUESS !" 805 Z=22:S=0:GOSUB 25:END