Programmierkurs Kapitel 4 Datentypen Arten von Datentypen

Werbung
Kapitel 4
Programmierkurs
Datentypen und Operatoren
Einschub Binärdarstellung
Ganzzahlige Numerische Datentypen
Logischer Datentyp
Typumwandlung
Rationale numerische Datentypen (Gleitkommazahlen)
Der alphanumerische Datentyp char
Birgit Engels, Anna Schulze
ZAIK
Universität zu Köln
WS 07/08
1 / 62
Datentypen
2
Arten von Datentypen
Wir unterscheiden hier wieder Arten von Datentypen:
Bei der Deklaration einer Variablen legt der Datentyp fest:
Primitive Datentypen:
Welche Werte die Variable annehmen kann.
I
Wieviel Speicherplatz die Variable belegen darf.
I
I
Welche Operationen auf die Variable angewendet werden
dürfen.
I
Ganzzahlige numerische Datentypen: int, long, ...
Logischer Datentyp: boolean
Rationale numerische Datentypen: float, double, ...
Alphanumerischer Datentyp: char
Vordefinierte Datentypen (z.B. : BufferedReader,
InputStreamReader)
Damit auch implizit in welchen Anweisungen sie vorkommen
kann (später).
Selbstdefinierte Datentypen (z.B. : Greets, Age)
3 / 62
4
Vor-/Selbstdefinierte Datentypen
Primitive Datentypen
Bei sogenannten “primitiven” Datentypen tritt die
Objektorientierung zunächst in den Hintergrund.
Sie heissen auch “Standarddatentypen”, da sie von quasi allen
Programmiersprachen mehr oder weniger äquivalent implementiert
sind.
Vor-/ Selbstdefinierte Datentypen stehen in engem Zusammenhang
mit Objektorientierung und werden daher später behandelt.
Vorgriff Klasse - Datentyp - Objekt:
Jede (wie bisher gesehen) definierte Klasse XYZ spezifiziert einen
eigenen Datentyp XYZ.
Es können Variablen mit diesem Datentyp als deklariert werden:
XYZ beispiel
Solche Variablen sind Objekte vom Typ XYZ und werden
Instanzen der Klasse XYZ genannt.
Im einfachsten Fall möchte man mit Variablen eines solchen
Datentyps ganze oder natürliche Zahlen darstellen.
Diese müssen im Computer natürlich binär gespeichert werden.
Reserviert ein solcher Datentyp n Bits Speicherplatz, so kann man
entweder
die 2n natürlichen Zahlen von 0 bis 2n − 1 oder
die 2n ganzen Zahlen von −2n−1 bis 2n−1 − 1 darstellen.
5 / 62
Natürliche Zahlen: Binärcodierung
Darstellung natürlicher Zahlen mit n
Die Zahlen von 0 bis 2n − 1.
Beispiel: n = 3
Dezimal Binär Dezimal Binär
0
000
1
001
3
011
4
100
6
110
7
111
6
Natürliche Zahlen: Zahlenkreis
Bits:
Dezimal
2
5
8
Addiere: 111 + 001 = 1000
n = 3 Bits: Höchstes Bit fällt weg:
(111 + 001 = 000)bin (7 + 1 = 0)dez
Binär
010
101
-
Fehler durch “Überlauf” !
0
7
000
111
8 = 23 ist mit 3 Bits (wegen der Darstellung der 0) nicht
mehr darstellbar.
6
110
8 wäre in Binärdarstellung mit 4 Bits: 1000
010
Das erste Bit entfällt, bei 3-Bit-Darstellung und 000
entspricht bereits der Codierung der 0: Überlauf.
2
011
101
5
1
001
100
3
4
7 / 62
8
Ganze Zahlen - Vorzeichencodierung
Ganze Zahlen - Einerkomplement
2. Möglichkeit: Einerkomplement
(−x ist bitweises Komplement von +x).
Beispiel: n = 3
Dezimal Binär Dezimal Binär
0
000
1
001
2
010
3
011
-0
111
-1
110
-2
101
-3
100
Gleicher Darstellungsbereich wie Vorzeichendarstellung
Zur Darstellung von positiven ganzen Zahlen muss nun noch die
für negative hinzu kommen.
1. Möglichkeit: 1. Bit codiert
Beispiel: n = 3
Dezimal Binär Dezimal
0
000
1
2
010
3
-0
100
-1
-2
110
-3
Vorzeichen.
Darstellung ganzer Zahlen von
Binär
001
011
101
111
2n−1
0 doppelt codiert
bis
2n−1
− 1.
1. Bit codiert immernoch Vorzeichen.
0 doppelt codiert.
1. und 2. Möglichkeit: Schwierige Implementierung von
arithmetischen Operationen, da jede Zahl (positiv, negativ) anders
interpretiert werden muss. Daher: Zweierkomplementdarstellung.
9 / 62
Ganze Zahlen - Zweierkomplement
10
Ganze Zahlen: Zahlenkreis im Zweierkomplement
Zweierkomplement formal definiert:
Höchstwertiges Bit bn hat Wertigkeit −1
3. Möglichkeit: Zweierkomplement
(−x ist bitweises Komplement von +x + 1).
Beispiel: n = 3
Dezimal Binär Dezimal Binär
0
000
1
001
2
010
3
011
-1
111
-2
110
-3
101
-4
100
0 nicht mehr doppelt codiert!
Alle anderen Bits bi 1, d.h.
x = −bn ∗ 2n + bn−1 ∗ 2n−1 + · · · + b0
Beispiel:
110 = −1 ∗ 22 + 1 ∗ 21 + 0 ∗ 20 = −4 + 2 + 0 = −2
0
-1
000
111
-2
1
001
110
010
2
Gewonnene “freie” Codierung für zusätzliche negative Zahl −4
011
101
−4 statt +4 : 1. Bit codiert immernoch Vorzeichen.
-3
100
3
-4
11 / 62
12
4.2 Ganzzahlige numerische Datentypen
Typ
byte
short
int
long
Anz Bits
8
16
32
64
Min
-128
-32768
-2147483648
< −1018
Gültiger Zahlenbereich (Over-/Underflow)
Werden die Grenzen (min./max. darstellbare Zahl) des gültigen
Zahlenbereichs eines Datentyps z.B. durch Zuweisung einer zu
großen oder zu kleinen Zahl zu einer Variable des Typs verletzt
entsteht ein sogenannter Über-/Unterlauf bzw. Over-/Underflow
(Vorstellung: Bitdarstellung als Kreis → Übung):
Max
127
32767
2147483647
> 1018
Overflow:
Wir sehen, dass für Standarddatentypen
n = 8 < 16 < 32 < 64 < . . . ist.
Diese n Bits werden in Java jeweils für die ganzen
(vorzeichenbehaftete) Zahlen von −2n−1 bis 2n−1 − 1 verwendet.
Die Asymmetrie zwischen kleinster und größter darstellbarer Zahl
eines Typs wird durch die Darstellung der “0” bedingt.
Bitdarstellung einer zu großen Zahl erfordert
mehr Bits als verfügbar.
Bits werden abgeschnitten: Darstellung
entspricht kleinerer Zahl.
Bitdarstellung wird auch als kleinere Zahl (meist
sogar wegen Darstellung als negative Zahl!)
interpretiert.
Underflow: Analog mit zu kleiner Zahl.
13 / 62
Operanden für ganze Zahlen I - Arithmetische Operationen
14
Kurzschreibweisen
Für häufig benutzte Ausdrücke existieren Kurzschreibweisen:
Operator
+
+
*
/
%
=
Beispiel
+i
-i
a+b
a-b
a*b
a/b
a%b
x=a+b
Inkrementierung/Dekrementierung:
int i=0;
i = i + 1;
entspricht:
i= i - 1;
Bedeutung
Vorzeichen (kann weggelassen werden)
Vorzeichen
Summe
Differenz
Produkt
ganzzahlige Division
Rest der ganzzahligen Division (Modulo)
Zuweisung
int i=0;
i++;
i--;
Selbsbezügliche Addition/Subtraktion/... mit beliebigem 2.
Wert:
Operator
+=
-=
*=
/=
%=
Diese Operatoren ermöglichen eine Art von Anweisung:
Die Zuweisung arithmetischer Ausdrücke.
15 / 62
Beispiel
a+=b
a-=b
a*=b
a/=b
a%=b
Bedeutung
a=a+b
a=a-b
a=a*b
a=a/b
a=a%b
16
Ganzzahlige Operanden: IntOps.java
Ganzzahlige Operanden: IntOps.java
1. public static void main(String[] args)
2. {
3.
int a=1, b=3, c=5, d=10;
4.
System.out.println( a + ‘‘ ’’ + b +
‘‘ ’’ + c + ‘‘ ’’ + d );
5.
a++;
6.
b+=a;
7.
d=d/c;
8.
a=b%d;
9.
System.out.println( a + ‘‘ ’’ + (b-a) );
10. }
1. public static void main(String[] args)
2. {
3.
int a=1, b=3, c=5, d=10;
4.
System.out.println( a + ‘‘ ’’ + b +
‘‘ ’’ + c + ‘‘ ’’ + d );
5.
a++;
6.
b+=a;
7.
d=d/c;
8.
a=b%d;
9.
System.out.println( a + ‘‘ ’’ + (b-a) );
10. }
1 3 5 10
14
1 3 5 10
14
Der Wert b-a wird berechnet
und auf dem Bildschirm ausgegeben, aber nicht gespeichert.
17 / 62
Ganzzahlige Operanden: IntOps.java
18
Ganzzahlige Operanden: IntOps.java
1. public static void main(String[] args)
2. {
3.
int a=1, b=3, c=5, d=10;
4.
System.out.println( a + ‘‘ ’’ + b +
‘‘ ’’ + c + ‘‘ ’’ + d );
5.
a++;
6.
b+=a;
7.
d=d/c;
Merke: Kurze, gleichartige
8.
a=b%d;
kombinierte Deklarationen und
9.
System.out.println( a + ‘‘ ’’ + (b-a) );
Initialisierungen zusammenfas10. }
sen.
1. public static void main(String[] args)
2. {
3.
int a=1, b=3, c=5, d=10;
4.
System.out.println( a + ‘‘ ’’ + b +
‘‘ ’’ + c + ‘‘ ’’ + d );
5.
a++;
6.
b+=a;
7.
d=d/c;
8.
a=b%d;
9.
System.out.println( a + ‘‘ ’’ + (b-a) );
10. }
1 3 5 10
14
1 3 5 10
14
19 / 62
Merke: Ausgabe von Variablen mit
System.out.println(var) ohne “ ”.
und Zusammensetzen von Ausgaben mit
System.out.println(var + ‘‘ ’’)
20
Kurzschreibweisen II
Inkrement/Dekrement: InkDekOps.java
Für die Inkrementierung/Dekrementierung
Kurzschreibweisen:
int i=0;
++i;
entspricht
--i;
nicht:
1. public static void main(String[] args)
2. {
3.
int a=1, b=1;
4.
System.out.println( ‘‘a: ’’ + a++ );
5.
System.out.println( a );
6.
System.out.println( ‘‘b: ’’ + ++b );
7. }
existieren weitere
int i=0;
i++;
i--;
Dies ist wichtig, falls die Inkrementierung/Dkrementierung
innerhalb komplexerer Anweisungen ausgeführt werden: Im Ersten
Fall wird zuerst In-/Dekrementiert und dann der (neue) Wert von
i weiterverwendet, im zweiten Fall wird zuerst der alte Wert von i
verwendet und dann In-/Dekrementiert.
1
2
2
21 / 62
Inkrement/Dekrement: InkDekOps.java
22
Inkrement/Dekrement: InkDekOps.java
1. public static void main(String[] args)
2. {
3.
int a=1, b=1;
4.
System.out.println( ‘‘a: ’’ + a++ );
5.
System.out.println( a );
6.
System.out.println( ‘‘b: ’’ + ++b );
7. }
1. public static void main(String[] args)
2. {
3.
int a=1, b=1;
4.
System.out.println( ‘‘a: ’’ + a++ );
5.
System.out.println( a );
6.
System.out.println( ‘‘b: ’’ + ++b );
7. }
1
2
2
1
2
2
Der Wert von a wird zuerst ausgegeben, dann inkrementiert (vgl. 2. Ausgabe von
a).
23 / 62
Der Wert von b wird noch vor
der Ausgabe inkrementiert.
24
Operanden für ganze Zahlen II - Vergleichsoperationen
4.3 Logischer Datentyp boolean
Java besitzt den logischen Datentyp boolean :
Operator
</<=
>/>=
!=
==
=
Beispiel
a<b/a<=b
a>b/a>=b
a!=b
a==b
x=a<b
Bedeutung
Liefert wahr,
Liefert wahr,
Liefert wahr,
Liefert wahr,
Zuweisung
Wertebereich: { true, false }
falls
falls
falls
falls
a
a
a
a
kleiner(-gleich) b
grösser(-gleich) b
ungleich b ist
gleich b ist
Kann bei Zuweisungen von logischen Ausdrücken verwendet
werden.
Wird implizit bei Kontrollstrukturen verwendet.
Logische Operatoren:
Operator
!
&&
||
=
Die Auswertung von Vergleichsoperationen liefert einen der
logischen Werte wahr oder falsch.
Die Zuweisung eines solchen Wertes erfordert links von = eine
Variable des Typs boolean !.
Beispiel
!i
a && b
a || b
a = a && b
Bedeutung
logische Negation
logisches UND
logisches ODER
Zuweisung
25 / 62
Vergleichsoperanden: CompOps.java
26
Vergleichsoperanden: CompOps.java
1. public static void main(String[] args)
throws IOException
1. public static void main(String[] args)
throws IOException
2. {
2. {
3.
int zahl;
3.
int zahl;
4.
boolean zwischen1und10;
4.
boolean zwischen1und10;
5.
System.out.println( ‘‘Ganze Zahl:’’ );
5.
System.out.println( ‘‘Ganze Zahl:’’ );
6.
{... Einlese-Anweisungen ... }
6.
{... Einlese-Anweisungen ... }
7.
zahl = Integer.parseInt(zahlString);
7.
zahl = Integer.parseInt(zahlString);
8.
zwischen1und10 = (zahl>=0) && (zahl<=10);
8.
zwischen1und10 = (zahl>=0) && (zahl<=10);
9.
9.
System.out.println( ‘‘Die Zahl liegt zwischen 0
und 10: ’’
+ zwischen1und10 );
Vergleich auf Variablen vom
10. }//main
Typ int.
System.out.println( ‘‘Die Zahl liegt zwischen 0
und 10: ’’
+ zwischen1und10 );
10. }//main
27 / 62
28
Vergleichsoperanden: CompOps.java
Vergleichsoperanden: CompOps.java
1. public static void main(String[] args)
throws IOException
1. public static void main(String[] args)
throws IOException
2. {
2. {
3.
int zahl;
3.
int zahl;
4.
boolean zwischen1und10;
4.
boolean zwischen1und10;
5.
System.out.println( ‘‘Ganze Zahl:’’ );
5.
System.out.println( ‘‘Ganze Zahl:’’ );
6.
{... Einlese-Anweisungen ... }
6.
{... Einlese-Anweisungen ... }
7.
zahl = Integer.parseInt(zahlString);
7.
zahl = Integer.parseInt(zahlString);
8.
zwischen1und10 = (zahl>=0) && (zahl<=10);
8.
zwischen1und10 = (zahl>=0) && (zahl<=10);
System.out.println( ‘‘Die Zahl liegt zwischen 0
und 10: ’’
+ zwischen1und10 );
Wird zu Typ boolean ausge10. }//main
wertet!
9.
9.
System.out.println( ‘‘Die Zahl liegt zwischen 0
und 10: ’’
+ zwischen1und10 );
Können logisch weiter ver10. }//main
knüpft werden.
29 / 62
Verwechslungsgefahr
30
4 Ganzzahlige Datentypen vs. 1 int
Haben byte, short, int, long kennen gelernt.
Operator
==
=
Beispiel
a==b
x=a<b
Nutzen in Beispielen nur int, da dieser Typ auch in der Praxis am
gebräuchlichsten ist.
Bedeutung
Liefert wahr, falls a gleich b ist
Zuweisung
Nutzung von byte, short :
Speicherplatz sparen (bei Speicherkritischen Geräten, z.B.
Handys, oder grossen Eingaben für Algorithmen).
Durch Tippfehler wird der Vergleichsoperator für den Test auf
Gleichheit zweier Variablen == leicht zum Zuweisungsperator = und
umgekehrt !!!
Falls keine “normalen” Zahlen dargestellt werden sollen,
sondern spezielle Dinge kodiert werden (z.B. Überschaubare
Anzahl von Zuständen, Farben, ...).
Nutzung von long, falls Wertebereich von int nicht ausreicht.
31 / 62
32
4.4 Typumwandlung (Typecast) I
Expliziter Typecast
Java ist eine strikt typisierte Sprache, d.h. jede Variable besitzt
einen Typ. Dieser wird vom Compiler bei der Variablendeklaration
“gelernt” und “erlaubt” danach nur:
Explizite Typumwandlung: Einer Variable wird explizit der Neue
Typ in Klammern vorangestellt:
Zuweisungen von Variablen des gleichen Datentyps.
short s=123;
int i;
i= (int) s;
Operationen, die für den Typ der Variablen definiert sind.
Operationen auf Variablen gleichen Typs.
Manchmal ist es dennoch nötig (und sinnvoll!), andere
Zuweisungen bzw. Operationen auszuführen, daher gibt es 2 Arten
von Typumwandlung (Typecast):
Normale Deklaration.
Normale Deklaration.
Zuweisung mit explizitem Cast
von short auf int
Achtung: Der Typecast (kurz: Cast) ändert nicht den deklarierten
Typ der Variable, sondern ermöglicht nur die Zuweisung zu einer
Variable anderen Typs bzw. die Anwendung einer Operation
anderen Typs. Variable s ist immernoch vom Typ short und i
vom Typ int !
Expliziter Typecast
Impliziter Typecast
33 / 62
Impliziter Typecast
Impliziter Typecast - Erlaubte Typen
Für einige Datentypen gibt es Typen, auf die ein impliziter Cast
erlaubt ist, d.h. bei typgemischten Zuweisungen oder Operationen
wird vom Compiler jede Variable automatisch in einen der
beteiligten Typen umgewandelt. Dieser ist fest definiert.
Implizite Typumwandlung: Eine Variable wird einer anderen von
anderem, erlaubten Typ zugewiesen oder eine
Operation eines solchen Typs auf sie angwandt:
short s=123;
int i;
i= s;
34
Beispiel byte, short, int, long:
Normale Deklaration.
Normale Deklaration.
Zuweisung von short zu int
Cast wie folgt erlaubt, da Wertebereich sich vergrössert:
byte → short → int → long
Der Typecast ändert auch hier nicht den deklarierten Typ der
Variable !Variable s ist immernoch vom Typ short und i vom Typ
int !
Cast wie folgt verboten, da Wertebereich sich verkleinert
(Gefahr von Over-/Underflow):
long 9 int 9 short 9 byte
35 / 62
36
Warnung
Beispiel Typecast (IntCast.java)
1. public static void main(String[] args)
2. {
3.
byte b;
4.
short s=255;
5.
int i=123456;
6.
long l;
7.
b = (byte) s ;
8.
l = i ;
9.
System.out.println( ‘‘Byte: ’’ + b + ‘‘ Short:
’’ + s );
10.
System.out.println( ‘‘Int: ’’ + i + ‘‘ Long: ’’
+ l );
11. }
Impliziter Cast:
I
I
I
Auf nicht erlaubte Typen erzeugt Kompilierfehler.
Auf erlaubte Typen kann ungewollt sein und fehlerhafte Effekte
erzeugen (Beispiele später)!
Typen können erlaubt sein, aber nur in sehr speziellen Fällen
oder trickreicher Programmierung sinnvoll sein!
Expliziter Cast:
Compiler lässt auch Unsinniges zu.
Die Sicherheit eines Typecasts muss der Programmierer
verantworten !
Byte: -1 Short: 255
Int: 123456 Long: 123456
37 / 62
Beispiel Typecast (IntCast.java)
38
Beispiel Typecast (IntCast.java)
1. public static void main(String[] args)
2. {
3.
byte b;
4.
short s=255;
5.
int i=123456;
6.
long l;
7.
b = (byte) s ;
Expliziter Cast erforder8.
l = i ;
lich, da nicht sicher.
9.
System.out.println( ‘‘Byte: ’’ + b + ‘‘ Short:
’’ + s );
10.
System.out.println( ‘‘Int: ’’ + i + ‘‘ Long: ’’
+ l );
11. }
1. public static void main(String[] args)
2. {
3.
byte b;
4.
short s=255;
5.
int i=123456;
6.
long l;
7.
b = (byte) s ;
Impliziter Cast, da sicher.
8.
l = i ;
9.
System.out.println( ‘‘Byte: ’’ + b + ‘‘ Short:
’’ + s );
10.
System.out.println( ‘‘Int: ’’ + i + ‘‘ Long: ’’
+ l );
11. }
Byte: -1 Short: 255
Resultiert in Overflow für
Int: 123456 Long: 123456
Byte-Variable.
Byte: -1 Short: 255
Wert bleibt gleich in
Int: 123456 Long: 123456
Long-Variable.
39 / 62
40
4.5 Gleitkommazahlen
Rationale Numerische Datentypen (Gleitkommazahlen)
Wie bereits am Beispiel einer Konstanten
Im Computer wird eine rationale Zahl immer als Gleitkommazahl
durch Vorzeichen, Mantisse und Exponent (zur Basis 2)
repräsentiert.
static final double PI=3.1415;
gesehen, benötigen wir neben ganzen Zahlen natürlich auch
rationale Zahlen.
In Java gibt es für Gleitkommazahlen die 2 Typen float (Floating
Point Number) und double (Double Precission):
Jede Zahl x ∈ Q, x 6= 0 lässt sich schreiben als:
x = s · m · 10e
Bitanzahl für:
Vorzeichen
Mantisse
Exponent
Summe
Bereich
mit
- Vorzeichen s ∈ {1, −1}
- Mantisse m ∈ Q, 1 ≤ m < 10
- Exponent e ∈ Z.
Da sich in ausgeschriebener Variante, die Position des Kommas je
nach Exponent verändern würde, heisst diese Darstellung
Gleikommazahl (Floating Point Number).
float
1
23
8
32
1.4E − 45 − 3.4E 38
double
1
52
11
64
4.9E − 324 − 1.8E 308
41 / 62
Notation für Gleitkommazahlen
42
Vor- und Nachteile von Gleitkommazahlen
Die Darstellung einer Gleitkommazahl im Java-Quelltext hat die
Form:
Vorzeichen (optional)
Vorteile von Gleitkommazahlen:
Vorkommastellen
Der abgedeckte Zahlenbereich ist sehr gross.
Dezimalpunkt
Erlaubt dennoch hohe Präzision.
Nachkommastellen
Nachteile von Gleitkommazahlen:
E
Vorzeichen des Exponenten (optional)
Bei Rechenoperationen entstehen in der Regel (wie bei den
meisten reellen Rechnungen im Computer) Rundungsfehler.
Ganzzahliger Exponent
Die Rechenoperationen, insbesondere Addition und
Subtraktion, sind erheblich aufwändiger.
Variablen vom Typ float und double können auch Zahlen in
gewöhnlicher Punktschreibweise:
< vorkommastellen > . < nachkommastellen >
zugewiesen werden.
43 / 62
44
Operanden für Gleitkommazahlen
Prioritäten der Java Operanden
Operanden für Gleitkommazahlen entsprechen den arithmetischen
und vergleichenden Operanden für ganze Zahlen.
Für die Beschreibung komplizierterer Ausdrücke (besonders ohne
Bruchschreibweise), empfiehlt sich die Kenntnis der Prioritäten
unter den Operanden.
Einige Besonderheiten:
Kurzschreibweisen Inkrement ++ und Dekrement -funktionieren (obwohl nicht so intuitiv) auch bei
Gleitkommazahlem.
Wollte Prioritätentabelle angeben, fand statt dessen:
Der Operator / steht für Division (nicht ganzzahlig).
Wegen Rundungsfehlern ist Prüfen auf Gleichheit ==
oder Ungleichheit != meist nicht sinnvoll.
45 / 62
Prioritäten der Java Operanden
46
Grundregeln
Für die Beschreibung komplizierterer Ausdrücke (besonders ohne
Bruchschreibweise), empfiehlt sich die Kenntnis der Prioritäten
unter den Operanden.
Der Zugriffsoperator . hat größte Priorität.
Klammern haben zweithöchste Priorität und können jedem
Ausdruck die gewünschte Priorität einräumen.
Wollte Prioritätentabelle angeben, fand statt dessen:
Es gilt Punkt- vor Strichrechnung.
Kein Programmierer sucht nach seiner
Präzedenz-Tabelle, um die Ausführungsreihenfolge von
Operatoren zu überprüfen.
Setzen Sie einfach Klammern, wenn Sie nicht sicher sind,
und fertig.
Gerade komplizierte Ausdrücke werden mit Klammerung leserlicher.
Bei Unsicherheit immer Klammern.
47 / 62
48
Beispiel Rundungsfehler (FloatErr.java)
Beispiel Rundungsfehler (FloatErr.java)
1. public static void main(String[] args)
2. {
3.
float f1=1.234567E-7f, f2=1, f3=-f2;
4.
float sum1,sum2;
5.
sum1=(f1+f2)+f3;
6.
sum2=f1+(f2+f3);
7.
System.out.println( ‘‘(f1+f2)+f3: ’’ + sum1 );
8.
System.out.println( ’’f1+(f2+f3): ‘‘ + sum2 );
9. }
1. public static void main(String[] args)
2. {
3.
float f1=1.234567E-7f, f2=1, f3=-f2;
4.
float sum1,sum2;
5.
sum1=(f1+f2)+f3;
6.
sum2=f1+(f2+f3);
7.
System.out.println( ‘‘(f1+f2)+f3: ’’ + sum1 );
8.
System.out.println( ’’f1+(f2+f3): ‘‘ + sum2 );
9. }
(f1+f2)+f3: 1.1920929E-7
f1+(f2+f3): 1.234567E-7
(f1+f2)+f3: 1.1920929E-7 (f1+f2)+f3 : Zu eine kleinen Zahl
f1+(f2+f3): 1.234567E-7 wird 1 addiert, dann wieder abgezogen: Präzisionsverlust
49 / 62
Beispiel Rundungsfehler (FloatErr.java)
50
float Zuweisung
1. public static void main(String[] args)
2. {
3.
float f1=1.234567E-7f, f2=1, f3=-f2;
4.
float sum1,sum2;
5.
sum1=(f1+f2)+f3;
6.
sum2=f1+(f2+f3);
7.
System.out.println( ‘‘(f1+f2)+f3: ’’ + sum1 );
8.
System.out.println( ’’f1+(f2+f3): ‘‘ + sum2 );
9. }
Bei Zuweisung einer möglicherweise zu grossen/präzisen Konstante
zu einer, gibt es (nur hier!) 2 Möglichkeiten des expliziten Casts:
float f =
1676158.43141f
float f = (float)
1676158.43141
Ohne eine dieser Varianten würde die Zahl als double interpretiert
und ein Kompilierfehler ausgegeben.
(f1+f2)+f3: 1.1920929E-7 f1+(f2+f3) : +1 und -1 werden zuf1+(f2+f3): 1.234567E-7 erst addiert und ergeben exakt 0. Es
wird quasi keine Addition auf f1 ausgeführt: Kein Präzisionsverlust
51 / 62
52
Typumwandlung (Typecast) II
Operanden und gemischte Typen I
Expliziter Typecast ist wie bei den ganzen Zahlen auch hier und
bei allen weiteren Datentypen möglich.
Der erlaubte impliziter Typecast zwischen ganzzahligen
numerischen Datentypen erweitert sich auf rationale Datentypen
wie folgt:
Jeder Operator kann nur auf gleichartigen Datentypen arbeiten
Operationen und Zuweisungen können trotzdem gemischte
Typen enthalten:
int i = 1;
double d = 2, e;
e = i/d;
Erlaubt:
byte → short → int → long → float → double
Dies ist so nur erlaubt, wenn alle beteiligten Typen
standardmäß implizit in den gleichen Typ umgewandelt
werden (Hier: double).
Nicht erlaubt:
double 9 float 9 long 9 int 9 short 9 byte
Vor der Division i/d wird i automatisch in double
umgewandelt.
Weitere Typen können erlaubt sein, aber Fehlerquellen beinhalten.
53 / 62
Operanden und gemischte Typen II
54
Abrunden mit int-Cast
Durch explizite Umwandlung von Gleitkommazahlen (double,
float) in ganzzahlige Werte erhält man den ganzzahligen Anteil
der Zahl:
Andernfalls muss zusätzlich ein explitizer Typecast auftreten:
int i = 1;
double d = 2;
float f = (float) i/d;
Das Programmfragment:
double d = 3.1415;
int i = (int) d;
System.out.prinln(d);
Warum Cast (float) notwendig?
1. Bei Berechnung i/d wird i (erlaubterweise) implizit in double
umgewandelt.
2. Das Ergebnis der Division ist damit auch automatisch ein
double-Wert.
3. Die Zuweisung f=i/d ist daher nicht erlaubt (obwohl 0.5 ohne
Probleme als float- Wert darstellbar ist.
Gibt aus:
3
Bei gemischten Zuweisungen können unerwünschte implizite
Umwandlungen in int auftreten, die ebenfalls diesen Effekt
haben...
55 / 62
56
Beispiel gemischte Typen (MixedType.java
Beispiel gemischte Typen (MixedType.java
1. public static void main(String[] args)
2. {
3.
int i = 1;
4.
double d = 2, e, a, b;
5.
e = i/d;
6.
float f= (float) (i/d);
7.
a = i/2 ;
8.
b = i/2.0 ;
9.
System.out.println( ’’e: ‘‘ + e + ’’ f: ‘‘ +
f);
10.
System.out.println( ’’a: ‘‘ + a + ’’ b: ‘‘ +
b);
11. }
1. public static void main(String[] args)
2. {
3.
int i = 1;
4.
double d = 2, e, a, b;
5.
e = i/d;
6.
float f= (float) (i/d);
2 wird als int interpretiert: / als
7.
a = i/2 ;
ganzzahlige Division ergibt 0 und wird
8.
b = i/2.0 ;
in +double
umgewandelt.
9.
System.out.println( implizit
’’e: ‘‘
e + ’’
f: ‘‘ +
f);
10.
System.out.println( ’’a: ‘‘ + a + ’’ b: ‘‘ +
b);
11. }
e: 0.5 f: 0.5
a: 0.0 b: 0.5
e: 0.5 f: 0.5
a: 0.0 b: 0.5
57 / 62
Beispiel gemischte Typen (MixedType.java
58
4.6 Der alphanumerische Datentyp char
1. public static void main(String[] args)
2. {
3.
int i = 1;
4.
double d = 2, e, a, b;
5.
e = i/d;
6.
float f= (float) (i/d);
2.0 wird als double interpretiert: i
7.
a = i/2 ;
wird implizit in double umgewandelt,
8.
b = i/2.0 ;
so dass / als rationale Division 0.5 als
9.
System.out.println( ’’e:
‘‘ + e ergibt.
+ ’’ f: ‘‘ +
double-Wert
f);
10.
System.out.println( ’’a: ‘‘ + a + ’’ b: ‘‘ +
b);
11. }
char-Variablen werden dazu verwendet, Zeichen darzustellen.
Zeichen sind hier: Buchstaben, Ziffern, Sonderzeichen ...
Typischerweise sind chars 1 Byte groß und können daher 256
verschiedene Werte repräsentieren. Dabei entsprechen die
ersten 128 Zeichen den Zeichen der ASCII-Tabelle (s.o.). Die
nächsten 128 Zeichen sind Länderspezifischen Erweiterungen
vorbehalten.
Java verwendet einen 2 Byte langen char-Typen, der die
65536 des Unicode umfasst. So können quasi alle bis heute
bekannten Schriftzeichen anhand einer Eindeutigen
Unicode-Nummer dargestellt werden.
e: 0.5 f: 0.5
a: 0.0 b: 0.5
59 / 62
60
Nutzung von char
char vs. String
Zeichenkonstanten (Variablen vom Typ char) können wie folgt
Werte zugewiesen werden:
Bisher kennen wir haben wir Zeichenketten in Form des
Datentyps String kennen gelernt.
Unterschiede:
Zeichen in einfaches Hochkomma eingeschlossen:
char c = ’A’
ASCII-Code des Zeichens:
char c = 65
Ausgabe beider Zuweisungen: A
I
I
I
String Zeichenkette, char einzelnes Zeichen.
String in “ ”, char in ’ ’
String i. Ggs. zu char kein primitiver Datentyp.
Der Datentyp String ist ein zusammengesetzter Datentyp.
Manche Zeichen müssen besonders codiert werden, z.B.
werden die Zeichen ’, ”oder \ als \’, \”und \\ dargestellt.
Ein String besteht aus einem Feld (Array) von char
Variablen (später) und besitzt eigene Operatoren.
Weiter gibt es Sonderzeichen wie \n für Zeilenvorschub und
\t für ein Tabulatorzeichen.
Mehr im Kapitel Ein- und Ausgabe.
61 / 62
62
Herunterladen