Ein Werkzeugkasten aus statischen Methoden
java.lang.Math ist eine Klasse voller fertiger mathematischer Funktionen: Potenzen, Wurzeln, Beträge, Runden, Trigonometrie, Logarithmen und Zufallszahlen. Zwei Dinge machen sie einfach zu benutzen:
- Sie liegt in
java.lang, das jede Java-Datei automatisch importiert. Du musst keineimport-Zeile schreiben. - Jede Methode ist
static. Du rufst sie auf dem Klassennamen auf,Math.sqrt(25), und erzeugst nie einMath-Objekt. Wasstaticbedeutet, erklärt die Seite zu statischen Membern.
Manche Ergebnisse werden mit .0 ausgegeben, andere nicht. Jede Math-Methode hat einen festen Rückgabetyp, und diesen zu kennen ist der größte Teil dessen, was es über diese Klasse zu lernen gibt.
| Methode | Macht | Liefert |
|---|---|---|
Math.pow(a, b) | a hoch b | double |
Math.sqrt(x) | Quadratwurzel | double |
Math.cbrt(x) | Kubikwurzel | double |
Math.abs(x) | Betrag | denselben Typ wie x |
Math.max(a, b) / Math.min(a, b) | größeren / kleineren von zwei Werten | den breiteren der beiden Typen |
Math.round(x) | nächste ganze Zahl | long für einen double, int für einen float |
Math.floor(x) / Math.ceil(x) | abrunden / aufrunden | double |
Math.random() | Zufallszahl von 0.0 bis unter 1.0 | double |
Math.PI, Math.E | die Konstanten π und e | double |
Math.pow: Potenzen
Math.pow(base, exponent) erhebt eine Zahl in eine Potenz. Die Methode nimmt zwei double-Parameter und liefert einen double, auch wenn du ganze Zahlen übergibst:
Um das Ergebnis in einem int zu speichern, caste es mit (int). Bei kleinen ganzzahligen Potenzen ist das double-Ergebnis exakt, also liefert der Cast die richtige Antwort. Bei großen Ergebnissen geht der Cast schief: Ein double über Integer.MAX_VALUE (2.147.483.647) wird genau zu Integer.MAX_VALUE, also ergibt (int) Math.pow(2, 40) den Wert 2147483647. Caste bei größeren Potenzen zu long und denk daran, dass ein double oberhalb von 2⁵³ nicht mehr jede ganze Zahl exakt darstellen kann. Was ein Cast mit dem Wert macht, erklärt die Seite zur Typumwandlung.
Java hat keinen Potenzoperator. 2 ^ 3 kompiliert, aber ^ ist das bitweise XOR, und das Ergebnis ist 1, nicht 8. Das ist einer der häufigsten Anfängerfehler in Java-Code mit Mathematik.
Ein double ab zehn Millionen wird in wissenschaftlicher Schreibweise ausgegeben, was beim ersten Ausgeben einer Zehnerpotenz überrascht:
1.0E7 bedeutet 1,0 × 10⁷. Der Wert ist derselbe, nur die Ausgabeform ändert sich. Caste zu long oder formatiere mit String.format("%.0f", value), um ihn als einfache Ziffern auszugeben.
Math.sqrt und Math.cbrt: Wurzeln
Math.sqrt(x) liefert die Quadratwurzel von x als double. Math.cbrt(x) liefert die Kubikwurzel.
Die Quadratwurzel einer negativen Zahl ist keine reelle Zahl, deshalb liefert Math.sqrt(-4) den Wert NaN („not a number“), statt eine Exception zu werfen. NaN breitet sich durch jede Rechnung aus, in die es gerät. Prüf die Eingaben also vor dem Wurzelziehen, wenn negative Werte möglich sind. Math.hypot(a, b) berechnet sqrt(a*a + b*b) direkt, ein üblicher Weg, den Abstand zwischen zwei Punkten zu bestimmen.
Math.abs: Betrag
Math.abs(x) entfernt das Vorzeichen. Anders als pow und sqrt liefert es denselben Typ, den du hineingibst: einen int für einen int, einen double für einen double.
Der übliche Einsatz ist eine Differenz, bei der dich die Größe interessiert, nicht die Richtung, etwa der Abstand zwischen zwei Positionen.
Math.max und Math.min
Math.max(a, b) liefert den größeren von zwei Werten und Math.min(a, b) den kleineren. Sie nehmen genau zwei Argumente. Für drei oder mehr verschachtelst du die Aufrufe:
Haben die beiden Argumente unterschiedliche Typen, wird der schmalere zuerst erweitert. Math.max(3, 7.5) vergleicht zwei double-Werte und liefert einen double. Das letzte Beispiel begrenzt einen Wert auf den Bereich von 0 bis 100: Math.min kappt ihn bei 100, Math.max verhindert, dass er unter 0 fällt.
Runden: round, floor, ceil
Java hat drei Rundungsmethoden, und sie unterscheiden sich sowohl in der Richtung als auch im Rückgabetyp:
Math.roundgeht zur nächsten ganzen Zahl. Ein Wert genau in der Mitte wird aufgerundet, in Richtung plus unendlich, also wird2.5zu3und-2.5zu-2. Für eindouble-Argument liefert es einenlong(und für einenfloateinenint).Math.floorrundet immer ab, in Richtung minus unendlich, und liefert einendouble.Math.ceilrundet immer auf, in Richtung plus unendlich, und liefert einendouble.- Ein Cast
(int)ist überhaupt kein Runden: Er schneidet den Nachkommaanteil ab, wodurch positive Zahlen kleiner und negative Zahlen größer werden.
Weil Math.round(double) einen long liefert, kompiliert die Zuweisung an einen int nicht ohne Cast:
int n = Math.round(2.6); // error: incompatible types: possible lossy conversion from long to int
int m = (int) Math.round(2.6); // OK, m ist 3
long k = Math.round(2.6); // OK
Um auf eine bestimmte Zahl von Nachkommastellen zu runden, skalierst du hoch, rundest und skalierst wieder herunter. Die Division durch 100.0 (einen double) statt durch 100 behält die Nachkommastellen:
Die zweite Zeile teilt einen long durch einen int, das ist Ganzzahldivision, also gehen die Nachkommastellen verloren. Wenn du eine gerundete Zahl nur anzeigen willst, ist String.format("%.2f", value) einfacher und ändert den gespeicherten Wert nicht.
Math.random: Zufallszahlen
Math.random() liefert einen double, der mindestens 0.0 und kleiner als 1.0 ist. Der Wert ist bei jedem Aufruf anders, deshalb ändert sich die Ausgabe der Programme in diesem Abschnitt bei jedem Klick auf Ausführen.
Für eine ganze Zahl in einem Bereich streckst du diesen Wert, castest ihn und verschiebst ihn. Für eine ganze Zahl von min bis max, beide eingeschlossen:
int value = (int) (Math.random() * (max - min + 1)) + min;
So funktioniert das bei einem Würfel, bei dem min gleich 1 und max gleich 6 ist:
Math.random() * 6ergibt einendoublevon0.0bis ausschließlich6.0.(int)schneidet den Nachkommaanteil ab und ergibt eine der Zahlen0, 1, 2, 3, 4, 5.+ 1verschiebt das zu1, 2, 3, 4, 5, 6.
Die erste Zeile zeigt fünf zufällige Würfe. Die zweite Zeile prüft zehntausend Würfe und gibt in der Praxis immer lowest: 1, highest: 6 aus: Die Formel erreicht beide Enden des Bereichs und geht nie darüber hinaus.
Die Klammern um Math.random() * (max - min + 1) sind wichtig. Ein Cast wirkt auf den Wert direkt dahinter, also castet (int) Math.random() * 6 zuerst Math.random(). Das ist immer 0, und 0 * 6 ist 0, also kommt bei jedem „Wurf“ dasselbe heraus.
Für Spiele und Übungen ist Math.random() in Ordnung. Für alles Weitere liefern die Klasse java.util.Random und ThreadLocalRandom.current().nextInt(min, max + 1) (in java.util.concurrent) direkt ganze Zahlen, und Random kann einen Seed bekommen, um in Tests dieselbe Folge zu wiederholen. Keine davon eignet sich für Passwörter oder Sicherheitstokens; nimm dafür java.security.SecureRandom.
Math.PI und Math.E
Math.PI (π) und Math.E (die Eulersche Zahl e) sind Konstanten vom Typ static final double:
Nimm sie, statt 3.14 zu tippen. Sie sind so genau, wie ein double es erlaubt, und der Name sagt der lesenden Person, was die Zahl ist.
Ganzzahlige Ergebnisse vs. double-Ergebnisse
Die meisten Math-Methoden nehmen und liefern double. Wenn du ihnen int-Werte gibst, erweitert Java die Argumente automatisch zu double, aber die Rechnung, die du vor dem Aufruf schreibst, passiert trotzdem in int. Daher kommen die meisten falschen Antworten:
items / perBox ist 7 / 2, und die Division zweier int-Werte verwirft den Rest, also ist das Ergebnis 3, bevor Math.ceil es überhaupt sieht. Math.ceil(3.0) ist 3.0. Mach einen Operanden zum double, mit einem Cast oder einem Literal wie 4.0, damit die Division ihren Nachkommaanteil behält. Die Seite zu Operatoren erklärt die Ganzzahldivision ausführlicher.
Die allgemeine Regel: Leg fest, welchen Typ du am Ende willst, lass die Division oder Multiplikation in double passieren, wenn Nachkommastellen zählen, und caste nur einmal, ganz am Ende, zurück zu int oder long.
Weitere nützliche Methoden
Noch ein paar Methoden aus derselben Klasse, alle auf dieselbe Weise aufgerufen:
Math.logist der natürliche Logarithmus;Math.log10ist der Logarithmus zur Basis 10.Math.floorMod(a, b)liefert einen Rest mit dem Vorzeichen vonb. Das willst du, wenn Werte in einem Bereich umlaufen sollen, etwa bei Wochentagen. Der Operator%behält das Vorzeichen vona.- Die trigonometrischen Methoden (
sin,cos,tan) arbeiten mit Bogenmaß. Rechne Grad vorher mitMath.toRadiansum. Math.addExact,Math.multiplyExactund ihre Verwandten werfen bei einem Überlauf eineArithmeticException, statt stillschweigend zu einer negativen Zahl umzuschlagen.
Häufig gestellte Fragen
Wie verwende ich Math.pow in Java?
Math.pow(base, exponent) liefert base hoch exponent als double, also ist Math.pow(2, 3) gleich 8.0. Um das Ergebnis in einem int zu speichern, caste es: int n = (int) Math.pow(2, 10); ergibt 1024. Java hat keinen Potenzoperator ^; ^ ist das bitweise XOR.
Wie erzeuge ich mit Math.random eine Zufallszahl in einem Bereich?
Math.random() liefert einen double von 0.0 bis ausschließlich 1.0. Für eine ganze Zahl von min bis einschließlich max nimm (int) (Math.random() * (max - min + 1)) + min. Ein Würfelwurf ist (int) (Math.random() * 6) + 1.
Muss ich die Math-Klasse in Java importieren?
Nein. Math liegt im Paket java.lang, das jede Java-Datei automatisch importiert. Alle ihre Methoden sind static, du rufst sie also auf dem Klassennamen auf, etwa Math.sqrt(16), ohne ein Objekt zu erzeugen.
Warum liefert Math.round in Java einen long?
Math.round(double) liefert einen long, weil ein double Werte weit über dem Bereich von int fassen kann. Um das Ergebnis einem int zuzuweisen, brauchst du einen Cast: int n = (int) Math.round(2.6);. Math.round(float) liefert einen int.
Was ist der Unterschied zwischen Math.floor, Math.ceil und Math.round?
Math.floor rundet ab (2.7 wird zu 2.0, -2.3 zu -3.0), Math.ceil rundet auf (2.1 wird zu 3.0), und Math.round geht zur nächsten ganzen Zahl, wobei Hälften aufgerundet werden (2.5 wird zu 3). floor und ceil liefern einen double; round liefert einen long.