Zum Inhalt springen

Kurzeinstieg Java: Zahlen und etwas Mathematik

Aus Wikibooks

Wie kommen die Zahlen in das Programm?

[Bearbeiten]

Zahlen kommen entweder durch Konstanten oder Nutzereingaben in ein Programm und werden dort verarbeitet. Das soll explizit auch Dateien einschließen. Die Zahlen liegen dort als Text vor, also beispielsweise "12" als String und müssen dann umgewandelt werden. Wrapperklassen übernehmen solche Aufgaben, wie unser Taschenrechner zeigt:

public class Argumentenrechner {

    public static void main(String[] args) {
        double summe = 0;
        
        for(String arg : args) {
            Double z = new Double(arg);
            summe += z;
        }
        System.out.println(summe);
    }
}

Das Programm addiert die Zahlen, die auf der Kommandozeile übergeben werden. Diese Zahlen kommen aus einem String-Feld und werden mit Hilfe einer Wrapperklasse in eine Zahl umgewandelt, anschließend addiert und ausgegeben. Sie bemerken, dass wir den Fall, dass eine Zahl nicht umgewandelt werden kann ("dreizehn") nicht abfangen. Hier würde uns eine Ausnahme helfen.

Zahlen können auch in anderen Basen gelesen werden. Die Zahl "1101" beispielsweise ist dezimal "13". Die Klasse Integer hat auch hierfür eine passende statische Methode:

public class BinaerLeser {

    public static void main(String[] args) {
        
        String s = "1101";  // binär für 13
        Integer i = Integer.parseInt(s, 2);  // lies zur Basis 2
        System.out.println("Binär: " + s + " Dezimal: " + i);
        
    }   
}

Den umgekehrten Fall, nämlich Zahlen in einen String einzubetten kennen sie schon: Den Operator + haben wir oft benutzt. Die Wrapperklassen stellen zusätzlich dazu Methoden bereit, beispielsweise toString(), die im nächsten Beispiel vorkommt.

Welche Zahlendarstellungen kennt Java?

[Bearbeiten]

Zahlen kann man binär, oktal, dezimal und hexadezimal ausgeben. Daneben kann man sich eine eigene Basis definieren. Die Klasse Integer enthält die passenden Methoden:

public class Darstellung {

    public static void main(String[] args) {
        
        int z = 13;        
        System.out.println("Binär: " + Integer.toBinaryString(z) );
        System.out.println("Oktal: " + Integer.toOctalString(z) );
        System.out.println("Dezimal: " + z );
        System.out.println("Hexadezimal: " + Integer.toHexString(z) );    
        System.out.println("Basis 13: " + Integer.toString(z, 13) );    

    }    
}

Literale, die Zahlen zu einer der typischen Zahlenbasen darstellen sind:

int binaer = 0b1101; // Zahl 13 binär geschrieben
int oktal = 015;    // Zahl 13 oktal geschrieben
int hexadezimal = 0xd;  // 13 hexadezimal geschrieben

Bei binärer Zahlendarstellung verwendet man "0b" als Präfix, anschließend eine Folge von "0" und "1". Oktalzahlen haben den Präfix "0", dann Ziffern aus der Menge "0" bis "7" und Hexadezimalzahlen den Präfix "0x", anschließend folgen Ziffern aus der Menge "0"-"9" sowie "A"-"F". Bezüglich der Großschreibung der verwendeten Buchstaben im Präfix wie auch als Ziffern ist Java tolerant, "0xABCD" ist dasselbe wie "0XabCd".

Welche mathematischen Konstanten kennt Java?

[Bearbeiten]

In der Java-Klasse Math sind die Konstanten für die eulersche Zahl e und die Kreiszahl π hinterlegt. Die Konstanten sind so groß wie ein double und werden in der offiziellen Dokumentation beschrieben als diejenigen double-Zahlen, welche den mathematischen Konstanten am nächsten kommen:

public class Konstanten {

    public static void main(String[] args) {
        
        System.out.println("e = " + Math.E);
        System.out.println("π = " + Math.PI);
       
    }    
}

Mit welchen Zahlentypen kann man rechnen?

[Bearbeiten]

Die Klasse Math hat statische Methoden für die Datentypen double als größten Datentypen. Wo es sinnvoll ist, werden für float und ganzzahlige Typen eigene Methoden bereitgestellt. Die Grundrechenarten funktionieren auf allen primitiven numerischen Typen wie auch auf den zugehörigen numerischen Objekt-Typen (siehe Kapitel Wrapperklassen). Es gibt in der Java-API keinen Typ, der komplexe Zahlen verarbeiten kann, hier muss man auf Pakete von Drittherstellern zugreifen.

Math enthält dabei unter anderem Methoden aus den Folgenden Gruppen

  • Logarithmen zu verschiedenen Basen,
  • Absolutbeträge,
  • Trigonometrische Funktionen,
  • Runden
  • Potenzieren und
  • Wurzelziehen

Wie benutzt man trigonometrische Funktionen?

[Bearbeiten]

Java kennt einige trigonometrische Funktionen und benutzt dabei immer Radiant als Winkelmaß. Zur Umrechnung der im Alltag gebräuchlichen Einheit Dezimalgrad nach Radiant und umgekehrt gibt es die statischen Methoden toRadians() und toDegrees():

public class Winkel {

    public static void main(String[] args) {
        
        double winkelInGrad = 90;
        double winkelInRad = Math.toRadians(winkelInGrad);
        System.out.println("Winkel in Grad = " + winkelInGrad);
        System.out.println("Winkel in Radiant = " + winkelInRad);
        
        winkelInRad += Math.PI / 36.0;
        
        System.out.println("nun Winkel in Grad = " + Math.toDegrees(winkelInRad));
        System.out.println("Winkel in Radiant = " + winkelInRad);
          
    }    
}

Zum Gebrauch der Funktionen sin() und cos() hier ein Beispiel, das Punkte auf dem Einheitskreis berechnet:

public class Einheitskreis {

    public static void main(String[] args) {
        
        double x, y;
        for(double winkel = 0.0; winkel < 2.0 * Math.PI; winkel+= Math.PI / 10.0) {
            x = Math.cos(winkel);
            y = Math.sin(winkel);
            System.out.println("Winkel " + winkel + " x = " + x + " y = " + y);
            
        }
    }
}

Wie nutzt man Zufallszahlen?

[Bearbeiten]

Sowohl die Klasse Math wie auch Random aus dem Paket 'java.util' können Zufallszahlen bereitstellen. In Math erzeugt die statische Methode random() Pseudozufallszahlen im rechts halboffenen Intervall . Damit ist es leicht, einen Würfel zu programmieren:

public class Zufall {

    public static int zufall6() {
        double r = Math.random() * 6.0 + 1.0; // Zufallszahl in [1.0, 7.0)        
        return (int) Math.floor(r);          // abrunden
    }
    
    public static void main(String[] args) {
        for(int i = 0; i < 10; i++) {
            System.out.println("Würfel " + zufall6());
        }
    }
}

Die Methoden der Klasse Random sind nicht statisch. Es muss also ein Exemplar erzeugt werden. Die Klasse bietet weitaus mehr als pure gleichverteilte Zufallszahlen, doch zunächst ein Besuch im Casino:

import java.util.Random;
public class Casino {

    public static void main(String[] args) {
        
        Random rnd = new Random();
        int zZahl;  // Zufallszahl
        String farbe = "keine";
        
        for(int i = 0; i < 20; i++) {
            zZahl = rnd.nextInt(37);  // 0..36
            farbe = "ungerade, Zahl, rot";
            if(zZahl == 0) {
                farbe = "grün, Bank gewinnt";
            }
            else if(zZahl % 2 == 0) {
                farbe = "gerade Zahl, schwarz";
            }
            System.out.println("Die Kugel rollt... " + zZahl + " (" + farbe + ")");
        }
    }
}

Es wird ein Objekt vom Typ Random erstellt, die Methode nextInt() liefert entweder eine Zufallszahl, bei der 32 Bits zufällig gesetzt werden oder, wenn wie im Beispiel ein Parameter N verwendet wird eine Zufallszahl im ganzzahligen Bereich von bis .

Je nach Anwendungsgebiet sind besonders verteilte Zahlen interessant. Die Methode nextGaussian() liefert normalverteilte Zahlen mit Mittelwert 0.0 und Standardabweichung 1.0. Leider war es das auch schon, mehr Verteilungen werden nicht angeboten. Je nach Einsatzgebiet muss man auf Dritthersteller ausweichen oder selber schreiben.

Falls die Zufallszahlen kryptographischen Standards entsprechen sollen, dann lohnt ein Blick in die Klasse SecureRandom. Hier ein Beispiel, das der Originaldokumentation zu 'java.security.SecureRandom' entlehnt ist. Es werden gleichzeitig N viele zufällige Bytes erzeugt.

import java.security.SecureRandom;
        
public class Krypton {

    public static void main(String[] args) {
        
        SecureRandom srnd = new SecureRandom();
        byte zufallsBytes[] = new byte[13];
        srnd.nextBytes(zufallsBytes);
        
        for(int i = 0; i < 13; i++) {
            System.out.println((i+1) + ". Zufallszahl ist " + zufallsBytes[i]);
        }
    }
}

Das Array zufallsBytes wird von der Methode nextBytes() mit Zufallszahlen gefüllt.

Informatik

[Bearbeiten]

Schreib mit

  • 2er Komplement: Wie sind ganze (positive und negative) Zahlen aufgebaut?
  • Fließkommazahlen: Wie sind Zahlen nach IEEE-Norm aufgebaut, was bedeutet das für Rundungen und den ==-Operator?