Java-Kurs: Rechnen mit Fließkommazahlen
Willemers Informatik-Ecke
Variablen Datentyp char

Das Programm Rechteck berechnet Umfang und Fläche eines Rechtecks:
public class Rechteck {
    public static void main(String[] args) {
        int breite, laenge, flaeche, umfang;
        breite = 3;
        laenge = 4;
        flaeche = breite * laenge;
        System.out.print("Fläche: " + flaeche);
        umfang = 2*breite + 2*laenge;
        System.out.print(" Umfang: " + umfang);
    }
}
Allerdings verwendet es nur ganze Zahlen, da der Datentyp int nur ganze Zahlen beherrscht. In den meisten Fällen wird man aber Nachkommastellen benötigen. Diese beherrschen Variablen vom Typ int aber nicht. Dafür verwendet Java den Typ double.

public class Rechteck {
    public static void main(String[] args) {
        double breite, laenge, flaeche, umfang;
        breite = 3.25;
        laenge = 4.0;
        flaeche = breite * laenge;
        System.out.print("Fläche: " + flaeche);
        umfang = 2*breite + 2*laenge;
        System.out.print(" Umfang: " + umfang);
    }
}
Dieses Programm berechnet auch die Fläche und den Umfang eines Rechtecks. Es verwendet allerdings double statt int. Damit können auch Fließkommazahlen verwendet werden. Java verwendet allerdings kein Komma, um die Nachkommastellen abzutrennen, sondern einen Punkt, wie er im angelsächsischem Sprachraum üblich ist.

Unterschiede zwischen int und double

int

  • Kann Vorzeichen haben
  • Beginnt mit Ziffer 1 bis 9
  • Die einzige Zahl, die mit 0 beginnt, ist 0.
  • Es folgen Ziffern 0 bis 9
Beispiele: 1 -3 243223 -12 0

double

  • Beginnt mit Mantisse wie int-Zahl
  • Optional folgt Punkt mit int-Zahl für Nachkommastellen
  • Optional folgt E oder e, das den Exponenten zur Basis 10 einführt
  • Auf E folgt Exponent
Beispiele: -12.0 -0.12e2 -1200e-2

Eingabe von Fließkommazahlen

Der bekannte Scanner kann auch mit Fließkommazahlen umgehen. Um Fließkommazahlen einlesen zu können, wird nextDouble() statt nextInt() verwendet.
public class Rechteck {
    public static void main(String[] args) {
        double breite, laenge, flaeche, umfang;
        java.util.Scanner eingabe = new java.util.Scanner(System.in);
        laenge = eingabe.nextDouble();
        breite = eingabe.nextDouble();
        flaeche = breite * laenge;
        System.out.print("Fläche: " + flaeche);
        umfang = 2*breite + 2*laenge;
        System.out.print(" Umfang: " + umfang);
    }
}
Vorsicht Falle! Im Programm und in der Ausgabe eines Programms wird der Punkt als Nachkommazeichen verwendet, wie es im angelsächsischen Bereich üblich ist. Die Eingabe nextDouble() stellt fest, dass der Computer auf Deutsch eingerichtet ist und verwendet das deutsche Komma.

Eiskalt berechnend

Das folgende Programm stellt die verschiedenen Rechenarten für int vor.
public class Rechenoperationen {
    public static void main(String[] args) {
        int a = 22, b = 7;
        int summe = a + b;
        int differenz = a - b;
        int produkt = a * b;
        int quotient = a / b;
        int rest = a % b;
        System.out.print(quotient);
        System.out.print(" Rest " + rest);
    }
}
Das Programm gibt aus: 3 Rest 1

Bei einer ganzzahligen Division gibt es keine Nachkommastellen, da ein int diese nicht vorsieht. Um dennoch ein richtiges Ergebnis zu erhalten, kann der Rest ermittelt werden. Die Restberechnung bezeichnet man als Modulo. Sicherlich ist die Wahl des Prozentzeichens für Modulo durchaus nicht glücklich.

Das Ganze sieht in double nicht anders aus.

public class Rechenoperationen {
    public static void main(String[] args) {
        double a = 22, b = 7;
        double summe = a + b;
        double differenz = a - b;
        double produkt = a * b;
        double quotient = a / b;
        double rest = a % b;
        System.out.print(quotient);
        System.out.print(" Rest " + rest);
    }
}
Das Programm gibt aus: 3.2142857142857144 Rest 1.0

Die Fließkommadivision zeigt Nachkommastellen an, auch wenn das Komma ein Punkt ist. Auch double kennt die Modulo-Berechnung, auch wenn man sie selten braucht.

Kurzformen

Der Ausdruck auf der rechten Seite des Zuweisungszeichens = wird immer vor der Zuweisung ausgewertet. Dies wird hier deutlich:
int zaehler = 1;
zaehler = zaehler + 1; // zaehler enthält anschließend 2
Die Variable zaehler enthält eine 1. Dann wird sie um 1 erhöht und anschließend der Variable zaehler zugewiesen. Anschließend ist deren Wert 2.

Wird eine Variable verändert, kann folgende Kurzform verwendet werden:

zaehler += zaehler; // funktioniert auch mit *, / oder -
Noch kürzer geht das Inkrementieren und Dekrementieren:
zaehler++; // funktioniert auch mit --
++zaehler;
Oft findet man bei Anfängern folgende Variante:
zaehler = zaehler++; // boese Falle!
zaehler = ++zaehler;
Die Zuweisung ist hier nicht nur unnütz, sondern in der ersten Zeile sogar schädlich. Denn anstatt einen höheren Wert zu finden, bleibt die Variable zaehler nach der ersten Zeile gleich.

Casting

Umwandlung zur Verhinderung einer ganzzahligen Division

int nenner = 10;
int zaehler = 9;
double quotient = zaehler / nenner; // quotient enthält 0.0
Der Ausdruck auf der rechten Seite wird zuerst ausgewertet und ist eine reine int-Division, also ohne Nachkommastellen. Abhilfe: Einer der beteiligten Operanden muss zur Fließkommazahl werden:
double quotient = zaehler / (double)nenner; // nun 0.9
Fast immer, wenn Wahrscheinlichkeiten berechnet werden, ist dieser Fehler zu erwarten, weil die Günstigen und die Möglichen in der Regel in int-Variablen gespeichert werden, die Wahrscheinlichkeit selbst aber eine double-Variable ist.

Kompatibilität

Der Inhalt einer ganzzahligen Variable passt immer in eine Fließkommavariable. Umgekehrt verhindert es der Compiler (Typemismatch). Hier kann der Programmierer die Verantwortung übernehmen und casten.
double fwert = 7.0;
int iwert = (int)fwert;
Sollte die Variable allerdings tatsächlich Nachkommastellen gehabt haben, sind diese wie abgeschnitten. Und manchmal möchte man genau das. Will man allerdings wirklich auf- oder abrunden, dann bieten sich Funktionen aus der Mathebibliothek von Java an. Für das Runden gibt es round. Allerdings erwartet sie als Rückgabetyp einen long und keinen int. Aber den kann man ja per cast wieder leicht zum int degradieren.

double w = 1.55;
long a = Math.round(w); // a muss long sein!
int b = (int)a;

Links

Videos


Variablen Datentyp char