Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.
 
Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Imperative Sprachkonzepte
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Eigene Klassen schreiben
6 Objektorientierte Beziehungsfragen
7 Ausnahmen müssen sein
8 Äußere.innere Klassen
9 Besondere Typen der Java SE
10 Generics<T>
11 Lambda-Ausdrücke und funktionale Programmierung
12 Architektur, Design und angewandte Objektorientierung
13 Die Klassenbibliothek
14 Einführung in die nebenläufige Programmierung
15 Einführung in Datenstrukturen und Algorithmen
16 Einführung in grafische Oberflächen
17 Einführung in Dateien und Datenströme
18 Einführung ins Datenbankmanagement mit JDBC
19 Einführung in <XML>
20 Testen mit JUnit
21 Bits und Bytes und Mathematisches
22 Die Werkzeuge des JDK
A Java SE Paketübersicht
Stichwortverzeichnis

Download:
- Beispielprogramme, ca. 20,0 MB
- Übungsaufgaben, ca. 1,8 MB
- Musterlösungen, ca. 0,8 MB

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenbloom
Das umfassende Handbuch
Buch: Java ist auch eine Insel

Java ist auch eine Insel
Rheinwerk Computing
1306 Seiten, gebunden, 11. Auflage
49,90 Euro, ISBN 978-3-8362-2873-2
Pfeil 21 Bits und Bytes und Mathematisches
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 Typanpassung auf die Bitmuster
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 Richtung negativ unendlich, alternativer Restwert *
Pfeil 21.3.7 Wurzel- und Exponentialmethoden
Pfeil 21.3.8 Der Logarithmus *
Pfeil 21.3.9 Winkelmethoden *
Pfeil 21.3.10 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
Pfeil 21.4.3 Was bitte macht ein ulp?
Pfeil 21.5 Zufallszahlen: Random, SecureRandom, 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.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 Zum Weiterlesen
 
Zum Seitenanfang

21.4Genauigkeit, Wertebereich eines Typs und Überlaufkontrolle * Zur vorigen ÜberschriftZur nächsten Überschrift

 
Zum Seitenanfang

21.4.1Der größte und der kleinste Wert Zur vorigen ÜberschriftZur nächsten Überschrift

Für jeden primitiven Datentyp gibt es in Java eine eigene Klasse mit diversen Methoden und Konstanten. Die Klassen Byte, Short, Integer, Long, Float und Double besitzen die Konstanten MIN_VALUE und MAX_VALUE für den minimalen und maximalen Wertebereich. Die Klassen Float und Double verfügen zusätzlich über die wichtigen Konstanten NEGATIVE_INFINITY und POSITIVE_INFINITY für minus und plus unendlich und NaN (Not a Number, undefiniert).

[+]Hinweis

Integer.MIN_VALUE steht mit –2147483648 für den kleinsten Wert, den die Ganzzahl annehmen kann. Double.MIN_VALUE steht jedoch für die kleinste positive Zahl (beste Näherung an 0), die ein Double darstellen kann (4.9E–324).

Wenn uns beim Wort double im Vergleich zu float eine »doppelte Genauigkeit« über die Lippen kommt, müssen wir mit der Aussage vorsichtig sein, denn double bietet zumindest nach der Anzahl der Bits eine mehr als doppelt so präzise Mantisse. Über die Anzahl der Nachkommastellen sagt das jedoch direkt nichts aus.

Bastelaufgabe

Warum sind die Ausgaben so, wie sie sind?

Listing 21.9DoubleFloatEqual.java, main()

double d1 = 0.02d;
float f1 = 0.02f;
System.out.println( d1 == f1 ); // false
System.out.println( (float) d1 == f1 ); // true

double d2 = 0.02f;
float f2 = 0.02f;
System.out.println( d2 == f2 ); // true
 
Zum Seitenanfang

21.4.2Überlauf Zur vorigen ÜberschriftZur nächsten Überschrift

Bei einigen mathematischen Fragestellungen muss sich feststellen lassen, ob Operationen wie die Addition, Subtraktion oder Multiplikation den Zahlenbereich sprengen, also etwa den Ganzzahlenbereich eines Integers von 32 Bit verlassen. Passt das Ergebnis einer Berechnung nicht in den Wertebereich einer Zahl, so wird dieser Fehler standardmäßig nicht von Java angezeigt; weder der Compiler noch die Laufzeitumgebung melden dieses Problem. Es gibt auch keine Ausnahme, Java hat keine eingebaute Überlaufkontrolle in der Sprache.

[zB]Beispiel

Mathematisch gilt a × a ÷ a = a, also zum Beispiel 100.000 × 100.000 ÷ 100.000 = 100.000. In Java ist das anders, da wir bei 100.000 × 100.000 einen Überlauf im int haben.

System.out.println( 100000 * 100000 / 100000 ); // 14100

liefert daher 14100. Wenn wir den Datentyp auf long erhöhen, indem wir hinter ein 100.000 ein L setzen, sind wir bei dieser Multiplikation noch sicher, da ein long das Ergebnis aufnehmen kann:

System.out.println( 100000L * 100000 / 100000 ); // 100000

[+]Hinweis

Ein Test auf Überlauf könnte so aussehen:

boolean canMultiply(int a, int b) { return a * b / b == a; }

Doch eine JVM kann das zu return a == a; optimieren und somit zu return true; machen, sodass der Test nicht funktioniert.

Überlauf erkennen

In Java 8 kommen neue Methoden hinzu, die eine Überlauferkennung ermöglichen. Die Methoden gibt es in Math und StrictMath:

class java.lang.Math
class java.lang.StrictMath

  • static int addExact(int x, int y)

  • static long addExact(long x, long y)

  • static int subtractExact(int x, int y)

  • static long subtractExact(long x, long y)

  • static int multiplyExact(int x, int y)

  • static long multiplyExact(long x, long y)

  • static int toIntExact(long value)

Alle Methoden werfen eine ArithmeticException, falls die Operation nicht durchführbar ist, die letzte zum Beispiel, wenn (int)value != value ist. Leider deklariert Java keine Unterklassen wie UnderflowException oder OverflowException, und Java meldet nur alles vom Typ ArithmeticException mit der Fehlermeldung »xxx overflow«, auch wenn es eigentlich ein Unterlauf ist.

[zB]Beispiel

Von der kleinsten Ganzzahl mit subtractExact(…) eins abzuziehen, führt zur Ausnahme:

subtractExact( Integer.MIN_VALUE, 1 ); // ArithmeticException

In Math, aber nicht in StrictMath, gibt es weiterhin:

class java.lang.Math

  • static int incrementExact(int a)

  • static long incrementExact(long a)

  • static int decrementExact(int a)

  • static long decrementExact(long a)

  • static int negateExact(int a)

  • static long negateExact(long a)

Kann wegen des Wertebereichs die Operation nicht durchgeführt werden, folgt wieder eine ArithmeticException.

Vergleich mit C#

C# verhält sich genauso wie Java und reagiert standardmäßig nicht auf einen Überlauf. Es gibt jedoch spezielle checked-Blöcke, die eine OverflowException melden, wenn es bei arithmetischen Grundoperationen zu einem Überlauf kommt. Folgendes löst diese Ausnahme aus: checked { int val = int.MaxValue; val++; }. Solche checked-Blöcke gibt es in Java nicht, wer diese besondere Überlaufkontrolle braucht, muss die Methoden nutzen, und ein val++ dann auch umschreiben zu Math.addExact(val, 1) bzw. Math.incrementExact(val).

 
Zum Seitenanfang

21.4.3Was bitte macht ein ulp? Zur vorigen ÜberschriftZur nächsten Überschrift

Die Math-Klasse bietet sehr spezielle Methoden, die für diejenigen interessant sind, die sich sehr genau mit Rechen(un)genauigkeiten beschäftigen und mit numerischen Näherungen arbeiten.

Der Abstand von einer Fließkommazahl zur nächsten ist durch den internen Aufbau nicht immer gleich. Wie groß genau der Abstand einer Zahl zur nächstmöglichen ist, zeigt ulp(double) bzw. ulp(float). Der lustige Methodenname ist eine Abkürzung für Unit in the Last Place. Was genau denn die nächsthöhere/-niedrigere Zahl ist, ermitteln die Methoden nextUp(float|double)/nextDown(float|double), die auf nextAfter(…) zurückgreifen.

[zB]Beispiel

Was kommt nach und vor 1:

System.out.printf( "%.16f%n", Math.nextUp( 1 ) );
System.out.printf( "%.16f%n", Math.nextDown( 1 ) );
System.out.printf( "%.16f%n", Math.nextAfter( 1, Double.POSITIVE_INFINITY ) );
System.out.printf( "%.16f%n", Math.nextAfter( 1, Double.NEGATIVE_INFINITY ) );

Die Ausgabe ist:

1,000000119209289
0,9999999403953552
1,0000001192092896
0,9999999403953552

nextUp(d) ist eine Abkürzung für nextAfter(d, Double.POSITIVE_INFINITY) und nextDown(d) eine Abkürzung für nextAfter(d, Double.NEGATIVE_INFINITY). Ist das zweite Argument von Math.nextAfter(…) größer als das erste, dann wird die nächstgrößere Zahl zurückgegeben, ist sie kleiner, dann die nächstkleinere Zahl. Bei Gleichheit kommt die gleiche Zahl zurück.

Dazu ein weiteres Beispiel: Je größer die Zahlen werden, desto größer werden auch die Sprünge:

Methode

Rückgabe des ulp

Math.ulp( 0.00001 )

0,000000000000000000001694065895

Math.ulp( –1 )

0,00000011920928955078125

Math.ulp( 1 )

0,00000011920928955078125

Math.ulp( 2 )

0,0000002384185791015625

Math.ulp( 10E30 )

1125899906842624

Tabelle 21.12Da das Vorzeichen in einem eigenen Bit gespeichert ist, haben negative oder positive Zahlen keine anderen Genauigkeiten.

Ein Quantum Ungenauigkeit

Die üblichen mathematischen Fließkommaoperationen haben eine ulp von ½. Das ist so genau wie möglich. Um wie viel ulp die Math-Methoden vom echten Resultat abweichen können, steht in der Javadoc. Rechenfehler lassen sich insbesondere bei komplexen Methoden nicht vermeiden. So darf sin(double) eine mögliche Ungenauigkeit von 1 ulp haben, atan2(double, double) von maximal 2 ulp und sinh(double), cosh(double), tanh(double) von 2,5 ulp.

Die ulp(…)-Methode ist für das Testen interessant, denn mit ihr lassen sich Abweichungen immer in der passenden Größenordnung realisieren. Bei kleinen Zahlen ergibt eine Differenz von vielleicht 0,001 einen Sinn, bei größeren Zahlen kann die Toleranz größer sein.

Java deklariert in den Klassen Double und Float drei besondere Konstanten. Sie lassen sich gut mit nextAfter(…) erklären. Am Beispiel von Double:

  • MIN_VALUE = nextUp(0.0) = Double.longBitsToDouble(0x0010000000000000L)

  • MIN_NORMAL = MIN_VALUE/(nextUp(1.0)-1.0) = Double.longBitsToDouble(0x1L)

  • MAX_VALUE = nextAfter(POSITIVE_INFINITY, 0.0) =
       Double.longBitsToDouble(0x7fefffffffffffffL)

 


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück
 Zum Katalog
Zum Katalog: Java ist auch eine Insel Java ist auch eine Insel
Jetzt bestellen

 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Java SE 8 Standard-Bibliothek
Java SE 8 Standard-Bibliothek


Zum Katalog: Professionell entwickeln mit Java EE 7
Professionell entwickeln mit Java EE 7


Zum Katalog: Schrödinger programmiert Java
Schrödinger programmiert Java


Zum Katalog: Einführung in Java
Einführung in Java


Zum Katalog: Programmieren lernen mit Java
Programmieren lernen mit Java


Zum Katalog: Apps entwickeln für Android 5
Apps entwickeln für Android 5


Zum Katalog: Apps entwickeln mit Android Studio
Apps entwickeln mit Android Studio


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo

 
 


Copyright © Rheinwerk Verlag GmbH 2016
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.

 
Nutzungsbestimmungen | Datenschutz | Impressum

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