Javaで「strictfp」キーワードを使用する必要があるのはいつですか?


258

私はこれが何をするか調べましたが、誰かが実際strictfpにJavaでキーワードを使用するときの例を持っていますか?誰かが実際にこれの用途を見つけましたか?

私のすべての浮動小数点演算にそれを置くだけの副作用はありますか?


1
常に、再現性よりもパフォーマンスが実際に必要な場合を除きます。
アンチモン2012

1
@Antimony-または精度/正確さ。たとえば、x86 / x64は内部で80ビットの浮動小数点レジスターを使用するため、strictfpを使用しない長い計算の結果はより正確になります。
Robert Fraser

1
@Robert実際には、仕様は仮数の制限された精度を保証しています。唯一の違いは、通常よりも大きな指数精度を使用する可能性があることです。まれに、二重丸めのために違いがあります。
アンチモン2016年

この便利なモディファイヤをジョイント全体に散布するオプションに加えて、新しいsfloat&sdoubleプリミティブstrictfpデータ型が良いアイデアかもしれないと思います。
theRiley

回答:


274

Strictfpは、すべてのプラットフォームでの浮動小数点計算からまったく同じ結果が得られることを保証します。strictfpを使用しない場合、JVM実装は、可能な場合は追加の精度を自由に使用できます。

JLSから

FP-strict式内では、すべての中間値はfloat値セットまたはdouble値セットの要素である必要があります。つまり、すべてのFP-strict式の結果は、シングルおよびダブル形式を使用して表されるオペランドのIEEE 754演算によって予測されたものでなければなりません。 。FP厳格ではない式の中で、拡張された指数範囲を使用して中間結果を表す実装には、ある程度の余裕があります。正味の効果は、大まかに言えば、float値セットまたはdouble値セットを排他的に使用するとオーバーフローまたはアンダーフローが発生する可能性がある場合に、計算が「正しい答え」を生成する可能性があることです。

つまり、Write-Once-Run-Anywhereが実際にWrite-Once-Get-Equally-Wrong-Results-Everywhereを意味することを確認することです。

strictfpを使用すると、結果は移植可能ですが、それがないと、正確になる可能性が高くなります。


28
再現可能な科学的結果やビット単位のユニットテストに使用します。
Aleksandr Dubinsky 2014

1
「strictfpを使用しない場合、JVM実装は利用可能な場合に追加の精度を自由に使用できます」-これは悪いことのように聞こえます:P
AMDG

それは確かに@LinkTheProgrammer できる悪いこと
ティム・

@TimCastelijns Happy Wheelsはあなたの参照だと思いますか?リプレイはキーストロークを記録します。FP-math実装の精度の多様性により、再生は同様のハードウェアでのみ正確です。浮動小数点演算のばらつきによって引き起こされる、より現実的な問題を挙げていただけますか?私はおそらく粒子シミュレータを想像できますが、他に何がありますか?
AMDG 2018年

つまり、これは、複数のプラットフォームが関与する本番環境では常にstrictfpを使用する必要があることを意味します。
ビアトリス

65

ウィキペディアは実際には、このトピックについての良い記事があるここを Java仕様へのリンクを、。

行間を読むと、指定しないと strictfp、JVMおよびJITコンパイラーは浮動小数点計算を必要に応じて計算するライセンスを持っていることになります。速度の観点から、それらはおそらくあなたのプロセッサに計算を委任します。ではstrictfp上、計算は実際には、おそらくJVMは、計算を行うことを意味し、IEEE 754算術標準に準拠する必要があります。

では、なぜ使用したいのでしょうstrictfpか?私が見ることができる1つのシナリオは、基盤となるハードウェアやCPUに関係なく、すべての浮動小数点計算を決定論的にする必要がある分散アプリケーション(またはマルチプレイヤーゲーム)です。トレードオフとは何ですか?最も可能性の高い実行時間。


5
「中間結果を表すための拡張指数範囲」は「浮動小数点計算を必要に応じて計算するためのライセンス」ではなく、実際には、strictfp計算でさえ役に立たない8087 FPUを利用します。少し注意が必要なのはこの場合だけです。stackoverflow.com/questions/18496560/…を
Pascal Cuoq 14年

@PascalCuoq reに同意します:必要に応じて浮動小数点計算を計算するためのライセンス」。どちらかと言えばstrictfp、IEEE 754標準への準拠を保証するため(この場合、すべてのプラットフォームで同じ結果が得られるようになるため)、この場合は逆になります。私が見ることができる唯一の欠点は、ネイティブハードウェアで非常に優れたFPUを利用できるという利点を失う可能性があることです。
タイプレーサー

25

すべては物語から始まりました、

JavaがJames Gosling、Herbert、および彼のチームの他のメンバーによって開発されていたとき。彼らは、プラットフォームの独立性と呼ばれるこのクレイジーなことを念頭に置いていました。彼らはオークを作りたかった(Java)非常に優れているため、異なるオペレーティングシステムを実行していても、命令セットが異なるマシンでまったく同じように実行できます。しかし、浮動小数点やプログラミング言語ではdoubleとも呼ばれる小数点の数に問題がありました。残りは精度を目標としたものの、一部のマシンは効率を目標にして構築されました。したがって、後の(より正確な)マシンは浮動小数点のサイズが80ビットでしたが、前者の(より効率的で高速な)マシンは64ビットの倍精度でした。しかし、これはプラットフォームに依存しない言語を構築するという核となる考えに反していました。また、コードが64ビットサイズの2倍のマシンでビルドされ、80ビットサイズの2倍のマシンで実行されると、精度/データが失われる可能性があります。

アップサイジングは許容できますが、ダウンサイジングは許容できません。そのため、彼らはstrictfp(厳密な浮動小数点)の概念に出くわしました。このキーワードをクラス/関数で使用すると、その浮動小数点と倍精度浮動小数点は、どのマシンでも一貫したサイズになります。つまり、それぞれ32/64ビットです。


8
strictfpはJava 1.2で導入されました。これは、オークが設計されたときよりもはるかに遅れていました。
–ThorbjørnRavn Andersen 2017

「10進数は浮動小数点とも呼ばれます」-10進数は10を意味し、浮動小数点表現とは関係ありません。
aioobe

21

ここにいくつかの参照があります:

  • strictfpの使用(JDCテクニカルヒント)
  • jGuru:strictfp修飾子は何ですか?いつ使用することを検討しますか?

    基本的に、結局のところ、コード内の浮動小数点式の結果が高速であるか予測可能であるかどうかを気にするかどうかです。たとえば、複数のプラットフォーム間で一貫性を保つために浮動小数点値を使用するコードで得られる答えが必要な場合は、を使用しますstrictfp

  • strictfp-Java用語集

    浮動小数点ハードウェアは、Java仕様が必要とするよりも高い精度とより広い範囲の値で計算します。一部のプラットフォームが他のプラットフォームよりも精度を高めていると、混乱を招きます。strictfpメソッドまたはクラスで修飾子を使用すると、コンパイラーは、すべてのプラットフォームで同一の結果を得るために、Java仕様に厳密に準拠するコードを生成します。なしstrictfpでは、それは少し緩いですが、Pentiumのガードビットを使用して80ビットの精度を与えるほど緩いわけではありません。

  • そして最後に、実際のJava言語仕様、§15.4FP-strict式

    FP-strict式内では、すべての中間値はfloat値セットまたはdouble値セットの要素である必要があります。つまり、すべてのFP-strict式の結果は、シングルおよびダブル形式を使用して表されるオペランドのIEEE 754演算によって予測されたものでなければなりません。 。FP厳格ではない式の中で、拡張された指数範囲を使用して中間結果を表す実装には、ある程度の余裕があります。正味の効果は、大まかに言えば、float値セットまたはdouble値セットを排他的に使用するとオーバーフローまたはアンダーフローが発生する可能性がある状況で、計算が「正しい答え」を生成する可能性があるということです。

でも、個人的に使ったことはありません。


12

他の回答で述べたように、中間浮動小数点の結果はIEEE仕様に準拠します。特に、x86プロセッサは、IEEE仕様とは異なる精度で中間結果を保存できます。JITが特定の計算を最適化すると、状況はさらに複雑になります。命令の順序は毎回異なり、結果として丸めがわずかに異なる場合があります。

strictfpによって発生するオーバーヘッドは、プロセッサとJITに大きく依存する可能性があります。SSE2に関するこのウィキペディアの記事、問題についてある程度の洞察を持っているようです。したがって、JITがSSE命令を生成して計算を実行できる場合、strictfpにはオーバーヘッドがないようです。

現在のプロジェクトでは、strictfpを使用する場所がいくつかあります。潜在的な宇宙線をピクセル値から削除する必要があるポイントがあります。外部の研究者が同じピクセル値と宇宙線を前面に持っている場合、彼らは私たちのソフトウェアと同じ結果値を取得するはずです。


8
  • strictfpは、IEEE 754に従って浮動小数点の計算を制限する修飾子です。

  • これは、「public strictfp class StrictFpModifierExample {}」のようなクラス全体またはメソッド「public strictfp void example()」で使用できます。すべてのメソッドがクラスで使用される場合、すべてのメソッドはIEEE 754に従い、メソッドで使用される場合、特定のメソッドはIEEE 754に従ってください。

  • それが使用される理由は?? :::異なるプラットフォームが異なる浮動小数点ハードウェアを持っているため、Java仕様が必要とするよりも高い精度と広い範囲の値で計算されるため、異なるプレートフォームで異なる出力が生成される可能性があります。プレートフォーム

  • strictfpは、拡張精度浮動小数点演算の速度と精度を確実に利用することもできます。

  • 浮動小数点計算を行うときに使用できるこのキーワードには不利はありません

  • 私の最後のポイントは--IEEE754とは要するに? doubles)precision。これは、中間計算および拡張精度フォーマットの基準も定義します。


2

strictfpキーワードであり、クラスまたはメソッドの非アクセス修飾子として使用できます(ただし、変数は使用できません)。クラスにマークを付けるstrictfp内のメソッドコードが浮動小数点に関するIEEE 754標準規則に準拠することになります。

その修飾子がないと、メソッドで使用される浮動小数点はプラットフォームに依存した方法で動作する可能性があります。これにより、JVMが実行されている基盤となるプラットフォームに関係なく、浮動小数点の動作を予測できます。欠点は、基盤となるプラットフォームがより高い精度をサポートできる場合、strictfpメソッドはそれを利用できないことです。

クラスをとして宣言しない場合strictfpでもstrictfp、メソッドを次のように宣言することにより、メソッドごとに動作を取得できます。strictfp

〜Java™6のSCJPSun®認定プログラマー-Kathy Sierra&Bert Bates〜


0

以下の例は、これをより明確に理解するのに役立ちます。たとえば、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.

0

'strictfp'キーワードは、Javaでの浮動小数点計算(floatまたはdouble)の精度をIEEEの754標準に明示的に強制するために使用されます。strictfpキーワードを使用しない場合、浮動小数点の精度はターゲットプラットフォームのハードウェアに依存します。

インターフェイスまたはクラスがstrictfpで宣言されている場合、そのインターフェイスまたはクラス内のすべてのメソッドとネストされた型は、暗黙的にstrictfpです。

参照リンク

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.