18.5 Mathe bitte strikt *
Bei der Berechnung mit Fließkommazahlen schreibt die Definition des IEEE 754-Standards vor, wie numerische Berechnungen durchgeführt werden. Damit soll die CPU/FPU für float und double mit 32 beziehungsweise 64 Bit rechnen. In Wirklichkeit rechnet jedoch so gut wie kein mathematischer Prozessor mit diesen Größen, außer vielleicht AMD mit der 3Dnow!-Technologie. Auf der PC-Seite kommen Intel und AMD mit internen Rechengenauigkeiten von 80 Bit, also 10 Byte, zum Zuge. Dieses Dilemma betrifft aber nur 80x86- und andere CISC-Prozessoren. Bei RISC sind 32 Bit und 64 Bit das Übliche. Die 80-Bit-Lösung bringt in Java zwei Nachteile mit sich:
- Diese Genauigkeit kann Java bisher nicht nutzen.
- Wegen der starren IEEE 754-Spezifikation kann der Prozessor weniger Optimierungen durchführen, weil er sich immer eng an die Norm halten muss. Das kostet Zeit. Gegebenenfalls können aber die mathematischen Ergebnisse auf unterschiedlichen Maschinen anders aussehen.
18.5.1 Strikte Fließkommaberechnungen mit strictfp

Damit zum einen die Vorgaben der Norm erfüllt werden und zum anderen die Geschwindigkeit gewährleistet werden kann, lässt sich vor Klassen und Methoden der Modifizierer strictfp setzen, damit Operationen strikt nach der IEEE-Norm vorgehen. Ohne dieses Schlüsselwort (wie es also für die meisten unserer Programme der Fall ist) nimmt die JVM eine interne Optimierung vor. Nach außen bleiben die Datentypen 32 Bit und 64 Bit lang, das heißt: Bei den Konstanten in double und float ändert sich nichts. Zwischenergebnisse bei Fließkommaberechnungen werden aber eventuell mit größerer Genauigkeit berechnet.
18.5.2 Die Klassen Math und StrictMath
Für strikte mathematische Operationen gibt es eine eigene Klasse StrictMath. An der Klassendeklaration für StrictMath lässt sich ablesen, dass alle Methoden sich an die IEEE-Norm halten.
Listing 18.9: java.lang.StrictMath.java, StrictMath
public final strictfp class StrictMath {
// ...
}
Allerdings gibt es nicht zwei Implementierungen der mathematischen Methoden – einmal strikt und genau beziehungsweise einmal nicht strikt, dafür potenziell schneller. Bisher delegiert die Implementierung für Math direkt an StrictMath:
Listing 18.10: java.lang.Math.java, Ausschnitt
public final strictfp class Math
{
public static double tan( double a ) {
return StrictMath.tan( a );
// default impl. delegates to StrictMath
}
// ...
}
Die Konsequenz ist, dass alle Methoden wie Math.pow() strikt nach IEEE-Norm rechnen. Das ist zwar aus Sicht der Präzision und Übertragbarkeit der Ergebnisse wünschenswert, aber die Performance ist nicht optimal.
Ihr Kommentar
Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.