In diesem Kapitel wird beschrieben, wie Forth Zahlen sieht. Die Rede ist allerdings von Ganzzahlen, also einem Teilbereich der Zahlen, die man in der Mathematik 'Ganze Zahlen' nennt. Moderne Forth-System kennen natürlich gebrochene, sogenannte Fließkommazahlen. Traditionelle Forth-System basieren allerdings auf Ganzzahlen und daher beschränke ich mich hier auch auf die Beschreibung dieser Zahlen.
Der nun folgende Teil ist für diejenigen gedacht, die sich mit der Darstellung von Zahlen im Comupter gar nicht auskennen. Sollte ihnen das Konzept der Zahldarstellung schon vertraut sein und sie wollen nur wissen, wie in Forth mit Zahlen umgegangen wird, dann können sie gleich hier weiterlesen.
Jeder Computer speichert Zahlen im Zweiersystem. Dieses Zahlsystem kennt als Ziffern nur die '0' und die '1'. Genau wie bei der Dezimalschreibweise hat dabei jede Stelle ihre Wertigkeit. Sind es bei der Dezimalschreibweise die Einerstelle, Zehnerstelle, Hunderterstelle, ..., dann sind es in der Zweierschreibweise die Einerstelle, die Zweierstelle, die Viererstelle, die Achterstelle ...
In Forth sind Zahlen zunächst einmal 16 Bit lang, bei modernen Forth-Systemen auch 32 Bit. Ich will hier die Erklärungen erst einmal für 8 Bit vortragen. Das ist etwas einfacher und die Logik hinter der Sache ist bei größeren Bitanzahlen gleich. Zunächst einmal, wie wird eine Zahl im Zweiersystem kodiert? Betrachte man erst einmal die 8 Bits einer Zahl mit ihrer jeweiligen Wertigkeit.
Zahl: | ||||||||
Wertigkeit: | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Betrachtet man nun mal eine konkrete Zahl, dann sind die Bits teilweise Null oder Eins:
Zahl: | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 |
Wertigkeit: | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Will man nun wissen, welche Zahl im Dezimalsystem dahinter steckt, dann braucht man nur die Stellen, die '1' sind mit ihrer Wertigkeit multiplizieren und die Ergebnisse zu addieren. Für das obige Beispiel bedeutet das: 1 mal 64 + 1 mal 16 + 1 mal 8 + 1 mal 1 und das ergibt natürlich 89.
Man kann sich nun leicht überlegen, dass man mit einer solchen, 8 Bit breiten Zahldarstellung alle Zahlen zwischen 0 und 255 darstellen kann. (Wenn sie es nicht glauben, rechnen sie es nach). Da sich auf diese Art und Weise nur die Null und positive Zahlen darstellen lassen, spricht man auch von vorzeichenlosen Zahlen.
Wie sieht die Sache nun aus, wenn man auch negative Zahlen darstellen will? Nun man betrachtet das oberste Bit nicht mehr gemäß seiner Wertigkeit sondern verwendet es als Vorzeichenbit. Ist es gesetzt, also '1', dann wird die Zahl als negative Zahl interpretiert, ist es nicht gesetzt, also '0', dann handelt es sich um eine positive Zahl. Mit den acht Bit, die hier als Beispiel dienen, kann man so von -128 bis 127 zählen. Allerdings gibt es noch eine Besonderheit.
Will man zu einer positiven Zahl ihr negatives 'Ebenbild' bilden, dann wird nicht einfach nur ihr Vorzeichenbit geändert. So entspricht zwar:
Zahl: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
Wertigkeit: | VZ | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
der Eins, aber
Zahl: | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
Wertigkeit: | VZ | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Nicht der '-1'. Wieso dass denn, werden sie fragen. Nun, der Grund liegt darin, dass es einfacher ist die negativen Zahlen anders darzustellen; insbesondere Rechnungen vereinfachen sich, wenn man eher wie bei einem Zählwerk vorgeht. Stellen sie sich vor, der Kilometerzähler in ihrem Auto würde rückwärts laufen, wenn sie rückwärts fahren.
Bei einem ganz neuen Ator steht der Zähler vielleicht bei: 000002. Wenn man nun zwei Kilometer rückwärts fährt, dann steht er bei 000000. Fährt man nun noch einen Kilometer rückwärts, dann stünde er bei 999999. Und genau so verfährt man mit den Zahlen im Computer. Die Null entspricht der:
Zahl: | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Wertigkeit: | VZ | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Zählt man von da aus um Eins 'zurück', dann erhält man:
Zahl: | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Wertigkeit: | VZ | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
der Computerdarstellung für die '-1' (Jetzt wissen sie auch, wieso die '-1' bei den Flags so eine besondere Rolle spielt. Es ist einfach die Zahl, bei deren binärer Darstellung alle Stellen auf '1' stehen).
Zwei Worte in Forth werden nun verständlicher:
Das Wort 2*
wurde schon erklärt, hat aber auch den
Namen 'left shift'. Das hängt damit zusammen, dass bei der
Multiplikation mit 2 einfach alle Stellen einer Zahl um eins nach
links geschoben -- geshiftet werden. Sehen sie sich einfach mal zwei
Zahlen an: Die 17 und die 34:
17: | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
34: | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 |
Wertigkeit: | VZ | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Man erkennt deutlich, dass die Stellen einfach nur um eine Stelle
nach links verschoben sind. Bei dem Forth-Wort 2/
ist
es natürlich genau umgekehrt und daher nennt man das Wort auch
'right shift'.
Wie groß sind Zahlen denn nun in Forth. Wie schon gesagt, war es in traditionellen Forth-Systemen so, dass eine einfache Zahl 16 Bits belegte. Damit waren Zahlen zwischen 0 und 65535 beziehungsweise zwischen -32768 und 32767 groß. In modernen Forth-Systemen sind diese Zahlen allerdings in der Regel 32 Bit groß. Die Werte liegen dann zwischen -2147483648 bis 2147483647 oder zwischen 0 und 4294967295.
Neben diesen Zahlen gibt es in Forth auch noch doppelt genaue Zahlen oder einfacher doppelte Zahlen. Wie der Name schon andeutet beanspruchen diese Zahlen einfach die doppelte Anzahl von Bits. In modernen Systemen also 64 Bit, womit Zahlen von 0 bis 18446744073709551615 möglich sind (vorzeichenlos; Die Zahl heißt übrigens: 18 Trillionen 446 Billiarden 744 Billionen 73 Milliarden 109 Millionen 551 Tausend 615) Genaueres zu den einfachen und den doppelten Zahlen kommt gleich im Teil für alle.
Noch einmal ein Wort zu Zahlsystemen. Bisher haben sie das Dezimalsystem (vermutlich schon vor der Grundschule) und gerade das Zweier- oder binäre System kennengelernt. Grundsätzlich kann man jede beliebige Zahl als Grundlage für eine Zahldarstellung nehmen. Nehmen wir das 3er-System.
Die 'unterste' Stelle, also die erste Stelle vor dem Komma ist immer die Einerstelle, das ist bei allen Zahlsystemen so. Das hängt damit zusammen, dass die Wertigkeit einer Stelle immer gleich der Zahlenbasis, also hier der 3, potenziert mit der Stellennummer, gezählt ab Null, ist. Die erste Stelle hat also die Stellennummer 0 und daher die Wertigkeit 30.
Die nächste Stelle, in unserem Beispiel die zweite vor dem Komma, hat die Stellennummer 1 und damit die Wertigkeit 31, also 3. Die nächste die 32 also 9. Es folgen 27, 81, 243, 729 usw. Die Umrechnung ins 10er-System ist immer recht einfach: Ziffer mal Wertigkeit und dann alles addieren. Machen wir ein Beispiel:
Die Zahl '21002' hat im Dezimalsystem die folgende Darstellung: 2 34 + 1 33 + 2 30 oder: 162+27+2=191.
Wie schon gesagt, kann jede Zahl außer der 1 als Zahlenbasis genommen werden. Im Umfeld mit Computern haben sich aber vor allem zwei Zahlsysteme neben dem Dezimalsystem etabliert: Das Hexadezimalsystem (zur Zahlenbasis 16) und das Okatalsystem (zur Basis 8). Ich kann ihnen wirklich nicht erklären, worin der Vorteil des Oktalsystems liegt, auch wenn es, vor allem in UNIX-Umgebungen immer noch verwendet wird. Bei der Hexadezimaldarstellung sieht die Sache anders aus.
Bei der Hexadezimaldarstellung hat es sich eingebürgert die Ziffern '0' bis '9' einfach so zu belassen, wie sie sind. Es kommen aber auch noch die Ziffern mit den Werten 10, 11, 12, 13, 14 und 15 vor. Die werden in der Regel einfach durch die Buchstaben 'A', 'B', 'C', 'D', 'E' und 'F' geschrieben. Nun ist es so, dass man genau 4 Bits braucht, um bis 15 zählen zu können, was dazu führt, dass man mit einer hexadezimalen Stelle einer Zahl genau einen Bereich von 4 Bits abdeckt. Das führt zu einer sehr kompakten Darstellung von Zahlen. Am besten verdeutlicht man das an einem Beispiel:
Man sieht sehr deutlich, wie immer eine Ziffer einer hexadezimalen Zahl genau 4 Bit abbildet. Da sich die Bitanzahlen aller Zahlen, die wir bis hierher besprochen haben. durch 4 teilen lassen, und zwar unabhängig davon ob es ein traditionelles oder modernes Forth-System ist, ist die hexadezimale Darstellugn für Zahlen besonders günstig.
Bisher war nur von Zahldarstellungen die Rede, wie sieht es denn mit Buchstaben und Symbolen aus? Nun auch die werden natürlich durch Zahlen kodiert. Es ist eigentlich nur eine Frage wie man eine solche Zahl interpretiert. Bei Forth-Systemen (und nicht nur da) hat sich die sogenannte ASCII-Kodierung durchgesetzt. Aus heutiger Sicht ist sie zwar ziemlich veraltet und kennt auch nicht viele Zeichen, aber sie ist immer noch im Gebrauch und moderne Kodierungen wie UTF-8 unterscheiden sich bei den kleinen Zahlwerten in ihrer Kodierung nicht von der ASCII-Kodierung.
Will man nun wissen, welches Zeichen oder welcher Buchstabe einer Zahl entspricht, dann braucht man eine Tabelle, die sogenannte ASCII-Tabelle. Sie enthält 128 Zeichen, also genau so viele, wie man mit 7 Bits kodieren kann -- insofern bleiben wir in unserer Sichtweise, denn oben habe ich ja beschrieben, wie eine 8 Bit breite Zahl aussieht und wie man sie interpretiert, wenn man auch negative Zahlen haben will, und da tauchte die 128 auch schon mal auf. Aber nun die ASCII-Tabelle.
ASCII Zeichen und Codes | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Zeichen | Hex | Dez | Zeichen | Hex | Dez | Zeichen | Hex | Dez | Zeichen | Hex | Dez |
NUL | 00 | 0 | Leer | 20 | 32 | @ | 40 | 64 | ` | 60 | 96 |
SOH | 01 | 1 | ! | 21 | 33 | A | 41 | 65 | a | 61 | 97 |
STK | 02 | 2 | " | 22 | 34 | B | 42 | 66 | b | 62 | 98 |
ETK | 03 | 3 | # | 23 | 35 | C | 43 | 67 | c | 63 | 99 |
EOT | 04 | 4 | $ | 24 | 36 | D | 44 | 68 | d | 64 | 100 |
ENQ | 05 | 5 | % | 25 | 37 | E | 45 | 69 | e | 65 | 101 |
ACK | 06 | 6 | & | 26 | 38 | F | 46 | 70 | f | 66 | 102 |
BEL | 07 | 7 | ' | 27 | 39 | G | 47 | 71 | g | 67 | 103 |
BS | 08 | 8 | ( | 28 | 40 | H | 48 | 72 | h | 68 | 104 |
HT | 09 | 9 | ) | 29 | 41 | I | 49 | 73 | i | 69 | 105 |
LF | 0A | 10 | * | 2A | 42 | J | 4A | 74 | j | 6A | 106 |
VT | 0B | 11 | + | 2B | 43 | K | 4B | 75 | k | 6B | 107 |
FF | 0C | 12 | , | 2C | 44 | L | 4C | 76 | l | 6C | 108 |
CR | 0D | 13 | - | 2D | 45 | M | 4D | 77 | m | 6D | 109 |
SM | 0E | 14 | . | 2E | 46 | N | 4E | 78 | n | 6E | 110 |
SI | 0F | 15 | / | 2F | 47 | O | 4F | 79 | o | 6E | 111 |
DLE | 10 | 16 | 0 | 30 | 48 | P | 50 | 80 | p | 70 | 112 |
DC1 | 11 | 17 | 1 | 31 | 49 | Q | 51 | 81 | q | 71 | 113 |
DC2 | 12 | 18 | 2 | 32 | 50 | R | 52 | 82 | r | 72 | 114 |
DC3 | 13 | 19 | 3 | 33 | 51 | S | 53 | 83 | s | 73 | 115 |
DC4 | 14 | 20 | 4 | 34 | 52 | T | 54 | 84 | t | 74 | 116 |
NAK | 15 | 21 | 5 | 35 | 53 | U | 55 | 85 | u | 75 | 117 |
SYN | 16 | 22 | 6 | 36 | 54 | V | 56 | 86 | v | 76 | 118 |
ETB | 17 | 23 | 7 | 37 | 55 | W | 57 | 87 | w | 77 | 119 |
CAN | 18 | 24 | 8 | 38 | 56 | X | 58 | 88 | x | 78 | 120 |
EM | 19 | 25 | 9 | 39 | 57 | Y | 59 | 89 | y | 79 | 121 |
SUB | 1A | 26 | : | 3A | 58 | Z | 5A | 90 | z | 7A | 122 |
ESC | 1B | 27 | ; | 3B | 59 | [ | 5B | 91 | { | 7B | 123 |
FS | 1C | 28 | < | 3C | 60 | \ | 5C | 92 | | | 7C | 124 |
GS | 1D | 29 | = | 3D | 61 | ] | 5D | 93 | } | 7D | 125 |
RS | 1E | 30 | > | 3E | 62 | ^ | 5E | 94 | ~ | 7E | 126 |
US | 1F | 31 | ? | 3F | 63 | _ | 5F | 95 | DEL | 7F | 127 |
Die ersten 32 und das letzte Zeichen sind nicht-druckbare Steuerzeichen. Sie dienten vor allem in frühreren Zeiten dazu Fernschreiber zu steuern und die Kommunikation mit ihnen zu ermöglichen. So bedeutet z.B. EOT = End of text, also das Textende. Die meisten davon werden heutzutage nicht mehr verwendet, aber wenn man an einem Texterminal arbeitet, sind einige dennoch interessant.
BEL: Dieses Steuerzeichen gibt einen Signalton aus. (BEL steht für Bell, also Klingel).
BS: Dieses Steuerzeichen bewegt den Cursor um eine Stelle
nach rechts. Man kann das schön sehen, wenn man zum Beispiel mal
eingibt: 8 8 8 EMIT EMIT EMIT
. Machen sie einfach mal
und sehen sie sich das Ergebnis an.
LF: Damit wird der Cursor in die nächste Zeile gerückt. Eigentlich soll er dabei in der gleichen Spalte stehen bleiben. In den meisten Umgebungen rückt der Cursor dann aber auch sofort in die erste Spalte der nächsten Zeile.
FF: Damit wird eine ganze Seite ausgegeben. Dieses Zeichen ist mitunter nützlich, weil es damit auf manchen Terminals möglich ist den Bildschirm schnell zu löschen.
CR: Dieses Steuerzeichen bewegt den Cursor in die erste Spalte. Im Normalfall wird dabei die Zeile nicht gewechselt. Das ist vor allem dann interessant, wenn man zum Beispiel auf einem Textterminal einen Fortschirttsbalken anzeigen will.
Eins vorweg! Traditionelle Forth-Syteme hatten Zahlen, deren interne Darstellung 16 Bit breit waren. Daneben gab es noch Zahlen mit doppelter Genauigkeit, die 32 Bit breit waren. Bei modernen Forth-Systemen ist das nicht mehr so. Viele haben als 'normale' Zahlen 32 Bit breite und als doppelt breite dann 64 Bit breite. Ich werde im folgenden nicht weiter darauf eingehen. Ich werde allerdings, ebenfalls der Einfachheit halber, von 'einfachen Zahlen' und 'doppelten Zahlen' sprechen.
Zahlen in Forth können vorzeichenlos oder vorzeichenbehaftet sein. Das ist in vielen Fällen Interpretationssache und es gibt daher auch einige Wörter, die entsprechend dafür ausgerüstet sind einer bestimmten Interpretation zu dienen.
Das Wort .
ist schon bekannt und gibt einfach die
oberste Zahl auf dem Stack aus. In dieser Form behandelt das Wort
die Zahl als vorzeichenbehaftet.
Will man die Zahl ohne Vorzeichen ausgeben, dann gibt es das
entsprechende Wort: U.
. Das 'U' steht hier für
'unsigned', also vorzeichenlos. Entsprechend gibt es einige Wörter,
um mit Zahlen ohne Vorzeichen zu rechnen.
U* ( u1 u2 -- ud )
Dieses Wort multipliziert zwei vorzeichenlose Zahlen. Interessant ist, dass die beiden Faktoren einfache Zahlen sind, während das Ergebnis, das Produkt eine doppelte Zahl ist.
U/MOD ( ud u1 -- u2 u3 )
Dieses Wort teilt die doppelte, vorzeichenlose Zahl ud durch die einfache vorzeichenlose Zahl u1. Der Quotient und der Rest werden als einfache vorzeichenlose Zahlen auf den Stack zurück gelegt.
U< ( u1 u2 -- f )
Dieses Wort prüft vorzeichenlos, ob die Zahl u1 kleiner als die Zahl u2 ist. Das Ergebnis ist ein Flag.
Sie werden noch flexiblere Möglichkeiten die Zahlenbasis zu bestimmen kennen lernen. Trotzdem ist es schon mal sinnvoll zwei Befehle zu kennen:
DECIMAL ( -- )
und
HEX ( -- )
Das erste Wort schaltet Forth auf die dezimale Darstellung von Zahlen um und das zweite auf die hexadezimale. Diese beiden Darstellungen sind oft sinnvoll und daher gibt es in den meisten Forth-Systemen diese beiden Wörter. Man kann sie vor allem gut gebrauchen, wenn man eine Zahl in der jeweils anderen Darstellung sehen will, z.B.:
1234 HEX . 4D2 ok DECIMAL
Wird eine Zahl eingegeben und in der Zahl findet sich eines der Zeichen: , . / : -, dann wird diese Zahl als doppelte Zahl interpretiert (Beim Minuszeichen funktioniert das allerdings nur dann, wenn das Minuszeichen nicht am Anfang steht. Bei manchen Implementierungen funktioniert das allerdings ausschließlich mit einem Punkt! Die Position des Punktes (oder eines anderen Zeichens) hat dabei keinen Einfluss auf die Zahl selber.
1.23 12.3 123.
haben alle die gleiche Bedeutung. Es ist immer die '123', allerdings
nicht als einfache Zahl, sondern eben als doppelte Zahl. Auf dem
Stack finden sich nach dieser Eingabe die beiden einfachen Zahlen
123 und 0, oder eben die doppelte Zahl 123; je nach Sichtweise. Will
man die Zahl auch wieder als doppelte Zahl ausgeben, dann kann das
mit D.
geschehen.
Die einfache Ausgabe einer Zahl ist natürlich schon mal schön, aber sicherlich nicht das, was einen immer und in allen Situationen befriedigt. Wie sieht es aus, wenn man einmal alle Zahlen in gleicher Länge ausgeben will und diese dann unter Umständen vorne mit Nullen auffüllen will. Oder man hat doppelte Zahlen als Vielfaches einer gewünschten Ausgabegröße verwendet und will diese nun umwandeln. So wäre z.B. denkbar, dass man in Zentimetern gerechnet hat, das Ergebnis aber in Metern (inklusive Nachkommastellen) ausgeben will. Für all diese Sitautionen bietet Forth Worte, die bei der Ausgabe einer Zahl verwendet werden können.
Die Worte, mit denen man dabei arbeitet, sind grundsätzlich für doppelte Zahlen gedacht, die darüber hinaus auch noch als vorzeichenlos behandelt werden. Wie man vorzeichenbehaftete doppelte und auch einfache Zahlen mit diesen Werkzeugen ausgeben kann, kommt später. Zunächst einmal der einfache Fall.
Die Zauberworte heißen <#
, #
,
#S
und #>
.
Zuerst mal die einfachen Worte: <#
leitet die
Umwandlung einer doppelten Zahl in eine Folge von Ziffern ein.
Dieses Wort dient also alleine dazu Forth zu sagen: "Ab hier beginnt
die Uwanldung einer Zahl in Ziffern". Das Gegenstück,
#>
dient alleine dazu diesen Prozess zu beenden. Das
Wort legt dann auch alle erforderlichen Werte auf den Stack, damit
die Ausgabe der Ziffernfolge erfolgen kann. Das geschieht
üblicherweise mit dem Wort TYPE
, das später noch
eingehend beschrieben werden wird.
Interessant wird es zwischen diesen beiden Worten. Das einfachste
Wort, das man verwenden kann ist #
. Es fügt einfach zu
der bisher bestehenden Ziffernfolge eine weiter Ziffer hinzu. Man
sollte sich aber klar machen, dass die Ziffernfolge dabei von hinten
nach vorne aufgebaut wird. Wird dieses Wort das erste Mal verwendet,
dann wird demzufolge die Einerziffer in die Ziffernfolge eingefügt.
Das Wort arbeitet übrigens mit der aktuell eingestellten
Zahlenabasis!
Ein ähnliches Wort ist #S
. Es beendet die Umwandlung in
dem Sinne, dass alle noch nicht umgewandelten Ziffern 'auf einen
Schlag' umgewandelt werden.
Damit klar wird, wie das Ganze funktioniert hier ein paar Beispiele. Die erste Definition ist sehr einfach:
: UD. <# #S #> TYPE ;
Das einleitende <#
beginnt dem Umwandlungsprozess. Das
Wort #S
wandelt 'auf einen Schlag' alle noch fehlenden
Ziffern, das sind hier natürlich alle Ziffern, um und
#>
beendet das Ganze auch schon wieder. Das
abscließende TYPE
sorgt dann nur noch für die Ausgabe.
Was macht das Wort? Nun, es gibt einfach eine doppelte Zahl
vorzeichenlos aus.
1.2 ok UD. 12 ok
Nun ein kleines bisschen komplizierter. Die folgende Definition sieht folgendermaßen aus:
: 2D. <# # # #> TYPE ;
Was passiert hier? Einleitung und Beendigung der Umwandlung dürften
klar sein. Die beiden #
erzeugen jeweils eine Ziffer,
so dass zwei Ziffern erzeugt werden. Dann erfolgt die Ausgabe.
1.2 ok 2D. 12 ok 1.23 ok 2D. 23 ok 1234.5678 ok 2D. 78 ok
Wie man sieht werden tatsächlich immer nur die beiden letzten Ziffern der Zahl ausgegeben.
Nun, man kann damit zufrieden sein und sicherlich gibt es
Situationen, bei denen auch wirklich nur die letzten beiden Ziffern
einer Zahl interessieren. Interessanter wird allerdings die Sache
mit dem Wort HOLD
. Dieses Wort fügt einfach an der
Stelle, an der die Umwandlung gerade ist ein Zeichen ein. Welches
Zeichen hängt davon ab, welche Zahl gerade auf dem Stack liegt. Man
betrachte das folgende Beispiel:
: DATUM <# # # 46 HOLD # # 46 HOLD # # #> TYPE ; 12.06.14 ok DATUM 12.06.14 ok
Durch das 46 HOLD
werden in die Ausgabe Punkte
eingefügt und schon kann eine doppelte Zahl als Datum verstanden
werden. Hier zeigt sich zum ersten Mal, dass Forth zwar
(traditionell) nur Ganzzahlen kennt, mit diesen aber wesentlich mehr
möglich ist, als man vielleicht im ersten Moment denkt.
Bisher haben wir nur vorzeichenlose Zahlen ausgegeben. Wie sieht es
mit Zahlen aus die ein Vorzeichen haben und dieses auch ausgegeben
werden soll? Dazu sollte man sich klar machen, dass eine doppelte
Zahl in Form zweier einfacher Zahlen auf dem Stack liegt und zwar
der 'höherwertige' Teil oben auf dem Stack. Um nun ein Vorzeichen zu
schreiben, braucht man noch einen dritten Wert auf dem Stack. Das
Wort SIGN
wertet diesen Wert aus und fügt, wenn er
negativ ist, ein Minuszeichen in die Ziffernfolge ein. Ein etwas
skurriles Beispiel:
: SKURRIL SWAP OVER DABS <# # # ROT SIGN #S #> TYPE ;
Das SWAP OVER DABS
sorgt dafür, dass die Werte so auf
dem Stack liegen, wie sie gebraucht werden. Der höherwertige Teil
der doppelten Zahl liegt oben und wird in den Absolutwert gewandelt.
Der vorzeichenbehaftete Teil, der an dritter Stelle auf dem Stack
liegt wird bei Bedarf durch ROT
nach oben geholt, wo er
von SIGN
ausgewertet wird.
Dann werden die ersten beiden Ziffern ausgegeben (Einer- und Zehnerstelle im Dezimalsystem). Dann kommt das Vorzeichen, wenn erforderlich und dann der Rest der Ziffern.
Es gibt eine ganze Reihe von Wörtern, die mit doppelten Zahlen umgehen. Ich will diese nicht alle hier beschreiben, da sie sich eigentlich selbst erklären. Sie sind größtenteils in der Wortliste beschrieben, allerdings nicht in allen Implementationen von Forth vorhanden. Sie sollten in der Dokumentation ihres Forth nachsehen.