Rheinwerk Computing < openbook >


 
Inhaltsverzeichnis
Materialien
Vorwort
1 Java ist auch eine Sprache
2 Imperative Sprachkonzepte
3 Klassen und Objekte
4 Arrays und ihre Anwendungen
5 Der Umgang mit Zeichenketten
6 Eigene Klassen schreiben
7 Objektorientierte Beziehungsfragen
8 Ausnahmen müssen sein
9 Geschachtelte Typen
10 Besondere Typen der Java SE
11 Generics<T>
12 Lambda-Ausdrücke und funktionale Programmierung
13 Architektur, Design und angewandte Objektorientierung
14 Java Platform Module System
15 Die Klassenbibliothek
16 Einführung in die nebenläufige Programmierung
17 Einführung in Datenstrukturen und Algorithmen
18 Einführung in grafische Oberflächen
19 Einführung in Dateien und Datenströme
20 Einführung ins Datenbankmanagement mit JDBC
21 Bits und Bytes, Mathematisches und Geld
22 Testen mit JUnit
23 Die Werkzeuge des JDK
A Java SE-Module und Paketübersicht
Stichwortverzeichnis


Download:

- Listings, ca. 2,7 MB


Buch bestellen
Ihre Meinung?



Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenboom

Einführung, Ausbildung, Praxis
Buch: Java ist auch eine Insel


Java ist auch eine Insel

Pfeil 21 Bits und Bytes, Mathematisches und Geld
Pfeil 21.1 Bits und Bytes
Pfeil 21.1.1 Die Bit-Operatoren Komplement, Und, Oder und XOR
Pfeil 21.1.2 Repräsentation ganzer Zahlen in Java – das Zweierkomplement
Pfeil 21.1.3 Das binäre (Basis 2), oktale (Basis 8), hexadezimale (Basis 16) Stellenwertsystem
Pfeil 21.1.4 Auswirkung der Typumwandlung auf die Bit-Muster
Pfeil 21.1.5 Vorzeichenlos arbeiten
Pfeil 21.1.6 Die Verschiebeoperatoren
Pfeil 21.1.7 Ein Bit setzen, löschen, umdrehen und testen
Pfeil 21.1.8 Bit-Methoden der Integer- und Long-Klasse
Pfeil 21.2 Fließkomma-Arithmetik in Java
Pfeil 21.2.1 Spezialwerte für Unendlich, Null, NaN
Pfeil 21.2.2 Standardnotation und wissenschaftliche Notation bei Fließkommazahlen *
Pfeil 21.2.3 Mantisse und Exponent *
Pfeil 21.3 Die Eigenschaften der Klasse Math
Pfeil 21.3.1 Attribute
Pfeil 21.3.2 Absolutwerte und Vorzeichen
Pfeil 21.3.3 Maximum/Minimum
Pfeil 21.3.4 Runden von Werten
Pfeil 21.3.5 Rest der ganzzahligen Division *
Pfeil 21.3.6 Division mit Rundung in Richtung negativ unendlich, alternativer Restwert *
Pfeil 21.3.7 Multiply-Accumulate
Pfeil 21.3.8 Wurzel- und Exponentialmethoden
Pfeil 21.3.9 Der Logarithmus *
Pfeil 21.3.10 Winkelmethoden *
Pfeil 21.3.11 Zufallszahlen
Pfeil 21.4 Genauigkeit, Wertebereich eines Typs und Überlaufkontrolle *
Pfeil 21.4.1 Der größte und der kleinste Wert
Pfeil 21.4.2 Überlauf und alles ganz exakt
Pfeil 21.4.3 Was bitte macht eine ulp?
Pfeil 21.5 Zufallszahlen: Random, SecureRandom und SplittableRandom
Pfeil 21.5.1 Die Klasse Random
Pfeil 21.5.2 Random-Objekte mit dem Samen aufbauen
Pfeil 21.5.3 Einzelne Zufallszahlen erzeugen
Pfeil 21.5.4 Pseudo-Zufallszahlen in der Normalverteilung *
Pfeil 21.5.5 Strom von Zufallszahlen generieren *
Pfeil 21.5.6 Die Klasse SecureRandom *
Pfeil 21.5.7 SplittableRandom *
Pfeil 21.6 Große Zahlen *
Pfeil 21.6.1 Die Klasse BigInteger
Pfeil 21.6.2 Beispiel: Ganz lange Fakultäten mit BigInteger
Pfeil 21.6.3 Große Fließkommazahlen mit BigDecimal
Pfeil 21.6.4 Mit MathContext komfortabel die Rechengenauigkeit setzen
Pfeil 21.6.5 Noch schneller rechnen durch mutable Implementierungen
Pfeil 21.7 Mathe bitte strikt *
Pfeil 21.7.1 Strikte Fließkommaberechnungen mit strictfp
Pfeil 21.7.2 Die Klassen Math und StrictMath
Pfeil 21.8 Geld und Währung
Pfeil 21.8.1 Geldbeträge repräsentieren
Pfeil 21.8.2 ISO 4217
Pfeil 21.8.3 Währungen in Java repräsentieren
Pfeil 21.9 Zum Weiterlesen
 

Zum Seitenanfang

21.3    Die Eigenschaften der Klasse Math Zur vorigen ÜberschriftZur nächsten Überschrift

Die Klasse java.lang.Math ist eine typische Utility-Klasse, die nur statische Methoden (bzw. Attribute als Konstanten) deklariert. Mit dem privaten Konstruktor lassen sich keine Exemplare von Math erzeugen.

 

Zum Seitenanfang

21.3.1    Attribute Zur vorigen ÜberschriftZur nächsten Überschrift

Die Math-Klasse besitzt zwei statische Attribute:

class java.lang.Math
  • static final double E

    die eulersche Zahl[ 272 ](Die irrationale Zahl e ist nach dem schweizerischen Mathematiker Leonhard Euler (1707–1783) benannt. ) e = 2,7182818284590452354

  • static final double PI

    die Kreiszahl Pi[ 273 ](Wer noch auf der Suche nach einer völlig unsinnigen Information ist: Die einmilliardste Stelle hinter dem Komma von Pi ist eine Neun. ) = 3,14159265358979323846

 

Zum Seitenanfang

21.3.2    Absolutwerte und Vorzeichen Zur vorigen ÜberschriftZur nächsten Überschrift

Die zwei statischen abs(…)-Methoden liefern den Betrag des Arguments (mathematische Betragsfunktion: y = |x|). Sollte ein negativer Wert als Argument übergeben werden, wandelt abs(…) ihn in einen positiven Wert um.

Eine spezielle Methode ist auch copySign(double, double). Sie ermittelt das Vorzeichen einer Fließkommazahl und überträgt es auf eine andere Zahl.

class java.lang.Math
  • static int abs(int x)

  • static long abs(long x)

  • static float abs(float x)

  • static double abs(double x)

  • static double copySign(double magnitude, double sign)

  • static float copySign(float magnitude, float sign)

    Liefern magnitude als Rückgabe, aber mit dem Vorzeichen von sign.

[»]  Hinweis

Es gibt genau einen Wert, auf den Math.abs(int) keine positive Rückgabe liefern kann: –2.147.483.648. Dies ist die kleinste darstellbare int-Zahl (Integer.MIN_VALUE), während +2.147.483.648 gar nicht in ein int passt! Die größte darstellbare int-Zahl ist 2.147.483.647 (Integer.MAX_VALUE). Was sollte abs(-2147483648) auch ergeben?

Vorzeichen erfragen

Die statische Methode signum(value) liefert eine numerische Rückgabe für das Vorzeichen von value, und zwar »+1« für positive, »–1« für negative Zahlen und »0« für 0. Die Methode ist nicht ganz logisch auf die Klassen Math für Fließkommazahlen und Integer/Long für Ganzzahlen verteilt:

  • java.lang.Integer.signum(int i)

  • java.lang.Long.signum(long i)

  • java.lang.Math.signum(double d)

  • java.lang.Math.signum(float f)

 

Zum Seitenanfang

21.3.3    Maximum/Minimum Zur vorigen ÜberschriftZur nächsten Überschrift

Die statischen max(…)-Methoden liefern den größeren der übergebenen Werte. Die statischen min(…)-Methoden liefern den kleineren von zwei Werten als Rückgabewert.

class java.lang.Math
  • static int max(int x, int y)

  • static long max(long x, long y)

  • static float max( float x, float y )

  • static double max(double x, double y)

  • static int min(int x, int y)

  • static long min(long x, long y)

  • static float min(float x, float y)

  • static double min(double x, double y)

Als Vararg sind diese Methoden nicht deklariert, auch gibt es keine Min-Max-Methoden für drei Argumente. Wenn Arrays vorliegen, muss eine andere Lösung gewählt werden, etwa durch Arrays.stream(value).min().getAsInt().

 

Zum Seitenanfang

21.3.4    Runden von Werten Zur vorigen ÜberschriftZur nächsten Überschrift

Für die Rundung von Werten bietet die Klasse Math fünf statische Methoden:

class java.lang.Math
  • static double ceil(double a)

  • static double floor(double a)

  • static int round(float a)

  • static long round(double a)

  • static double rint(double a)

Auf- und Abrunden mit ceil(double) und floor(double)

Die statische Methode ceil(double) dient dem Aufrunden und liefert die nächsthöhere Ganzzahl (jedoch als double, nicht als long), wenn die Zahl nicht schon eine ganze Zahl ist. Die statische Methode floor(double) rundet auf die nächstniedrigere Ganzzahl ab:

Listing 21.2    src/main/java/com/tutego/insel/math/Rounding1Demo.java, main()

System.out.println( Math.ceil(-99.1) );    //  -99.0

System.out.println( Math.floor(-99.1) ); // -100.0

System.out.println( Math.ceil(-99) ); // -99.0

System.out.println( Math.floor(-99) ); // -99.0

System.out.println( Math.ceil(-.5) ); // -0.0

System.out.println( Math.floor(-.5) ); // -1.0

System.out.println( Math.ceil(-.01) ); // -0.0

System.out.println( Math.floor(-.01) ); // -1.0

System.out.println( Math.ceil(0.1) ); // 1.0

System.out.println( Math.floor(0.1) ); // 0.0

System.out.println( Math.ceil(.5) ); // 1.0

System.out.println( Math.floor(.5) ); // 0.0

System.out.println( Math.ceil(99) ); // 99.0

System.out.println( Math.floor(99) ); // 99.0

Die genannten statischen Methoden haben auf ganze Zahlen keine Auswirkung.

Kaufmännisches Runden mit round(…)

Die statischen Methoden round(double) und round(float) runden kaufmännisch auf die nächste Ganzzahl vom Typ long bzw. int. Ganze Zahlen werden nicht aufgerundet. Wir können round(…) als Gegenstück zur Typumwandlung (long) doublevalue einsetzen:

Listing 21.3    src/main/java/com/tutego/insel/math/Rounding2Demo.java, main()

System.out.println( Math.round(1.01) );     //  1

System.out.println( Math.round(1.4) ); // 1

System.out.println( Math.round(1.5) ); // 2

System.out.println( Math.round(1.6) ); // 2

System.out.println( (int) 1.6 ); // 1

System.out.println( Math.round(30) ); // 30

System.out.println( Math.round(-2.1) ); // -2

System.out.println( Math.round(-2.9) ); // -3

System.out.println( (int) -2.9 ); // -2
[»]  Interna

Die Methoden Math.round(int) und Math.round(long) sind in Java ausprogrammiert. Sie addieren zum aktuellen Parameter 0,5 und übergeben das Ergebnis der statischen floor( double)-Methode.

Listing 21.4    java.lang.Math, round(double), etwas gekürzt

public static long round( double a ) {

return (long) floor( a + 0.5 );

}

Gerechtes Runden rint(double)

rint(double) ist mit round(…) vergleichbar, nur ist es im Gegensatz zu round(…) gerecht, was bedeutet, dass rint(double) bei 0,5 in Abhängigkeit davon, ob die benachbarte Zahl ungerade oder gerade ist, auf- oder abrundet:

Listing 21.5    src/main/java/com/tutego/insel/math/Rounding3Demo.java, main()

System.out.println( Math.round(-1.5) );     //   -1

System.out.println( Math.rint( -1.5) ); // -2.0

System.out.println( Math.round(-2.5) ); // -2

System.out.println( Math.rint( -2.5) ); // -2.0

System.out.println( Math.round( 1.5) ); // 2

System.out.println( Math.rint( 1.5) ); // 2.0

System.out.println( Math.round( 2.5) ); // 3

System.out.println( Math.rint( 2.5) ); // 2.0

Mit einem konsequenten Auf- oder Abrunden pflanzen sich natürlich auch Fehler ungeschickter fort als mit dieser 50/50-Strategie.

[zB]  Beispiel

Die statische rint(double)-Methode lässt sich auch einsetzen, wenn Zahlen auf zwei Nachkommastellen gerundet werden sollen. Ist d vom Typ double, so ergibt der Ausdruck Math. rint(d*100.0)/100.0 die gerundete Zahl.

Listing 21.6    Round2Scales.java

class Round2Scales {

public static double roundScale2( double d ) {

return Math.rint( d * 100 ) / 100.;

}



public static void main( String[] args ) {

System.out.println( roundScale2(+1.341 ) ); // 1.34

System.out.println( roundScale2(-1.341 ) ); // -1.34

System.out.println( roundScale2(+1.345 ) ); // 1.34

System.out.println( roundScale2(-1.345 ) ); // -1.34



System.out.println( roundScale2(+1.347 ) ); // 1.35

System.out.println( roundScale2(-1.347 ) ); // -1.35

}

}

Arbeiten wir statt mit rint(double) mit round(…), wird die Zahl 1,345 nicht auf 1,34, sondern auf 1,35 gerundet. Wer nun Lust hat, etwas auszuprobieren, darf testen, wie der Format-String %.2f bei printf(…) rundet.

 

Zum Seitenanfang

21.3.5    Rest der ganzzahligen Division * Zur vorigen ÜberschriftZur nächsten Überschrift

Neben dem Restwert-Operator %, der den Rest der Division berechnet, gibt es auch eine statische Methode Math.IEEEremainder(double, double).

Listing 21.7    src/main/java/com/tutego/insel/math/IEEEremainder.java, main()

double a = 44.0;

double b = 2.2;

System.out.println( a / b ); // 20.0

System.out.println( a % b ); // 2.1999999999999966

System.out.println( Math.IEEEremainder( a, b ) ); // -3.552713678800501E-15

Das zweite Ergebnis ist mit der mathematischen Ungenauigkeit fast 2,2, aber etwas kleiner, sodass der Algorithmus nicht noch einmal 2,2 abziehen konnte. Die statische Methode IEEEremainder(double, double) liefert ein Ergebnis nahe null (–0,000000000000003552713 6788005), was besser ist, denn 44,0 lässt sich ohne Rest durch 2,2 teilen, also wäre der Rest eigentlich 0.

class java.lang.Math
  • static double IEEEremainder(double dividend, double divisor)

    Liefert den Rest der Division von Dividend und Divisor, so wie es der IEEE-754-Standard vorschreibt.

Eine eigene statische Methode, die mitunter bessere Ergebnisse liefert – mit den Werten 44 und 2,2 wirklich 0,0 –, ist die folgende:

public static double remainder( double a, double b ) {

return Math.signum(a) *

(Math.abs(a) - Math.abs(b) * Math.floor(Math.abs(a)/Math.abs(b)));

}
 

Zum Seitenanfang

21.3.6    Division mit Rundung in Richtung negativ unendlich, alternativer Restwert * Zur vorigen ÜberschriftZur nächsten Überschrift

Die Ganzzahldivision in Java ist simpel gestrickt. Vereinfacht ausgedrückt: Konvertiere die Ganzzahlen in Fließkommazahlen, führe die Division durch, und schneide alles hinter dem Komma ab. So ergeben zum Beispiel 3 / 2 = 1 und 9 / 2 = 4. Bei negativem Ergebnis, das entweder durch einen negativen Dividenden oder durch einen negativen Divisor zustande kam, folgt das gleiche Spiel: -9 / 2 = -4 und 9 / -2 = -4. Schauen wir uns einmal die Rundungen an.

Ist das Ergebnis einer Division positiv und mit Nachkommaanteil, so wird das Ergebnis durch das Abschneiden der Nachkommastellen ein wenig kleiner, also abgerundet. Wäre 3 / 2 bei Fließkommazahlen 1,5, ist es bei einer Ganzzahldivision abgerundet 1. Bei negativen Ergebnissen einer Division ist das genau andersherum, denn durch das Abschneiden der Nachkommastellen wird die Zahl etwas größer. -3 / 2 ist genau genommen –1,5, aber bei der Ganzzahldivision -1. Doch -1 ist größer als –1,5. Java wendet ein Verfahren an, das gegen null rundet.

Die gegen minus unendlich rundende Methode floorDiv(…)

Drei Methoden runden bei negativem Ergebnis einer Division nicht gegen null, sondern gegen negativ unendlich, also auch in Richtung der kleineren Zahl, wie es bei den positiven Ergebnissen ist.

class java.lang.Math

class java.lang.StrictMath
  • static int floorDiv(int x, int y)

  • static long floorDiv(long x, long y)

  • static long floorDiv(long x, int y) – erst seit Java 9

Ganz praktisch heißt das: 4/2 = Math.floorDiv(4, 3) = 1, aber wo -4 / 3 = -1 ergibt, liefert Math.floorDiv(-4, 3) = -2.

Die gegen minus unendlich rundende Methode floorMod(…)

Die Division taucht indirekt auch bei der Berechnung des Restwerts auf. Zur Erinnerung: Der Zusammenhang zwischen Division a/b und Restwert a%b (a heißt Dividend, b Divisor) ist (int)(a/b) * b + (a%b) = a. In der Gleichung gibt es eine Division, doch da es mit a / b und floorDiv(a, b) zwei Arten von Divisionen gibt, muss es folglich auch zwei Arten von Restwertbildung geben, die sich dann unterscheiden, wenn die Vorzeichen unterschiedlich sind. Neben a % b gibt es daher die Bibliotheksmethode floorMod(a, b), und der Zusammenhang zwischen floorMod(…) und floorDiv(…) ist: floorDiv(a, b) * b + floorMod(a, b) == b. Nach einer Umformung der Gleichung folgt floorMod(a, b) = a - (floorDiv(a, b) * b). Das Ergebnis ist im Bereich -abs(b) und abs(b), und das Vorzeichen des Ergebnisses bestimmt der Divisor b (beim %-Operator ist es der Dividend a).

Die Javadoc zeigt ein Beispiel mit den Werten 4 und 3 bei unterschiedlichen Vorzeichen:

floorMod(…)-Methode

%-Operator

floorMod(+4, +3) == +1

+4 % +3 == +1

floorMod(+4, -3) == -2

+4 % -3 == +1

floorMod(-4, +3) == +2

-4 % +3 == -1

floorMod(-4, -3) == -1

-4 % -3 == -1

Tabelle 21.11    Ergebnis unterschiedlicher Restwertbildung

Sind die Vorzeichen für a und b identisch, so ist auch das Ergebnis von floorMod(a, b) und a % b gleich. Die Beispiele in der Tabelle machen auch den Unterschied im Ergebnisvorzeichen deutlich, das einmal vom Dividenden (%) und einmal vom Divisor (floorMod(…)) kommt. Die komplett anderen Ereignisse (vom Vorzeichen einmal abgesehen) bei den Paaren (+4, –3) und (–4, +3) ergeben sich ganz einfach aus unterschiedlichen Ergebnissen der Division:

floorMod(+4, -3) = +4 - (floorDiv(+4, -3) * -3) = +4 - (-2 * -3) = +4 - +6 = 

-2 +4 % -3 = +4 - (+4/-3 * -3) = +4 – (-1 * -3) = +4 – 3 = +1
class java.lang.Math

class java.lang.StrictMath
  • static int floorMod(int x, int y)

  • static long floorMod(long x, long y)

  • static long floorMod(long x, int y) – erst seit Java 9

Die Implementierung ist relativ einfach mit x - floorDiv(x, y) * y angegeben.

 

Zum Seitenanfang

21.3.7    Multiply-Accumulate Zur vorigen ÜberschriftZur nächsten Überschrift

Die mathematische Operation a × b + c kommt in Berechnungen oft vor, sodass Prozessoren heute diese Berechung optimiert – das heißt schneller und mit besserer Genauigkeit – durchführen können. Bei Math und StrictMath gibt es seit Java 9 die Methode fma(…) für die fused multiply-accumulate-Funktion aus dem IEEE-754-Standard.

class java.lang.Math

class java.lang.StrictMath
  • static double fma(double a, double b, double c)

  • static float fma(float a, float b, float c)

    Führen a × b + c mit dem RoundingMode.HALF_EVEN durch. Gegenüber einem einfachen a * b + c berücksichtigt fma(…) die Besonderheiten unendlich und NaN.

 

Zum Seitenanfang

21.3.8    Wurzel- und Exponentialmethoden Zur vorigen ÜberschriftZur nächsten Überschrift

Die Math-Klasse bietet außerdem Methoden zum Berechnen der Wurzel und weitere Exponentialmethoden:

class java.lang.Math
  • static double sqrt(double x)

    Liefert die Quadratwurzel von x; sqrt steht für square root.

  • static double cbrt(double a)

    Berechnet die Kubikwurzel aus a.

  • static double hypot(double x, double y)

    Berechnet die Wurzel aus x2 + y2, also den euklidischen Abstand. Könnte als sqrt(x*x, y*y) umgeschrieben werden, doch hypot(…) bietet eine bessere Genauigkeit und Performance.

  • static double scalb(double d, double scaleFactor)

    Liefert d mal 2 hoch scaleFactor. Kann prinzipiell auch als d * Math.pow(2, scaleFactor) geschrieben werden, doch scalb(…) bietet eine bessere Performance.

  • static double exp(double x)

    Liefert den Exponentialwert von x zur Basis e (der eulerschen Zahl e = 2,71828…), also ex.

  • static double expm1(double x)

    Liefert den Exponentialwert von x zur Basis e minus 1, also ex – 1. Berechnungen nahe null kann expm1(x) + 1 präziser ausdrücken als exp(x).

  • static double pow(double x, double y)

    Liefert den Wert der Potenz xy. Für ganzzahlige Werte gibt es keine eigene Methode.

Die Frage nach dem 0.0/0.0 und 0.0^0.0 *

Wie wir wissen, ist 0.0/0.0 ein glattes NaN. Im Unterschied zu den Ganzzahlwerten bekommen wir hier allerdings keine Exception, denn dafür ist extra die Spezialzahl NaN eingeführt worden. Interessant ist die Frage, was denn (long)(double)(0.0/0.0) ergibt. Die Sprachdefinition sagt hier in § 5.1.3, dass die Konvertierung eines Fließkommawerts NaN in ein int 0 oder in ein long 0 ergibt.

Eine weitere spannende Frage ist das Ergebnis von 0.00.0. Um allgemeine Potenzen zu berechnen, wird die statische Funktion Math.pow(double a, double b) eingesetzt. Wir erinnern uns aus der Schulzeit daran, dass wir die Quadratwurzel einer Zahl ziehen, wenn der Exponent b genau ½ ist. Doch jetzt wollen wir wissen, was denn gilt, wenn a = b = 0 gilt. § 20.11.13 der Sprachdefinition fordert, dass das Ergebnis immer 1.0 ist, wenn der Exponent b gleich –0.0 oder 0.0 ist. Es kommt also in diesem Fall überhaupt nicht auf die Basis a an. In einigen Algebra-Büchern wird 00 als undefiniert behandelt. Es macht aber durchaus Sinn, 00 als 1 zu definieren, da es andernfalls viele Sonderbehandlungen für 0 geben müsste.[ 274 ](Hier schreiben R. Graham, D. Knuth und O. Patashnik, die Autoren des Buchs Concrete Mathematics (Addison-Wesley, 1994, ISBN 0-201-55802-5): »Some textbooks leave the quantity 0^0 undefined, because the functions x^0 and 0^x have different limiting values when x decreases to 0. But this is a mistake. We must define x^0 = 1 for all x, if the binomial theorem is to be valid when x=0, y=0, and/or x=-y. The theorem is too important to be arbitrarily restricted! By contrast, the function 0^x is quite unimportant.« )

 

Zum Seitenanfang

21.3.9    Der Logarithmus * Zur vorigen ÜberschriftZur nächsten Überschrift

Der Logarithmus ist die Umkehrfunktion der Exponentialfunktion. Die Exponentialfunktion und der Logarithmus hängen durch folgende Beziehung zusammen: Ist y = ax, dann ist x = loga(y). Der Logarithmus, den Math.log(double) berechnet, ist der natürliche Logarithmus zur Basis e. In der Mathematik wird dieser mit ln angegeben (logarithmus naturalis). Logarithmen mit der Basis 10 heißen dekadische oder briggsche Logarithmen und werden mit lg abgekürzt, und der Logarithmus zur Basis 2 (binärer Logarithmus, dualer Logarithmus) wird mit lb abgekürzt. In Java gibt es die statische Methode log10(double) für den briggschen Logarithmus lg, nicht aber für den binären Logarithmus lb, der weiterhin nachgebildet werden muss. Allgemein gilt folgende Umrechnung: logb(x) = loga(x) ÷ loga(b).

[zB]  Beispiel

Eine eigene statische Methode soll den Logarithmus zur Basis 2 berechnen:

public static double lb( double x ) {

return Math.log( x ) / Math.log( 2.0 );

}

Da Math.log(2) konstant ist, sollte dieser Wert aus Performance-Gründen in einer Konstanten gehalten werden: static final double log2 = Math.log(2.0). Das gilt übrigens für andere konstante Ergebnisse auch, denn es ist nicht davon auszugehen, dass die JVM das Ergebnis des Methodenaufrufs einsetzt, anstatt die Methode aufzurufen. Für die JVM handelt es sich erst einmal um irgendeine Methode ohne Bedeutung. C-Compiler sind hier deutlich weiter.[ 275 ](Wer Lust hat, zu spielen, besucht http://godbolt.org/ und setzt im Editor Folgendes ein:

#include <math.h>

#include
<stdio.h>

int main() { return (int)(log(2.0)*1000 ); })

class java.lang.Math
  • static double log(double a)

    Berechnet von a den Logarithmus zur Basis e.

  • static double log10(double a)

    Liefert von a den Logarithmus zur Basis 10.

  • static double log1p(double x)

    Liefert log(x) + 1.

 

Zum Seitenanfang

21.3.10    Winkelmethoden * Zur vorigen ÜberschriftZur nächsten Überschrift

Die Math-Klasse stellt einige winkelbezogene Methoden und deren Umkehrungen zur Verfügung. Im Gegensatz zur bekannten Schulmathematik werden die Winkel für sin(double), cos(double) und tan(double) im Bogenmaß (2π entspricht einem Vollkreis) und nicht im Gradmaß (360 Grad entspricht einem Vollkreis) übergeben.

class java.lang.Math
  • static double sin(double x)

  • static double cos(double x)

  • static double tan(double x)

    Liefern den Sinus, Kosinus bzw. Tangens von x.

Arcus-Methoden

Die Arcus-Methoden realisieren die Umkehrfunktionen zu den trigonometrischen Methoden. Das Argument ist kein Winkel, sondern zum Beispiel bei asin(double) der Sinuswert zwischen –1 und 1. Das Ergebnis ist ein Winkel im Bogenmaß, etwa zwischen –π/2 und π/2.

class java.lang.Math
  • static double asin(double x)

  • static double acos(double x)

  • static double atan(double x)

    Liefern den Arcus-Sinus, Arcus-Kosinus bzw. Arcus-Tangens von x.

  • static double atan2(double x, double y)

    Liefert bei der Konvertierung von Rechteckkoordinaten in Polarkoordinaten den Winkel theta, also eine Komponente des Polarkoordinaten-Tupels. Die statische Methode berücksichtigt das Vorzeichen der Parameter x und y, und der freie Schenkel des Winkels befindet sich im richtigen Quadranten.

Hyperbolicus-Methoden bietet Java über sinh(double), tanh(double) und cosh(double).

Umrechnungen von Gradmaß in Bogenmaß

Zur Umwandlung eines Winkels vom Gradmaß ins Bogenmaß und umgekehrt existieren zwei statische Methoden:

class java.lang.Math
  • static double toRadians(double angdeg)

    Wandelt einen Winkel vom Gradmaß ins Bogenmaß um.

  • static double toDegrees(double angrad)

    Wandelt einen Winkel vom Bogenmaß ins Gradmaß um.

 

Zum Seitenanfang

21.3.11    Zufallszahlen Zur vorigen ÜberschriftZur nächsten Überschrift

Positive Gleitkomma-Zufallszahlen zwischen größer gleich 0,0 und echt kleiner 1,0 liefert die statische Methode Math.random(). Die Rückgabe ist double, und eine Typumwandlung in int führt immer zum Ergebnis 0.

Möchten wir Werte in einem anderen Wertebereich haben, ist es eine einfache Lösung, die Zufallszahlen von Math.random() durch Multiplikation (Skalierung) auf den gewünschten Wertebereich auszudehnen und per Addition (ein Offset) geeignet zu verschieben. Um ganzzahlige Zufallszahlen zwischen min (inklusiv) und max (inklusiv) zu erhalten, schreiben wir:

Listing 21.8    src/main/java/com/tutego/insel/math/RandomIntInRange.java

public static long random( long min, long max ) {

return min + Math.round( Math.random() * (max - min) );

}

Eine Alternative bietet der direkte Einsatz der Klasse Random und der Objektmethode nextInt(n).

Die Implementierung steckt nicht in der Mathe-Klasse selbst, sondern in Random, die wir uns in Abschnitt 21.5, »Zufallszahlen: Random, SecureRandom und SplittableRandom«, genauer ansehen.

 


Ihre Meinung?

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de

<< zurück
 Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Java ist auch eine Insel Java ist auch eine Insel

Jetzt Buch bestellen


 Buchempfehlungen
Zum Rheinwerk-Shop: Captain CiaoCiao erobert Java

Captain CiaoCiao erobert Java




Zum Rheinwerk-Shop: Java SE 9 Standard-Bibliothek

Java SE 9 Standard-Bibliothek




Zum Rheinwerk-Shop: Algorithmen in Java

Algorithmen in Java




Zum Rheinwerk-Shop: Objektorientierte Programmierung

Objektorientierte Programmierung




 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und in die Schweiz

InfoInfo



 

 


Copyright © Rheinwerk Verlag GmbH 2021

Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.

Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 

[Rheinwerk Computing]



Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de



Cookie-Einstellungen ändern