私はこれが何をするか調べましたが、誰かが実際strictfp
にJavaでキーワードを使用するときの例を持っていますか?誰かが実際にこれの用途を見つけましたか?
私のすべての浮動小数点演算にそれを置くだけの副作用はありますか?
私はこれが何をするか調べましたが、誰かが実際strictfp
にJavaでキーワードを使用するときの例を持っていますか?誰かが実際にこれの用途を見つけましたか?
私のすべての浮動小数点演算にそれを置くだけの副作用はありますか?
回答:
Strictfpは、すべてのプラットフォームでの浮動小数点計算からまったく同じ結果が得られることを保証します。strictfpを使用しない場合、JVM実装は、可能な場合は追加の精度を自由に使用できます。
FP-strict式内では、すべての中間値はfloat値セットまたはdouble値セットの要素である必要があります。つまり、すべてのFP-strict式の結果は、シングルおよびダブル形式を使用して表されるオペランドのIEEE 754演算によって予測されたものでなければなりません。 。FP厳格ではない式の中で、拡張された指数範囲を使用して中間結果を表す実装には、ある程度の余裕があります。正味の効果は、大まかに言えば、float値セットまたはdouble値セットを排他的に使用するとオーバーフローまたはアンダーフローが発生する可能性がある場合に、計算が「正しい答え」を生成する可能性があることです。
つまり、Write-Once-Run-Anywhereが実際にWrite-Once-Get-Equally-Wrong-Results-Everywhereを意味することを確認することです。
strictfpを使用すると、結果は移植可能ですが、それがないと、正確になる可能性が高くなります。
ウィキペディアは実際には、このトピックについての良い記事があるここを Java仕様へのリンクを、。
行間を読むと、指定しないと strictfp
、JVMおよびJITコンパイラーは浮動小数点計算を必要に応じて計算するライセンスを持っていることになります。速度の観点から、それらはおそらくあなたのプロセッサに計算を委任します。ではstrictfp
上、計算は実際には、おそらくJVMは、計算を行うことを意味し、IEEE 754算術標準に準拠する必要があります。
では、なぜ使用したいのでしょうstrictfp
か?私が見ることができる1つのシナリオは、基盤となるハードウェアやCPUに関係なく、すべての浮動小数点計算を決定論的にする必要がある分散アプリケーション(またはマルチプレイヤーゲーム)です。トレードオフとは何ですか?最も可能性の高い実行時間。
strictfp
計算でさえ役に立たない8087 FPUを利用します。少し注意が必要なのはこの場合だけです。stackoverflow.com/questions/18496560/…を
strictfp
、IEEE 754標準への準拠を保証するため(この場合、すべてのプラットフォームで同じ結果が得られるようになるため)、この場合は逆になります。私が見ることができる唯一の欠点は、ネイティブハードウェアで非常に優れたFPUを利用できるという利点を失う可能性があることです。
すべては物語から始まりました、
JavaがJames Gosling、Herbert、および彼のチームの他のメンバーによって開発されていたとき。彼らは、プラットフォームの独立性と呼ばれるこのクレイジーなことを念頭に置いていました。彼らはオークを作りたかった(Java)非常に優れているため、異なるオペレーティングシステムを実行していても、命令セットが異なるマシンでまったく同じように実行できます。しかし、浮動小数点やプログラミング言語ではdoubleとも呼ばれる小数点の数に問題がありました。残りは精度を目標としたものの、一部のマシンは効率を目標にして構築されました。したがって、後の(より正確な)マシンは浮動小数点のサイズが80ビットでしたが、前者の(より効率的で高速な)マシンは64ビットの倍精度でした。しかし、これはプラットフォームに依存しない言語を構築するという核となる考えに反していました。また、コードが64ビットサイズの2倍のマシンでビルドされ、80ビットサイズの2倍のマシンで実行されると、精度/データが失われる可能性があります。
アップサイジングは許容できますが、ダウンサイジングは許容できません。そのため、彼らはstrictfp(厳密な浮動小数点)の概念に出くわしました。このキーワードをクラス/関数で使用すると、その浮動小数点と倍精度浮動小数点は、どのマシンでも一貫したサイズになります。つまり、それぞれ32/64ビットです。
ここにいくつかの参照があります:
jGuru:strictfp修飾子は何ですか?いつ使用することを検討しますか?
基本的に、結局のところ、コード内の浮動小数点式の結果が高速であるか予測可能であるかどうかを気にするかどうかです。たとえば、複数のプラットフォーム間で一貫性を保つために浮動小数点値を使用するコードで得られる答えが必要な場合は、を使用します
strictfp
。
浮動小数点ハードウェアは、Java仕様が必要とするよりも高い精度とより広い範囲の値で計算します。一部のプラットフォームが他のプラットフォームよりも精度を高めていると、混乱を招きます。
strictfp
メソッドまたはクラスで修飾子を使用すると、コンパイラーは、すべてのプラットフォームで同一の結果を得るために、Java仕様に厳密に準拠するコードを生成します。なしstrictfp
では、それは少し緩いですが、Pentiumのガードビットを使用して80ビットの精度を与えるほど緩いわけではありません。
そして最後に、実際のJava言語仕様、§15.4FP-strict式:
FP-strict式内では、すべての中間値はfloat値セットまたはdouble値セットの要素である必要があります。つまり、すべてのFP-strict式の結果は、シングルおよびダブル形式を使用して表されるオペランドのIEEE 754演算によって予測されたものでなければなりません。 。FP厳格ではない式の中で、拡張された指数範囲を使用して中間結果を表す実装には、ある程度の余裕があります。正味の効果は、大まかに言えば、float値セットまたはdouble値セットを排他的に使用するとオーバーフローまたはアンダーフローが発生する可能性がある状況で、計算が「正しい答え」を生成する可能性があるということです。
でも、個人的に使ったことはありません。
他の回答で述べたように、中間浮動小数点の結果はIEEE仕様に準拠します。特に、x86プロセッサは、IEEE仕様とは異なる精度で中間結果を保存できます。JITが特定の計算を最適化すると、状況はさらに複雑になります。命令の順序は毎回異なり、結果として丸めがわずかに異なる場合があります。
strictfpによって発生するオーバーヘッドは、プロセッサとJITに大きく依存する可能性があります。SSE2に関するこのウィキペディアの記事、問題についてある程度の洞察を持っているようです。したがって、JITがSSE命令を生成して計算を実行できる場合、strictfpにはオーバーヘッドがないようです。
現在のプロジェクトでは、strictfpを使用する場所がいくつかあります。潜在的な宇宙線をピクセル値から削除する必要があるポイントがあります。外部の研究者が同じピクセル値と宇宙線を前面に持っている場合、彼らは私たちのソフトウェアと同じ結果値を取得するはずです。
strictfpは、IEEE 754に従って浮動小数点の計算を制限する修飾子です。
これは、「public strictfp class StrictFpModifierExample {}」のようなクラス全体またはメソッド「public strictfp void example()」で使用できます。すべてのメソッドがクラスで使用される場合、すべてのメソッドはIEEE 754に従い、メソッドで使用される場合、特定のメソッドはIEEE 754に従ってください。
それが使用される理由は?? :::異なるプラットフォームが異なる浮動小数点ハードウェアを持っているため、Java仕様が必要とするよりも高い精度と広い範囲の値で計算されるため、異なるプレートフォームで異なる出力が生成される可能性があります。プレートフォーム
strictfpは、拡張精度浮動小数点演算の速度と精度を確実に利用することもできます。
浮動小数点計算を行うときに使用できるこのキーワードには不利はありません
私の最後のポイントは--IEEE754とは要するに? doubles)precision。これは、中間計算および拡張精度フォーマットの基準も定義します。
strictfp
キーワードであり、クラスまたはメソッドの非アクセス修飾子として使用できます(ただし、変数は使用できません)。クラスにマークを付けるstrictfp
内のメソッドコードが浮動小数点に関するIEEE 754標準規則に準拠することになります。
その修飾子がないと、メソッドで使用される浮動小数点はプラットフォームに依存した方法で動作する可能性があります。これにより、JVMが実行されている基盤となるプラットフォームに関係なく、浮動小数点の動作を予測できます。欠点は、基盤となるプラットフォームがより高い精度をサポートできる場合、strictfp
メソッドはそれを利用できないことです。
クラスをとして宣言しない場合strictfp
でもstrictfp
、メソッドを次のように宣言することにより、メソッドごとに動作を取得できます。strictfp
。
〜Java™6のSCJPSun®認定プログラマー-Kathy Sierra&Bert Bates〜
以下の例は、これをより明確に理解するのに役立ちます。たとえば、Javaで使用する場合は常に、任意の操作の正確な情報を探します。たとえば、double num1 = 10e + 102; double num2 = 8e + 10; 結果= num1 + num2;
The output will be so long and not precise, becasue it is precissed by the hardware e.g JVM and JIT has the license
as long as we dont have specify it Strictfp
Marking it Strictfp will make the result Uniform on every hardware and platform, because its precised value will be same
One scenario I can see is in a distributed application (or multiplayer game) where all floating-point calculations need to
be deterministic no matter what the underlying hardware or CPU is.