Ich habe nachgeschlagen, was dies bewirkt, aber hat jemand tatsächlich ein Beispiel dafür, wann Sie das strictfp
Schlüsselwort in Java verwenden würden? Hat jemand tatsächlich eine Verwendung dafür gefunden?
Würde es irgendwelche Nebenwirkungen geben, wenn ich es nur auf alle meine Gleitkommaoperationen anwenden würde?
Antworten:
Strictfp stellt sicher, dass Sie auf jeder Plattform genau die gleichen Ergebnisse aus Ihren Gleitkommaberechnungen erhalten. Wenn Sie strictfp nicht verwenden, kann die JVM-Implementierung, sofern verfügbar, zusätzliche Präzision verwenden.
Aus dem JLS :
Mit anderen Worten, es geht darum sicherzustellen, dass Write-Once-Run-Anywhere tatsächlich Write-Once-Get-Equally-Wrong-Results-Everywhere bedeutet .
Mit strictfp sind Ihre Ergebnisse portabel, ohne sie sind sie mit größerer Wahrscheinlichkeit genau.
quelle
Wikipedia hat hier tatsächlich einen guten Artikel zu diesem Thema mit einem Link zur Java-Spezifikation.
Wenn Sie zwischen den Zeilen lesen, bedeutet dies
strictfp
, dass der JVM- und der JIT-Compiler die Lizenz haben, Ihre Gleitkommaberechnungen nach Belieben zu berechnen , wenn Sie dies nicht angeben . Im Interesse der Geschwindigkeit werden sie die Berechnung höchstwahrscheinlich an Ihren Prozessor delegieren. Mitstrictfp
on müssen die Berechnungen den IEEE 754-Arithmetikstandards entsprechen, was in der Praxis wahrscheinlich bedeutet, dass die JVM die Berechnung durchführt.Warum sollten Sie also verwenden
strictfp
? Ein Szenario, das ich sehen kann, ist eine verteilte Anwendung (oder ein Multiplayer-Spiel), in der alle Gleitkommaberechnungen deterministisch sein müssen, unabhängig von der zugrunde liegenden Hardware oder CPU. Was ist der Kompromiss? Höchstwahrscheinlich Ausführungszeit.quelle
strictfp
Berechnungen sogar eine nicht hilfreiche 8087-FPU. Es ist nur dann der Fall, dass ein wenig Sorgfalt erforderlich ist. Siehe stackoverflow.com/questions/18496560/…strictfp
die Einhaltung des IEEE 754-Standards sichergestellt ist (sodass Sie auf allen Plattformen das gleiche Ergebnis erzielen). Der einzige Nachteil, den ich sehen kann, ist, dass Sie möglicherweise die Vorteile einer wirklich guten FPU in Ihrer nativen Hardware verlieren.Alles begann mit einer Geschichte,
Als Java von James Gosling, Herbert und dem Rest seines Teams entwickelt wurde. Sie hatten dieses verrückte Ding im Sinn, das Plattformunabhängigkeit genannt wurde . Sie wollten Eiche machen (Java)so viel besser, dass es auf jedem Computer mit unterschiedlichen Befehlssätzen genau gleich läuft, selbst wenn unterschiedliche Betriebssysteme ausgeführt werden. Es gab jedoch ein Problem mit Dezimalstellen, die in Programmiersprachen auch als Gleitkomma- und Doppelpunktzahlen bezeichnet werden. Einige Maschinen wurden so gebaut, dass sie auf Effizienz abzielen, während der Rest auf Genauigkeit abzielte. Die späteren (genaueren) Maschinen hatten also eine Gleitkommagröße von 80 Bit, während die früheren (effizienteren / schnelleren) Maschinen 64-Bit-Doppel hatten. Dies widersprach jedoch der Kernidee, eine plattformunabhängige Sprache aufzubauen. Dies kann auch zu einem Verlust an Präzision / Daten führen, wenn ein Code auf einem Computer (mit einer doppelten Größe von 64 Bit) erstellt und auf einem anderen Maschinentyp (mit einer doppelten Größe von 80 Bit) ausgeführt wird.
Up-Sizing kann toleriert werden, Down-Sizing jedoch nicht. Sie stießen also auf ein Konzept von strictfp, dh striktem Gleitkomma . Wenn Sie dieses Schlüsselwort mit einer Klasse / Funktion verwenden, haben Gleitkomma und Double eine einheitliche Größe für jede Maschine. dh 32/64 -bit.
quelle
Hier sind einige Referenzen:
jGuru: Wofür ist der strictfp-Modifikator? Wann würde ich in Betracht ziehen, es zu verwenden?
strictfp - Java Glossar
Und schließlich die eigentliche Java-Sprachspezifikation, §15.4 FP-strenge Ausdrücke :
Ich persönlich hatte jedoch nie eine Verwendung dafür.
quelle
Wie in den anderen Antworten erwähnt, entsprechen die Zwischenergebnisse des Gleitkommas der IEEE-Spezifikation. Insbesondere x86-Prozessoren können Zwischenergebnisse mit einer anderen Genauigkeit als in der IEEE-Spezifikation speichern. Die Situation wird komplizierter, wenn die JIT eine bestimmte Berechnung optimiert. Die Reihenfolge der Anweisungen kann jedes Mal anders sein, was zu leicht unterschiedlichen Rundungen führt.
Der Overhead von strictfp ist wahrscheinlich sehr prozessor- und JIT-abhängig. Dieser Wikipedia-Artikel über SSE2 scheint einen Einblick in das Problem zu haben. Wenn die JIT also SSE-Anweisungen zur Durchführung einer Berechnung generieren kann, scheint strictfp keinen Overhead zu haben.
In meinem aktuellen Projekt gibt es einige Stellen, an denen ich strictfp verwende. Es gibt einen Punkt, an dem potenzielle kosmische Strahlen aus den Pixelwerten entfernt werden müssen. Wenn ein externer Forscher den gleichen Pixelwert und die gleiche kosmische Strahlung vor sich hat, sollte er den gleichen resultierenden Wert wie unsere Software erhalten.
quelle
strictfp ist ein Modifikator, der Gleitkommaberechnungen gemäß IEEE 754 einschränkt.
Dies kann für eine ganze Klasse wie "public strictfp class StrictFpModifierExample {}" oder für die Methode "public strictfp void example ()" verwendet werden. Wenn es für eine Klasse verwendet wird, folgen alle Methoden IEEE 754, und wenn es für eine Methode verwendet wird, wird eine bestimmte Methode verwendet Folgen Sie IEEE 754.
Warum wird es verwendet? ::: Da verschiedene Plattformen unterschiedliche Gleitkomma-Hardware haben, die präziser und in einem größeren Wertebereich berechnet, als es die Java-Spezifikation erfordert, kann dies zu einer unterschiedlichen Ausgabe auf unterschiedlichen Plattenformen führen. Daher wird dieselbe Ausgabe unabhängig von der unterschiedlichen bestätigt Plattenformen
strictfp stellt außerdem sicher, dass die Geschwindigkeit und Präzision der Gleitkommaoperationen mit erweiterter Präzision genutzt werden.
Dieses Schlüsselwort, das wir bei Gleitkommaberechnungen verwenden können, hat keinen Nachteil
Mein letzter Punkt ist - Was ist IEEE754, kurz IEEE 754 definiert die Standardmethode sowohl für Gleitkommaberechnungen als auch für die Speicherung von Gleitkommawerten in Einzel- (32-Bit, in Java-Floats verwendet) oder Doppel- (64-Bit, in Java verwendet) Doppelte) Genauigkeit. Es definiert auch Normen für Zwischenberechnungen und für erweiterte Präzisionsformate.
quelle
strictfp
ist ein Schlüsselwort und kann als Nicht-Zugriffsmodifikator für Klassen oder Methoden (jedoch niemals Variablen) verwendet werden. Das Markieren einer Klasse alsstrictfp
bedeutet, dass jeder Methodencode in der Klasse den IEEE 754-Standardregeln für Gleitkommazahlen entspricht.Ohne diesen Modifikator können sich Gleitkommawerte, die in den Methoden verwendet werden, plattformabhängig verhalten. Damit können Sie vorhersagen, wie sich Ihre Gleitkommawerte unabhängig von der zugrunde liegenden Plattform, auf der die JVM ausgeführt wird, verhalten werden. Der Nachteil ist, dass eine
strictfp
Methode diese nicht nutzen kann , wenn die zugrunde liegende Plattform eine höhere Präzision unterstützt .Wenn Sie eine Klasse nicht als deklarieren
strictfp
, können Sie dasstrictfp
Verhalten immer noch methodenweise abrufen, indem Sie eine Methode als deklarierenstrictfp
.~ SCJP Sun®Certified Programmer für Java ™ 6 - Kathy Sierra & Bert Bates ~
quelle
Kann das folgende Beispiel helfen, dies klarer zu verstehen: In Java, wenn wir nach genauen Informationen für eine Operation suchen, z. B. wenn wir double num1 = 10e + 102 ausführen; doppelte Zahl2 = 8e + 10; Ergebnis = num1 + num2;
quelle
Das Schlüsselwort 'strictfp' wird verwendet, um die Genauigkeit von Gleitkommaberechnungen (float oder double) in Java zu erzwingen, die explizit dem IEEE-Standard 754 entsprechen. Wenn Sie das Schlüsselwort strictfp nicht verwenden, hängt die Gleitkommapräzision von der Hardware der Zielplattform ab.
Wenn eine Schnittstelle oder Klasse mit strictfp deklariert wird, sind alle Methoden und verschachtelten Typen innerhalb dieser Schnittstelle oder Klasse implizit strictfp.
Referenz - Link
quelle