Allgemeine Grundlagen der Programmierung


Kapitel 2: Zahlensysteme


Inhaltsverzeichnis

Dieses Buch ist unter einer Creative Commons-Lizenz lizensiert.


2.1 Allgemeines

Eigenheiten von Zahlensystemen

Für den Nicht-Programmierer ist oft gar nicht bewußt, dass es verschiedene Zahlensysteme gibt und dass das im Alltag verwendete Dezimalsystem nur eines von unendlich vielen ist. Zahlensysteme werden über Zeichenvorrat und Stellenwert definiert. Der Zeichenvorrat repräsentiert die zugelassenen Zeichen im Zahlensystem. Das sind im Dezimalsystem die Ziffern 0, 1, 2, 3, 4, 5, 6, 7, 8 und 9. Der Stellenwert legt fest, welche Basiszahl mit der Stelle einer Ziffer potenziert wird. Die Basiszahl im Dezimalsystem ist 10.

Der Wert der drei Ziffern 456 wird im Dezimalsystem also genaugenommen wie folgt berechnet: Die Stelle ganz rechts ist die 0. Die Stelle links daneben, auf der die Ziffer 5 steht, ist die 1. Die Stelle ganz links ist die 2. Weitere Stellen würden mit linear aufsteigenden Zahlen beschrieben werden. Wie Sie bereits wissen, wird mit der Stellenbeschreibung jeweils die Basiszahl potenziert. Die Stelle 0 wird also zu 100, die Stelle 1 wird zu 101 und die Stelle 2 wird zu 102. Das jeweilige Ergebnis wird mit der Ziffer an der jeweiligen Stelle multipliziert. An der Stelle 0 steht im Beispiel die Ziffer 6, an der Stelle 1 die Ziffer 5 und an der Stelle 2 die Ziffer 4. Die gesamte Rechnung heisst also 6*100+5*101+4*102. Das ergibt 6*1+5*10+4*100, was wiederum 6+50+400 ergibt und zur Lösung 456 führt.

Wenn Sie eine Zahl wie 456 im Dezimalsystem sehen, brauchen Sie natürlich nicht jedesmal die Berechnung ausführen. Sie wissen sofort, was die Zahl bedeutet, weil Sie es gewohnt sind, im Dezimalsystem zu arbeiten. Sie müssen sich aber die Regeln zum Berechnen des Wertes einer Zahl vergegenwärtigen, wenn Sie Zahlen aus anderen Zahlensystemen vor sich haben. Oder können Sie sofort sagen, was die Hexadezimalzahl FA oder die Binärzahl 10011 für Werte darstellen?


2.2 Zahlensysteme und der Computer

Computer kennen keine Buchstaben

Wieso müssen Sie sich eigentlich mit Zahlensystemen beschäftigen? Sie sind doch Programmierer und kein Mathematiker. Leider haben Sie es als Programmierer mit einer Maschine zu tun, die ausschließlich mit Zahlen arbeitet. Computer sind wahre Zahlenakrobate. Wenn Sie dem Computer irgendwas direkt sagen wollen, dann müssen Sie sich in Zahlen ausdrücken. Das nächste Problem ist, dass der Computer zwar grundsätzlich Zahlen versteht, es aber vorzieht, in anderen Zahlensystemen zu arbeiten als Sie. Während Sie im Alltag mit dem Dezimalsystem gut zurechtkommen, verwendet Ihr Computer am liebsten das Binärsystem. Und damit es nicht zu einfach wird, lassen sich Zahlen im Binärsystem leider nicht allzu einfach in Zahlen des Dezimalsystems umwandeln. Nachdem das Binärsystem für menschliche Belange äußerst unangenehm zu handhaben ist, verwenden Programmierer lieber das Hexadezimalsystem. Denn vom Binärsystem ins Hexadezimalsystem sind es nur ein paar Schritte, und die Handhabung von Hexadezimalzahlen fällt doch wesentlich einfacher als die von Binärzahlen.

Beachten Sie, dass moderne Programmiersprachen normalerweise ohne Probleme die Angabe von Dezimalzahlen ermöglichen, wenn an irgendeiner Stelle im Programm Zahlen angegeben werden müssen. Sie sind also als Programmierer grundsätzlich nicht gezwungen, sich mit Binär- oder Hexadezimalzahlen herumzuschlagen. Dennoch kann es in vielen Fällen hilfreich sein zu wissen, wie Zahlen im Binär- und Hexadezimalsystem aussehen und gebildet werden.


2.3 Das Binärsystem

Nullen und Einser

Vielleicht kennen Sie den Spruch, dass Computer nur Nullen und Einsen kennen. Nullen und Einser sind die einzigen beiden gültigen Zeichen im Binärsystem. Der Zeichenvorrat des Binärsystems besteht also aus 0 und 1. Wenn Sie nun erfahren, dass der Stellenwert im Binärsystem 2 ist, haben Sie alle Informationen, die Sie brauchen, um den Wert von Binärzahlen zu errechnen.

Sehen Sie sich zum Beispiel die Binärzahl 10011 ein. An der Stelle 0 steht eine 1, an der Stelle 1 ebenfalls eine 1, an der Stelle 2 eine 0, an der Stelle 3 auch eine 0 und an der Stelle 4 wiederum eine 1. Stellen werden immer von rechts nach links beginnend bei Null hochgezählt. Da der Stellenwert im Binärsystem 2 ist, sieht die Berechnung wie folgt aus: 1*20+1*21+0*22+0*23+1*24. Das ergibt 1*1+1*2+0*4+0*8+1*16, was wiederum 1+2+0+0+16 ergibt. Die Lösung lautet also 19. Die Binärzahl 10011 stellt im Dezimalsystem den Wert 19 dar.

Wie gelangt man nun von der Dezimalzahl 19 zur entsprechenden Binärdarstellung? Dividieren Sie die Dezimalzahl durch den Stellenwert des Binärsystems, nämlich 2, und notieren Sie den Restwert. Divideren Sie das Ergebnis wiederum durch 2 und notieren Sie wieder den Restwert. Irgendwann gelangen Sie bei Null an. Sie erhalten nun die Binärzahl, wenn Sie die erhaltenen Restwerte in eine Reihe stellen. Beispiel gefällig?

19/2=9 Rest 1. 9/2=4 Rest 1. 4/2=2 Rest 0. 2/2=1 Rest 0. 1/2=0 Rest 1. Schreiben Sie nun die Restwerte von rechts nach links in eine Reihe und Sie erhalten 10011.


2.4 Das Hexadezimalsystem

Zahlen und ein paar Buchstaben

Im Hexadezimalsystem steht folgender Zeichenvorrat zur Verfügung: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E und F. Während das Binärsystem im Gegensatz zum Dezimalsystem weniger Informationszustände an einer Stelle speichern kann - nämlich nur zwei -, können im Hexadezimalsystem mehr Informationszustände gespeichert werden - nämlich 16. Die ersten zehn Zeichen sind mit denen im Dezimalsystem identisch. Für den Dezimalwert 10 benötigen Sie im Dezimalsystem aber zwei Stellen. Im Hexadezimalsystem können Sie diesen Wert an einer Stelle durch das Zeichen A ausdrücken. Erst ab Zahlen oberhalb des Dezimalwerts 15, der im Hexadezimalsystem dem Zeichen F entspricht, wird eine zweite Stelle benötigt.

Wie sieht nun die Umwandlung einer Hexadezimalzahl, zum Beispiel FA, ins Dezimalsystem aus? Dazu benötigen Sie neben dem Zeichenvorrat noch den Stellenwert. Der ist im Hexadezimalsystem 16. Und schon können Sie loslegen. An der Stelle 0 steht das Zeichen A, an der Stelle 1 das Zeichen F. Die Berechnung sieht also wie folgt aus: A*160+F*161. Nachdem das Dezimalsystem keine Buchstaben verwendet, werden die Zeichen aus dem Hexadezimalsystem einfach durch die Werte aus dem Dezimalsystem ersetzt. Die neue Rechnung heißt also: 10*160+15*161. Daraus folgt 10*1+15*16, was als Ergebnis 250 ergibt.

Die Umrechnung einer Dezimalzahl in eine Hexadezimalzahl erfolgt nach demselben Schema wie bei Binärzahlen. Sie dividieren die Dezimalzahl durch den Stellenwert, also 16, und notieren den Rest. Dann wiederholen Sie den Schritt, indem Sie das Ergebnis der eben durchgeführten Berechnung wiederum durch 16 dividieren. Dies wiederholt sich, bis Sie bei Null angelangt sind. Im letzten Schritt wandeln Sie dann gegebenenfalls zweistellige Restwerte in die Buchstaben aus dem Zeichenvorrat des Hexadezimalsystems um.

250/16=15 Rest 10. 15/16=0 Rest 15. 10 entspricht A, 15 entspricht F. In der richtigen Reihenfolge - nämlich von rechts nach links - ergibt dies die Hexadezimalzahl FA.


2.5 Vom Binärsystem zum Hexadezimalsystem und zurück

Zahlenzauber

Sie kennen nun das Binärsystem und das Hexadezimalsystem. Wenn Sie sich erinnern, habe ich Ihnen das Hexadezimalsystem verkauft als das System, in das sich Binärzahlen besonders leicht transferieren lassen. Inwiefern läßt sich aber die Binärzahl 11101010 besonders leicht in die Hexadezimalzahl EA umwandeln?

Der Trick ist, dass jeweils vier Stellen im Binärsystem eine Stelle im Hexadezimalsystem darstellen. Das heißt, die Binärzahl 0001 entspricht im Hexadezimalsystem 1, 0010 entspricht 2, 0011 entspricht 3 bis hin zu 1110 entspricht E und 1111 entspricht F. Für die nächsthöhere Zahl brauchen Sie sowohl im Binärsystem als auch im Hexadezimalsystem eine neue Stelle. Wenn Sie sich nun die Binärzahl 11101010 ansehen, besteht diese aus acht Stellen. Nachdem jeweils vier Stellen im Binärsystem eine Stelle im Hexadezimalsystem darstellen, wissen Sie bereits, dass Sie genau zwei Stellen brauchen. Schauen wir uns die ersten vier Stellen an: 1110. Per Umrechnung ins Dezimalsystem kommen Sie zum Wert 14 (diese Umrechnungen brauchen Sie mit ein wenig Erfahrung nicht mehr durchführen, da Sie den Wert sofort erkennen). 14 ist im Hexadezimalsystem E. Damit steht das erste Zeichen schon mal fest. Die nächsten vier Binärziffern sind 1010. Per Umrechnung ins Dezimalsystem gelangen Sie zum Wert 10. 10 entspricht im Hexadezimalsystem dem Zeichen A. Damit ist die Umrechnung komplett: Die Binärzahl 11101010 entspricht im Hexadezimalsystem EA.

Nachdem Sie nun den Trick raushaben, fällt auch die Umrechnung einer Hexadezimalzahl ins Binärsystem nicht mehr schwer. Sie wandeln einfach jede Stelle der Hexadezimalzahl in vier Stellen einer Binärzahl um. Nachdem die Hexadezimalzahl EA aus zwei Stellen besteht, muss die entsprechende Binärzahl aus acht Stellen bestehen. An der Stelle ganz links steht das Zeichen E, was dem Dezimalwert 14 entspricht. Per Umrechnung gelangen Sie zur Darstellung 1110. Das zweite Zeichen ist A, was dem Dezimalwert 10 entspricht. Der Dezimalwert 10 sieht in Binärform wie folgt aus: 1010. Damit ist klar, dass die Hexadezimalzahl EA in Binärform 11101010 lautet.


2.6 Zahlensysteme in der Praxis

Beim Zahlarzt in der Praxis

Standardmäßig werden Zahlen, die Sie in Quellcodes zur Entwicklung von Computer-Programmen angeben, als Dezimalzahlen geschrieben. Über spezielle Kennzeichnungen können Sie jedoch auch Hexadezimalzahlen angeben. Binärzahlen selber werden seltener unterstützt, nachdem die Schreibweise aus Nullen und Einsen sehr fehleranfällig ist und mit Hexadezimalzahlen eine bessere Lösung zur Verfügung steht.

int i = 0x14; 

Obiges Code-Beispiel ist in der Programmiersprache C geschrieben. Einer Variablen i vom Typ int wird die Hexadezimalzahl 14 zugewiesen. Damit der Compiler erkennt, dass es sich um eine Hexadezimalzahl handelt, wird in C das Kürzel 0x dem Wert vorangestellt.

Programmiersprachen wie C stellen noch eine andere Notation zur Verfügung.

int i = 014; 

Durch das Voranstellen von 0 wird die Zahl im Oktalsystem notiert. Das Oktalsystem besitzt den Zeichenvorrat 0, 1, 2, 3, 4, 5, 6 und 7 und den Stellenwert 8. Es hat ähnliche Vorteile wie das Hexadezimalsystem: Jeweils drei Binärstellen können in eine Oktalstelle umgewandet werden (beim Hexadezimalsystem vier Binärstellen in eine Hexadezimalstelle). Die Bedeutung in der Praxis ist jedoch sehr gering.

Wie Sie bereits aus Kapitel 1, Programmiersprachen wissen, stellen Programmiersprachen unter anderem bitweise Operatoren zur Verfügung. Mit diesen Operatoren können Sie einzelne Bits bearbeiten. Bits sind hierbei Informationen, die lediglich zwei Zustände annehmen können: Also wahr oder falsch, gesetzt oder nicht gesetzt, 1 oder 0. Binärzahlen eignen sich hervorragend zur Darstellung von Bits.

<html>
  <head>
    <title>Allgemeine Grundlagen der Programmierung</title>
    <script type="text/javascript">
      var i = 0xC, j = 0x5; 

      alert(i & j); 
    </script>
  </head>
  <body>
  </body>
</html>

Im obigen Javascript-Code werden zwei Variablen namens i und j definiert. Den Variablen werden die Hexadezimalzahlen C und 5 zugewiesen. Die Darstellung im Binärsystem der beiden Zahlen ist 1100 und 0101. Die zwei Variablen werden mit dem &-Operator verknüpft, der UND-Operator genannt wird. Dieser bitweise Operator arbeitet wie folgt: Bits an den gleichen Stellen werden miteinander verglichen. Sind beide Bits gesetzt - ist also an beiden Stellen die 1 vorhanden - wird das entsprechende Bit im Ergebnis ebenfalls auf 1 gesetzt.

Sie müssen nun lediglich Bits an den jeweils gleichen Stellen der beiden Variablen vergleichen: An der Stelle 0 der Variablen i befindet sich eine 0, in der Variablen j eine 1. Die Stelle 0 im Ergebnis wird also auf 0 gesetzt. An der Stelle 1 in der Variablen i befindet sich wieder eine 0, in der Variablen j auch. Die Stelle 1 im Ergebnis wird also auf 0 gesetzt. An der Stelle 2 in der Variablen i befindet sich eine 1, in der Variablen j ebenfalls. Daher wird die Stelle 2 im Ergebnis auf 1 gesetzt. Die Stelle 3 ist nur in einer der beiden Variablen gesetzt, also wird im Ergebnis an der Stelle 3 eine 0 stehen. Das Ergebnis des bitweisen Operators sieht also wie folgt aus: 0100. Dies entspricht 4 im Hexadezimal- und auch im Dezimalsystem.

<html>
  <head>
    <title>Allgemeine Grundlagen der Programmierung</title>
    <script type="text/javascript">
      var i = 0xC, j = 0x5; 

      alert(i | j); 
    </script>
  </head>
  <body>
  </body>
</html>

Ein anderer bitweiser Operator ist |, genannt ODER-Operator. Hier gilt die Regel: Im Ergebnis ist dann ein Bit gesetzt, wenn mindestens ein Bit in einem Operand gesetzt ist. Im Gegensatz zum &-Operator müssen nicht beide Bits gesetzt sein. Um zum Ergebnis zu gelangen, müssen wieder einzelne Bits miteinander verglichen werden: An der Stelle 0 befindet sich in der Variablen i eine 0, in der Variablen j eine 1. Daher wird im Ergebnis an der Stelle 0 eine 1 stehen. An der Stelle 1 befindet sich in der Variablen i eine 0, in der Variablen j ebenfalls. Die Stelle 1 im Ergebnis trägt daher auch eine 0. An den Stellen 2 und 3 der Variablen i und j befindet sich jedesmal mindestens eine 1, so dass auch im Ergebnis die Stellen 2 und 3 auf 1 gesetzt werden. Das Resultat ist also die Binärzahl 1101, die im Hexadezimalsystem D und im Dezimalsystem 13 entspricht.

<html>
  <head>
    <title>Allgemeine Grundlagen der Programmierung</title>
    <script type="text/javascript">
      var i = 0xC, j = 0x5; 

      alert(i ^ j); 
    </script>
  </head>
  <body>
  </body>
</html>

Der ^-Operator wird EXKLUSIVES-ODER genannt. Im Ergebnis ist nur dann ein Bit auf 1 gesetzt, wenn auch nur genau ein Bit in den beiden Operanden auf 1 gesetzt ist. Sind die Bits in beiden Operanden auf 1 gesetzt, so steht im Ergebnis an gleicher Stelle eine 0.

<html>
  <head>
    <title>Allgemeine Grundlagen der Programmierung</title>
    <script type="text/javascript">
      var i = 0xC; 

      alert(~i); 
    </script>
  </head>
  <body>
  </body>
</html>

Ein recht einfacher bitweiser Operator ist ~. Im Gegensatz zu den anderen Operatoren benötigt er lediglich einen einzigen Operanden, der hinter ~ angegeben wird. Dieser Operator dreht die Bits einfach um: Aus auf 1 gesetzten Bits werden auf 0 gesetzte Bits, aus auf 0 gesetzten Bits werden auf 1 gesetzte Bits. Das heißt, aus 1100 wird 0011, was der Hexadezimalzahl 3 entspricht (die auch gleichzeitig Dezimalzahl ist). Der bitweise Operator ~ wird NICHT-Operator genannt.

Sollte Ihr Browser bei der Ausführung des Beispiels anstelle der 3 eine negative Zahl als Ergebnis anzeigen, so ist dies völlig korrekt. Unterschiedliche Ergebnisse hängen von der Bandbreite der Variablen i ab. Wundern Sie sich nicht, sondern gehen Sie von obiger Beschreibung aus und ignorieren Sie gegebenenfalls ein negatives Ergebnis.


2.7 Aufgaben

Übung macht den Meister

Sie können die Lösungen zu allen Aufgaben in diesem Buch als ZIP-Datei erwerben.

  1. Wandeln Sie die Dezimalzahl 40019 mit Stift und Papier in die entsprechende Hexadezimalzahl und in die entsprechende Binärzahl um.

  2. Wandeln Sie die Oktalzahl 143215 mit Stift und Papier in die entsprechende Hexadezimalzahl und in die entsprechende Binärzahl um.

  3. Schreiben Sie ein Programm in Javascript, das die beiden Werte aus den ersten zwei Aufgaben mit den bitweisen Operatoren &, | und ^ verknüpft. Sagen Sie die Ergebnisse der bitweisen Verknüpfungen als Dezimalwerte voraus, bevor Sie das Programm ausführen.

  4. Für Experten: Schreiben Sie ein Programm in Javascript, das vom Anwender eine Dezimalzahl entgegennimmt und diese in eine Hexadezimalzahl umrechnet. Sie benötigen für die Realisierung des Programms den %-Operator. Dieser Operator dividiert zwei Werte und gibt als Ergebnis den ganzzahligen Restwert zurück.

    Zur Realisierung des Programms benötigen Sie eine Schleife, die wiederholt eine Division ausführt und die Restwerte zur Hexadezimalzahl zusammenstellt. Vergessen Sie nicht, zweistellige Restwerte in Buchstaben umzuwandeln.