Quand dois-je utiliser le mot clé "strictfp" en java?

258

J'ai recherché ce que cela fait, mais est-ce que quelqu'un a un exemple de quand vous utiliseriez le strictfp mot clé en Java? Quelqu'un at-il réellement trouvé une utilisation pour cela?

Y aurait-il des effets secondaires à simplement le mettre sur toutes mes opérations en virgule flottante?

GBa
la source
1
Toujours, sauf si vous avez réellement besoin de plus de performances que de reproductibilité.
Antimony
1
@Antimony - ou la précision / exactitude. x86 / x64, par exemple, utilisent des registres à virgule flottante 80 bits en interne, de sorte que le résultat sera plus précis pour un calcul long sans strictfp.
Robert Fraser
1
@Robert En fait, la spécification garantit une précision limitée de la mantisse. La seule différence est qu'il peut utiliser une précision d'exposant plus grande que la normale, ce qui présente des différences dans de rares cas en raison du double arrondi.
Antimony
Je pense qu'en plus de l'option de saupoudrer ce modificateur utile tout autour du joint, de nouveaux types de données stfloat et sdouble primitive strictfp pourraient être une bonne idée.
theRiley

Réponses:

274

Strictfp garantit que vous obtenez exactement les mêmes résultats de vos calculs en virgule flottante sur chaque plate-forme. Si vous n'utilisez pas strictfp, l'implémentation JVM est libre d'utiliser une précision supplémentaire lorsqu'elle est disponible.

Du JLS :

Dans une expression FP-stricte, toutes les valeurs intermédiaires doivent être des éléments de l'ensemble de valeurs flottantes ou de l'ensemble de valeurs double, ce qui implique que les résultats de toutes les expressions FP-strictes doivent être ceux prédits par l'arithmétique IEEE 754 sur des opérandes représentés à l'aide de formats simples et doubles . Dans une expression qui n'est pas stricte en FP, une certaine latitude est accordée à une implémentation pour utiliser une plage d'exposants étendue pour représenter des résultats intermédiaires; L'effet net, en gros, est qu'un calcul pourrait produire "la bonne réponse" dans des situations où l'utilisation exclusive de l'ensemble de valeurs flottantes ou de l'ensemble de valeurs doubles pourrait entraîner un débordement ou un dépassement de capacité.

En d'autres termes, il s'agit de s'assurer que Write-Once-Run-Anywhere signifie réellement Write-Once-Get-Equally-Wrong-Results-Everywhere .

Avec strictfp, vos résultats sont portables, sans eux, ils sont plus susceptibles d'être précis.

Dan Dyer
la source
28
Utilisez-le pour des résultats scientifiques reproductibles et des tests unitaires très précis.
Aleksandr Dubinsky
1
"Si vous n'utilisez pas strictfp, l'implémentation de la JVM est libre d'utiliser une précision supplémentaire là où elle est disponible" - vous faites ce bruit comme une mauvaise chose: P
AMDG
@LinkTheProgrammer, cela peut certainement être une mauvaise chose
Tim
@TimCastelijns Je suppose que Happy Wheels est votre référence? Les rediffusions enregistrent les frappes; en raison de la diversité de précision de l'implémentation FP-math, les relectures ne sont précises que sur du matériel similaire. Pouvez-vous nommer un problème plus réaliste causé par la variabilité mathématique en virgule flottante? Je peux imaginer peut-être un simulateur de particules, mais quoi d'autre?
AMDG
Cela signifie donc que nous devrions toujours utiliser strictfp dans la production où plusieurs plates-formes sont impliquées?
beatrice
65

Wikipedia a en fait un bon article sur ce sujet ici , avec un lien vers la spécification Java.

En lisant entre les lignes, l'implication est que si vous ne spécifiez pas strictfp, le compilateur JVM et JIT ont la licence pour calculer vos calculs à virgule flottante comme ils le souhaitent. Dans un souci de rapidité, ils délègueront très probablement le calcul à votre processeur. Avecstrictfp on, les calculs doivent être conformes aux normes arithmétiques IEEE 754, ce qui, en pratique, signifie probablement que la JVM fera le calcul.

Alors pourquoi voudriez-vous utiliser strictfp ? Je peux voir un scénario dans une application distribuée (ou un jeu multijoueur) où tous les calculs à virgule flottante doivent être déterministes, quel que soit le matériel ou le processeur sous-jacent. Quel est le compromis? Temps d'exécution le plus probable.

MattK
la source
5
«Une plage d'exposants étendue pour représenter des résultats intermédiaires» n'est pas «une licence pour calculer vos calculs à virgule flottante comme ils le souhaitent», et dans la pratique, même les strictfpcalculs utilisent même un FPU 8087 inutile. Ce n'est que le cas qu'un peu de soin est alors nécessaire. Voir stackoverflow.com/questions/18496560/…
Pascal Cuoq
Je suis d'accord avec @PascalCuoq re: "licence pour calculer vos calculs à virgule flottante comme ils le souhaitent" . Si quoi que ce soit, l'inverse semble être vrai dans ce cas, car il strictfpgarantit la conformité à la norme IEEE 754 (afin que vous obteniez le même résultat sur toutes les plates-formes). Le seul inconvénient que je peux voir est que vous pourriez perdre les avantages d'avoir un très bon FPU disponible dans votre matériel natif.
typeracer
25

Tout a commencé par une histoire,

Lorsque java était développé par James Gosling, Herbert et le reste de son équipe. Ils avaient en tête cette chose folle appelée l' indépendance de la plateforme . Ils voulaient faire du chêne (Java)tellement mieux qu'il fonctionnerait exactement de la même manière sur n'importe quelle machine ayant un jeu d'instructions différent, même sous différents systèmes d'exploitation. Mais, il y avait un problème avec les nombres à virgule décimale également appelés virgule flottante et double dans les langages de programmation. Certaines machines ont été conçues pour cibler l'efficacité tandis que les autres visaient la précision. Ainsi, les machines les plus récentes (plus précises) avaient une taille à virgule flottante de 80 bits tandis que les anciennes machines (plus efficaces / plus rapides) avaient des doubles 64 bits. Mais, cela était contraire à l'idée centrale de construire un langage indépendant de la plate-forme. En outre, cela peut entraîner une perte de précision / données lorsqu'un code est construit sur une machine (ayant un double de 64 bits) et exécuté sur un autre type de machine (ayant un double de 80 bits).

L'up-sizing peut être toléré mais pas le down-sizing. Ils sont donc tombés sur un concept de strictfp, c'est-à-dire de virgule flottante stricte . Si vous utilisez ce mot-clé avec une classe / fonction, sa virgule flottante et ses doubles ont une taille cohérente sur n'importe quelle machine. soit 32/64 bits respectivement.

AbhimanyuAryan
la source
8
strictfp a été introduit dans Java 1.2. C'était bien plus tard que lorsque le chêne a été conçu.
Thorbjørn Ravn Andersen
"nombres à virgule décimale également appelés virgule flottante" - Decimal signifie base 10, et n'a rien à voir avec les représentations à virgule flottante.
aioobe
21

Voici plusieurs références:

  • Utilisation de strictfp (JDC Tech Tip)
  • jGuru: À quoi sert le modificateur strictfp? Quand envisagerais-je de l'utiliser?

    Fondamentalement, tout se résume à savoir si vous vous souciez ou non que les résultats des expressions à virgule flottante dans votre code soient rapides ou prévisibles. Par exemple, si vous avez besoin des réponses fournies par votre code qui utilisent des valeurs à virgule flottante pour être cohérent sur plusieurs plates-formes, utilisez-les strictfp.

  • strictfp - Glossaire Java

    Le matériel à virgule flottante calcule avec plus de précision et avec une plage de valeurs supérieure à celle requise par la spécification Java. Ce serait déroutant si certaines plateformes donnaient plus de précision que d'autres. Lorsque vous utilisez le strictfpmodificateur sur une méthode ou une classe, le compilateur génère du code qui respecte strictement la spécification Java pour des résultats identiques sur toutes les plates-formes. Sans strictfp, il est légèrement laxiste, mais pas assez laxiste pour utiliser les bits de garde du Pentium pour donner 80 bits de précision.

  • Et enfin la spécification réelle du langage Java, §15.4 Expressions strictes FP :

    Dans une expression FP-stricte, toutes les valeurs intermédiaires doivent être des éléments de l'ensemble de valeurs flottantes ou de l'ensemble de valeurs double, ce qui implique que les résultats de toutes les expressions FP-strictes doivent être ceux prédits par l'arithmétique IEEE 754 sur des opérandes représentés à l'aide de formats simples et doubles . Dans une expression qui n'est pas stricte en FP, une certaine latitude est accordée à une implémentation pour utiliser une plage d'exposants étendue pour représenter des résultats intermédiaires; L'effet net, en gros, est qu'un calcul pourrait produire "la bonne réponse" dans des situations où l'utilisation exclusive de l'ensemble de valeurs flottantes ou de l'ensemble de valeurs doubles pourrait entraîner un débordement ou un dépassement de capacité.

Je ne l'ai jamais personnellement utilisé, cependant.

Michael Myers
la source
12

Comme les autres réponses l'ont mentionné, les résultats intermédiaires en virgule flottante sont conformes à la spécification IEEE. En particulier, les processeurs x86 peuvent stocker des résultats intermédiaires avec une précision différente de la spécification IEEE. La situation se complique lorsque le JIT optimise un calcul particulier; l'ordre des instructions peut être différent à chaque fois, ce qui entraîne des arrondis légèrement différents.

Les frais généraux encourus par strictfp sont susceptibles d'être très dépendants du processeur et du JIT. Cet article de wikipedia sur SSE2 semble avoir un aperçu du problème. Donc, si le JIT peut générer des instructions SSE pour effectuer un calcul, il semble que strictfp n'ait pas de surcharge.

Dans mon projet actuel, il y a quelques endroits où j'utilise strictfp. Il y a un point où les rayons cosmiques potentiels doivent être supprimés des valeurs des pixels. Si certains chercheurs extérieurs ont la même valeur en pixels et le même rayon cosmique devant eux, ils devraient obtenir la même valeur résultante que notre logiciel.

Sean McCauliff
la source
8
  • strictfp est un modificateur qui restreint les calculs en virgule flottante selon IEEE 754.

  • Cela peut être utilisé sur toute la classe comme "public strictfp class StrictFpModifierExample {}" ou sur la méthode "public strictfp void example ()". suivez IEEE 754.

  • Pourquoi il est utilisé ?? ::: Étant donné que différentes plates-formes ont un matériel à virgule flottante différent qui calcule avec plus de précision et une plus grande plage de valeurs que la spécification Java ne l'exige, ce qui peut produire une sortie différente sur différentes plates-formes, il confirme donc la même sortie indépendamment de la différence. plates-formes

  • strictfp garantit également de profiter de la vitesse et de la précision des opérations en virgule flottante à précision étendue.

  • Il n'y a aucun inconvénient avec ce mot-clé que nous pouvons utiliser lorsque nous faisons des calculs en virgule flottante

  • Mon dernier point est --Qu'est-ce que IEEE754 en bref IEEE 754 définit une méthode standard pour les calculs en virgule flottante et le stockage des valeurs en virgule flottante en simple (32 bits, utilisé dans les flottants Java) ou double (64 bits, utilisé en Java double) précision.Il définit également des normes pour les calculs intermédiaires et pour les formats de précision étendue.

Rahul Saxena
la source
2

strictfpest un mot-clé et peut être utilisé comme modificateur sans accès pour les classes ou les méthodes (mais jamais les variables). Le marquage d'une classe strictfpsignifie que tout code de méthode de la classe sera conforme aux règles standard IEEE 754 pour les virgules flottantes.

Sans ce modificateur, les virgules flottantes utilisées dans les méthodes peuvent se comporter de manière dépendante de la plateforme. Avec lui, vous pouvez prédire comment vos virgules flottantes se comporteront quelle que soit la plate-forme sous-jacente sur laquelle la JVM s'exécute. L'inconvénient est que si la plate-forme sous-jacente est capable de prendre en charge une plus grande précision, une strictfpméthode ne pourra pas en tirer parti.

Si vous ne déclarez pas une classe en tant que strictfp, vous pouvez toujours obtenir un strictfpcomportement méthode par méthode, en déclarant une méthode en tant que strictfp.

~ Programmeur certifié SCJP Sun® pour Java ™ 6 - Kathy Sierra et Bert Bates ~

Shanaka Jayalath
la source
0

L'exemple ci-dessous peut aider à comprendre cela plus clairement: En java chaque fois que nous utilisons la recherche d'informations précises pour toute opération, par exemple si nous faisons double num1 = 10e + 102; double num2 = 8e + 10; résultat = 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.
Neeraj
la source
0

Le mot clé 'strictfp' est utilisé pour forcer explicitement la précision des calculs en virgule flottante (float ou double) en Java conforme à la norme 754 de l'IEEE. Si vous n'utilisez pas de mot clé strictfp, la précision en virgule flottante dépend du matériel de la plate-forme cible.

Si une interface ou une classe est déclarée avec strictfp, toutes les méthodes et tous les types imbriqués de cette interface ou classe sont implicitement strictfp.

Lien de référence

Hari Krishna
la source