3. Datentypen, Ausdrücke und Operatoren Programm muß i.a. Daten zwischenspeichern Speicherplatz muß bereitgestellt werden, der ansprechbar, reserviert ist Ablegen & Wiederfinden in höheren Programmiersprachen Arbeit mit bestimmten Speicherplätzen über Vergabe von Namen = Variable 3.1 Variable im Programm definierter Name für einen (beim Programmlauf) zu reservierenden Speicherplatz im Arbeitsspeicher für Werte eines bestimmten Typs Arbeit mit Variablen (Zuweisungen von Werten, Berechnungen) bedeutet Zugriff auf den zugehörigen Speicherplatz Deklaration in C: Variablentyp Variablenname; Beispiel: int i; Deklaration der integer Variablen mit Namen i d.h. Bereitstellen von i.a. 4 Byte Speicherplatz (=32 bit) im Arbeitsspeicher i=3; Speicherung des Wertes 3=2^0+2^1( 11 binär) auf dem reservierten Speicherplatz 1 000............0011 i Arbeitspeicher in vielen höheren Programmiersprachen ist zur Reservierung eines Speicherplatzes, d.h. der Einführung einer neuen Variablen ein Variablentyp mit anzugeben der Variablentyp sagt dem Compiler wieviel Speicherplatz benötigt wird und wie er zu strukturieren ist (zu interpretieren)
3.2 Elementare Datentypen Es gibt drei qualitativ unterschiedliche Basistypen von Daten: ganze Zahlen, reelle Zahlen und alphanumerische Zeichen Die Basistypen werden i.a. in eine Reihe von Untertypen ( die sogenannten elementaren Typen) aufgesplittet. Die Bezeichnungen der Typen ist sprachabhängig, z.b. ganze Zahlen : int, long, short (in C) integer, longint, word (in PASCAL) INTEGER (in FORTRAN) reelle Zahlen : float, double (in C) real, extended (in PASCAL) REAL, DOUBLE (in FORTRAN) Zeichen : char (in C und in PASCAL) CHARACTER (in FORTRAN) (1) Integertypen in C: int short int long int kurz: short kurz: long Speicherbedarf: Speicherplatz für int = Wortlänge des Rechners heutzutage auf dem PC meist 4 Byte = 32 Bit max. bzw. min. darstellbare Zahl: 32 Stellen = 32 Möglichkeiten für 0 oder 1 2^32 verschiedene Zahlen darstellbar Sinnvolle Möglichkeiten: (A) das erste Bit gleich 0 bedeutet positive Zahl 1 bedeutet negative Zahl alle anderen Bits repräsentieren den Betrag der ganzen Zahl Diese Darstellungsweise ist auf den ersten Blick sehr sympathisch, hat aber praktische Nachteile, besonders bei der Addition negativer Zahlen.
(B) Deshalb: Kodierung in sog. Zweierkomplementdarstellung Für negative ganze Zahlen bedeutet das: Die Bitfolge der zugehörigen betragsgleichen positiven Zahl wird logisch negiert, d.h. aus jeder 0 wird eine 1 und aus jeder 1 wird eine 0. Anschließend wird zu der so erhaltenen Zahl eine 1 addiert. Beispiel betrachten hier einen max. Umfang von 4 Bit: < C Typ short bei 32 Bit ist der Bereich: 2 31 bis 2 31 1 2 31 negative Zahlen, 0 und 2 31 1 positive Zahlen Maximale Zahl = 2 31 1 ~ 2 Mio. Unterschiede zwischen long int, int, short int sind compilerabhängig (2) Gleitkomma Typen Darstellung reeller Zahlen Typen in C: float... einfache Genauigkeit double... doppelte Genauigkeit Was bedeutet einfach, was bedeutet doppelt genau? Und was ist eigentlich eine Gleitkommazahl? anderer Name: Maschinenzahl Festkommadarstellung z.b. : 321.45 Gleitkommadarstellung : 3.2145*10 2 bzw. 0.32145*10 3 Prinzipielles Problem: Da nur beschränkte Anzahl an Bytes zur Darstellung zur Verfügung steht, ist in der Regel eine genaue Darstellung nicht möglich. Irrationale Zahlen wie 2 oder die Eulersche Zahl e intern nie exakt darstellbar. aber auch viele andere nicht.
interne Darstellung im Rechner: x = ( 1) v 0.m 1 m 2 m L 2 p Vorzeichen Mantisse Basis + Exponent m i... sind 0 oder 1, m 1 = 1 p... ist der Exponent (selbst wieder intern binär gespeichert), m p M (d.h. Beschränkt) v... ist 0 oder 1 d.h. das Komma wird immer an der selben Stelle plaziert. Speicherplatz: Für die Codierung im Computer ist IEEE Standard üblich für Gleitkommazahl in einfacher Genauigkeit: 4Byte = 32 Bit v e 7... e 0 m 2...... m 24 Vorzeichenbit Exponent Mantisse m 1 muß nicht gespeichert werden, da stets = 1 für Gleitkommazahl in doppelter Genauigkeit: 8Byte = 64 Bit v e 10...... e 0 m 2............... m 53 Vorzeichenbit Exponent Mantisse Typ Max. /pos. Min. Rel. Rechengenauigkeit eps float double ~ 10 38 / ~ 10 38 ~ 0.6 10 7 ~ 10 308 / ~ 10 308 ~ 1.1 10 16 z.b. MAXFLOAT ~ 2 M, M = 2 7 = 128 2 M = 2 128 ~ 10 38 Mantisse bestimmt die Rechengenauigkeit Exponent bestimmt den Wertebereich
Grenzen der Maschinenzahlen: Unterlauf (underflow): x < eps Rundung x=0 Überlauf (overflow) x > MAX_Typ compilerabhängige Reaktion Abbruch + Fehlermeldung falsches Ergebnis x=inf oder x=nan Bei der Darstellung selbst einfachster Dezimalzahlen treten schon Rundungsfehler auf. Zusätzlich ergeben sich beim Rechnen weitere Rundungsfehler: Bei Addition zweier (positiver) Gleitkommazahlen werden folgende Einzelschritte ausgeführt: 1. Erkennen von Mantisse und Exponent beider Zahlen 2. Vergleichen der Exponenten 3. Angleichen der Exponenten 4. Anpassen der Mantisse der Zahl, deren Exponent bei der Exponentenanpassung verändert wurde 5. Addition der Mantissen, ggf. Änderung des gemeinsamen Exponenten (bei Überlauf der Mantisse) 6. Normalisierung des Ergebnisses (gleitendes Komma) Beispiel: Die Eulersche Zahl e = 2.71828182846... ist Grenzwert der Zahlenfolge a 1, a 2, a 3,... a n,... mit a n = (1 + 1/ n ) n Es gilt a n < a n+1 (Monotonie!) und a n < e für alle natürlichen Zahlen n. Folglich erhält man (mathematisch betrachtet) mit wachsendem n einen immer besseren Näherungswert für e. Auf dem Computer sieht aber die Addition von (1 + 1 / n) (bei einfacher Genauigkeit float und n=2 24 ) so aus: 1 = 0.100...000 * 2 1 bei 23 Bit Mantisse 1 / n = 0.100...000 * 2 25 Nach Exponentenanpassung ergibt sich für die Addition: 1 = 0.100...000 * 2 1 + 1 / n = 0.000...0001 * 2 1 die letzte 1 ist nicht abgespeichert, da nur 23 Bit verfügbar = 0.100... 000 * 2 1 d.h. für n = 2 24 = 16777216 ergibt sich nach Ausführung der Addition (1 + 1 / n) = 1 und folglich auch für (1 + 1 / n) ^n = 1 also keine Konvergenz zu e!!!