11.02 Mathematisches mit java.lang.Math

Neben den einfachen Rechenoperationen (multiplizieren, dividieren, subtrahieren und addieren) bietet Java noch mehr vordefinierte Rechenfunktionen. Diese finden Sie in der Klasse java.lang.Math und werden Ihnen in diesem Kapitel vorgestellt. Da bei der Berechnung keine Objektattribute gehalten werden müssen, sind alle Methoden der Klasse Math statisch.

Konstante Attribute

Über die Math-Klasse können Sie auf die eulersche Zahl und auf die Kreiszahl Pi zugreifen. Die Werte dieser Zahlen sind – so genau es der primitive Datentyp double zulässt – als statische Konstanten in der Klasse Math definiert.

System.out.println(Math.E); // 2.718281828459045
System.out.println(Math.PI); // 3.141592653589793

Zufallszahlen

Dieser Funktion sind Sie bereits häufiger im Java Blog Buch begegnet. Mit dem Aufruf Math.random() wird eine zufällige Zahl (double) zwischen 0,0 (inklusive) und 1,0 (exklusive) erzeugt. Der Computer kennt natürlich keinen wirklichen und willkürlichen Zufall. Stattdessen wird die Zufallszahl aus verschiedenen Faktoren „berechnet“.

Um eine Zufallszahl größer als 1,0 zu erhalten, müssen Sie den Rückgabewert mit dem Maximum (exklusive) der gewünschten Zufallszahl multiplizieren.

public static double getRandom(double maxExcl) {
  return Math.random() * maxExcl;
}

// ...

System.out.println(getRandom(1.5)); // liefert eine Zufallszahl zwischen 0 und 1,5

Falls die Zufallszahl nicht zwischen 0 und x liegen soll, sondern zwischen y und x, müssen Sie mit x – y multiplizieren (Wertebereich) und y addieren (minimum).

public static double getRandom(double minIncl, double maxExcl) {
  return minIncl + Math.random() * (maxExcl - minIncl);
}

// ... 

System.out.println(getRandom(2.3, 5.1)); // liefert eine Zufallszahl zwischen 2.3 und 5.1

Diese Methode lässt sich auch leicht für Ganzzahlen umschreiben:

public static int getRandom(int minIncl, int maxExcl) {
  return (int)(minIncl + Math.random() * (maxExcl - minIncl));
}

Betragsfunktion

Math.abs stellt die mathematische Betragsfunktion (a = |b|) für int, long, float und double zur Verfügung. Ein negativer Wert wird also in einen positiven gewandelt. Ein positiver Wert bleibt unverändert. Beachten Sie jedoch das Verhalten der Funktion, wenn der minimale Wert eines primitiven Datentypen übergeben wird (bei bspw. –2147483648 für einen int gibt es kein +2147483648, da der Wertebereich eines int nur bis +2147483647 reicht):

System.out.println(Math.abs(-42)); // 42
System.out.println(Math.abs(-353.4532)); // 353.4532
System.out.println(Math.abs(-212)); // 212
System.out.println(Math.abs(100)); // 100
System.out.println(Math.abs(-0.00000001)); // 1.0E-8
System.out.println(Integer.MIN_VALUE + "/" + Math.abs(Integer.MIN_VALUE)); // -2147483648/-2147483648
System.out.println(Double.MIN_VALUE + "/" + Math.abs(Double.MIN_VALUE)); // 4.9E-324/4.9E-324
System.out.println(Long.MIN_VALUE + "/" + Math.abs(Long.MIN_VALUE)); // -9223372036854775808/-9223372036854775808
System.out.println(Float.MIN_VALUE + "/" + Math.abs(Float.MIN_VALUE)); // 1.4E-45/1.4E-45

Winkelfunktionen

Über die Klasse Math haben Sie auch Zugriff auf die Standard-Winkelfunktionen Sinus (Math.sin(double d)), Cosinus (Math.cos(double d)) und Tangens (Math.tan(double d)) sowie deren Umkehrfunktionen (Math.asin(double d), Math.acos(double d), Math.atan(double d)). Für die Übergabeparameter und Rückgabewerte dieser Methoden wird jedoch das Bogenmaß und nicht das Gradmaß angesetzt. Mit den Methoden Math.toDegrees(double d) und Math.toRadians(double d) können Sie die Werte jedoch jeweils ineinander umrechnen.

double d = Math.toRadians(65); // 65 Grad in Bogenmaß
double sin = Math.sin(d);
double cos = Math.cos(d);
double tan = Math.tan(d);
System.out.println(Math.toDegrees(Math.asin(sin))); // 65
System.out.println(Math.toDegrees(Math.acos(cos))); // 65
System.out.println(Math.toDegrees(Math.atan(tan))); // 65

Für „höhere Mathematik“ stehen die Funktionen atan2(double x, double y) (Lieferung des theta-Winkels unter Berücksichtigung der Vorzeichen der Parameter), sowie sinh(x), cosh(x) und tanh(x) (Hyperbolicus Funktionen) zur Verfügung.

Minimum und Maximum

Wenn Sie die größere bzw. kleinere von zwei Zahlen (int, long, float oder double) ermitteln möchten, stellt Ihnen Java min(int one, int two) und max(int one, int two) zur Verfügung, die jeweils die kleinere bzw. größere Zahl zurückliefern.

Exponentialfunktionen, Logarithmus und Wurzel ziehen

Auch hierfür bietet Math Standardmethoden. Sie können mit der Methode sqrt(double d) die Quardatwurzel bzw. mit cbrt(double x) die dritte Wurzel aus x errechnen. Mit pow(double x, double y) erhalten Sie das Ergebnis der Rechnung x hoch y.

double base = 2;
double exp = 3;
double res = Math.pow(base, exp);
System.out.println(res); // 8
System.out.println(Math.cbrt(res)); // 2

Möchten Sie den Exponentialwert von x zur Basis e (siehe Math.E) erhalten Sie diesen durch Aufruf der Funktion exp(double exp). Soll vom Ergebnis noch der Faktor eins abgezogen werden (ex – 1), verwenden Sie stattdessen die Funktion expm1(double exp).

Weitere Exponentialfunktionen sind scalb(float x, int factor) bzw. scalb(double x, int factor), welche als Ergebnis x * 2factor zurückliefern, sowie hypot(double x, double y), welche zur Berechnung von sqrt(x2 + y2) dient.

Zur Berechnung des Logarithmus stehen folgende Methoden zur Verfügung:

  • log(double x) – Berechnet von x den Logarithmus zur Basis e
  • log10(double x) – Berechnet von x den Logarithmus zur Basis 10
  • log1p(double x) – Berechnet von x den Logarithmus zur Basis e und addiert den Faktor 1

Runden

Um eine Zahl in Java in jedem Fall auf- oder abzurunden verwendet man die Methoden ceil(double x) (aufrunden) bzw. floor(double x) (abrunden).

System.out.println(Math.ceil(2.2)); // 3.0
System.out.println(Math.ceil(2.6)); // 3.0
System.out.println(Math.floor(2.2)); // 2.0
System.out.println(Math.floor(2.6)); // 2.0
System.out.println(Math.ceil(-2.2)); // -2.0
System.out.println(Math.ceil(-2.6)); // -2.0
System.out.println(Math.floor(-2.2)); // -3.0
System.out.println(Math.floor(-2.6)); // -3.0

Beim Aufruf von ceil wird also die nächst höhere Ganzzahl, und bei floor die nächst niedrigere Ganzzahl ermittelt.

Ansonsten stehen Ihnen noch round(double x) bzw. round(float x) und rint(double x) zur Verfügung. round rundet hierbei kaufmännisch auf eine Ganzzahl. rint rundet wie round mit dem Unterschied, dass bei n.5 nicht aufgerundet, sondern zur nächsten geraden Ganzzahl gerundet wird.

System.out.println(Math.round(2.4)); // 2
System.out.println(Math.round(2.5)); // 3
System.out.println(Math.round(2.6)); // 3
System.out.println(Math.rint(2.4)); // 2.0
System.out.println(Math.rint(2.5)); // 2.0
System.out.println(Math.rint(2.6)); // 3.0
System.out.println(Math.rint(1.5)); // 2.0

Um auf eine beliebige Nachkommastelle zu runden, können Sie folgende Methode verwenden:

public static double round(double val, int sca) {
	  
  double s = Math.pow(10, sca);
  return Math.round(val * s) / s;
}

// ...

System.out.println(round(1.2443, 2)); // 1.24
System.out.println(round(1.532, 1)); // 1.5
System.out.println(round(1.425654, 3)); // 1.426

Sonstige Methoden

copySign(double a, double b)/copySign(float a, float b)

Kopiert das Vorzeichen von b zu a und liefert den veränderten a-Wert zurück.

System.out.println(Math.copySign(-3, 4)); // 3
System.out.println(Math.copySign(2, -4)); // -2
System.out.println(Math.copySign(-6, -4)); // -6

getExponent(double x)/getExponent(float x)

Liefert den Exponenten des Wertes x zurück. Siehe auch Kapitel 11.01 Berechnungen mit Fließkommazahlen.

System.out.println(Math.getExponent(1)); // 0
System.out.println(Math.getExponent(5)); // 2
System.out.println(Math.getExponent(100)); // 6
System.out.println(Math.getExponent(Double.MIN_VALUE)); // -1023

IEEEremainder(double dividend, double divisor)

Entspricht der Modulo-Funktion, arbeitet jedoch teilweise genauer.

nextAfter(double a, double b)/nextAfter(float a, float b)

Gibt die nächste darstellbare Fließkommazahl zurück, die sich von a in Richtung b befindet (Ist b größer als a, die nächst igrößere, ist b kleiner als a die nächst kleinere).

System.out.println(Math.nextAfter(5D, 9)); // 5.000000000000001
System.out.println(Math.nextAfter(5D, 2)); // 4.999999999999999

nextUp(double x)/nextUp(float x)

Ähnlich wie nextAfter, nur das bei dieser Methode immer die nächst größere und darstellbare Zahl ermittelt wird.

System.out.println(Math.nextUp(5D)); // 5.000000000000001
System.out.println(Math.nextUp(5)); // 5.0000005

signum(double x)/signum(float x)

Ermittelt das Vorzeichen des Parameters. 0 falls der Parameter den Wert 0 hat, 1 falls der Parameter positiv ist, oder -1 falls der Parameter negativ ist.

System.out.println(Math.signum(4234D)); // 1.0
System.out.println(Math.signum(-34)); // -1.0
System.out.println(Math.signum(0)); // 0

ulp(double x)/ulp(float x)

Mit dieser Funktion erhalten Sie die ULP des Parameters.

One Reply to “11.02 Mathematisches mit java.lang.Math”

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.