web-dev-qa-db-fra.com

Quand devrais-je utiliser le mot clé "strictfp" en Java?

J'ai examiné ce que cela faisait, mais est-ce que quelqu'un a réellement un exemple de l'utilisation du mot clé strictfp en Java? Quelqu'un at-il réellement trouvé un usage pour cela?

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

236
GBa

Strictfp garantit que vous obtenez exactement les mêmes résultats de vos calculs en virgule flottante sur toutes les plateformes. Si vous n'utilisez pas strictfp, la mise en œuvre de la machine virtuelle Java est libre d'utiliser une précision supplémentaire, le cas échéant.

De la JLS :

Dans une expression FP-strict, tout les valeurs intermédiaires doivent être des éléments de la valeur float définie ou du double valeur définie, ce qui implique que les résultats de toutes les expressions FP-strict doit être ceux prédits par l'arithmétique IEEE 754 sur des opérandes représentés par un simple et double formats. Dans un expression qui n'est pas FP-stricte, certaines la marge de manœuvre est accordée pour un mise en œuvre pour utiliser un .__ étendu. gamme d'exposants pour représenter résultats intermédiaires; l'effet net, en gros, est-ce un le calcul peut produire "la réponse correcte " dans les situations où exclusive utilisation du jeu de valeurs float ou du double valeur définie peut entraîner un débordement ou débordement.

En d'autres termes, il s'agit de s'assurer que Write-Once-Run-Anywhere signifie réellement Write-Once-Get-Egalement-De-Mauvais-Résultats-Partout.

Avec strictfp, vos résultats sont portables, sans lesquels ils sont plus susceptibles d'être exacts.

252
Dan Dyer

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

Si on lit entre les lignes, il en découle que si vous ne spécifiez pas strictfp, le compilateur JVM et JIT disposent d’une licence pour calculer vos calculs à virgule flottante comme ils le souhaitent. Dans l'intérêt de la rapidité, ils vont très probablement déléguer le calcul à votre processeur. Avec strictfp on, les calculs doivent être conformes aux normes arithmétiques IEEE 754, ce qui, dans la pratique, signifie probablement que la JVM effectuera les calculs.

Alors, pourquoi voudriez-vous utiliser strictfp? Je peux voir un scénario dans une application distribuée (ou jeu multijoueur) où tous les calculs en 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.

60
MattK

Tout a commencé par une histoire, 

Lors du développement de Java par James Gosling, Herbert et le reste de son équipe. Ils avaient en tête cette chose folle appeléeindépendant de la plate-forme. Ils voulaient améliorer Oak (Java) tellement mieux qu'il fonctionnerait exactement de la même manière sur toutes les machines ayant un jeu d'instructions différent, même sous un système d'exploitation différent. Mais il y avait un problème avec les nombres décimaux, également appelés virgule flottante et double dans les langages de programmation. Certaines machines ont été construites en visant l'efficacité, alors que les autres reposaient en précision. Ainsi, les machines les plus récentes (plus précises) avaient une taille en virgule flottante de 80 bits tandis que les machines précédentes (plus efficaces/plus rapides) avaient des doublons de 64 bits. Mais, cela était contre l’idée de base de construire un langage indépendant de la plateforme. En outre, cela pourrait entraîner une perte de précision/de données lorsqu'un code est créé sur une machine (taille double de 64 bits) et exécuté sur un autre type de machine (taille double de 80 bits).

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

21
AbhimanyuAryan

Voici plusieurs références:

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

    En gros, il s’agit essentiellement de savoir si les résultats des expressions à virgule flottante dans votre code sont 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érentes sur plusieurs plates-formes, utilisez strictfp.

  • strictfp - Glossaire Java

    Le matériel en virgule flottante calcule avec plus de précision et avec une plage de valeurs supérieure à celle requise par la spécification Java. Il serait déroutant que certaines plates-formes donnent plus de précision que d'autres. Lorsque vous utilisez le modificateur strictfp sur une méthode ou une classe, le compilateur génère un code conforme à la spécification Java pour des résultats identiques sur toutes les plateformes. Sans strictfp, c’est un peu laxiste, mais pas assez laxiste pour utiliser les bits de garde du Pentium pour donner une précision de 80 bits.

  • Et enfin, la spécification du langage Java, §15.4 Expressions FP-strict

    Dans une expression FP-strict, toutes les valeurs intermédiaires doivent être des éléments du jeu de valeurs float ou du jeu de valeurs doubles, ce qui implique que les résultats de toutes les expressions FP-strict doivent être ceux prédits par l'arithmétique IEEE 754 sur des opérandes représentés en utilisant des formats simples et doubles. . Dans une expression qui n'est pas FP-strict, une marge de manœuvre est accordée à une implémentation qui utilise une plage d'exposants étendue pour représenter les résultats intermédiaires; L'effet net, en gros, est qu'un calcul peut produire "la réponse correcte" dans des situations où l'utilisation exclusive des ensembles de valeurs float ou doubles peut entraîner un dépassement ou un dépassement.

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

21
Michael Myers

Comme indiqué dans les autres réponses, 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 celle de la spécification IEEE. La situation se complique lorsque le JIT optimise un calcul particulier; l'ordre dans lequel les instructions peuvent être différentes à chaque fois, ce qui donne des arrondis légèrement différents.

Les frais généraux supportés par strictfp risquent d’être très dépendants du processeur et de JIT . Cet article de Wikipédia sur SSE2 semble avoir une idée du problème . Donc si le JIT peut générer des instructions SSE pour effectuer un calcul, il semble que strictfp n’aura aucun surcoût. 

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

12
Sean McCauliff
  • strictfp est un modificateur qui limite les calculs en virgule flottante selon IEEE 754.

  • Ceci peut être utilisé sur toute la classe comme "public strictfp class StrictFpModifierExample {}" ou sur la méthode "public strictfp void example ()". S'il est utilisé sur une classe, toutes les méthodes suivront IEEE 754 et si elles sont utilisées sur une méthode, une méthode particulière suivez IEEE 754. 

  • Pourquoi est-il utilisé ?? ::: Comme différentes plates-formes ont un matériel différent en virgule flottante, qui calcule avec plus de précision et une plage de valeurs supérieure à celle spécifiée par la spécification Java, ce qui peut produire un résultat différent sur différentes plateformes.Il confirme le même résultat indépendamment des différentes plateformes

  • strictfp veille également à tirer parti de la rapidité et de la précision des opérations en virgule flottante de précision étendue.

  • Ce mot clé ne présente aucun inconvénient que nous pouvons utiliser lorsque nous effectuons des calculs en virgule flottante.

  • Mon dernier point est --What est IEEE754 en brefEEEE 754 définit une méthode standard pour les calculs en virgule flottante et le stockage des valeurs en virgule flottante au format simple (32 bits, utilisé dans Java float) ou double (64 bits, utilisé dans Java double) precision.Il définit également des normes pour les calculs intermédiaires et pour les formats de précision étendus.

8
Rahul Saxena

strictfp est un mot clé et peut être utilisé comme modificateur non-accès pour les classes ou les méthodes (mais jamais pour les variables). Le fait de marquer une classe comme étant strictfp signifie que tout code de méthode de la classe sera conforme aux règles standard IEEE 754 relatives aux points flottants. 

Sans ce modificateur, les points flottants utilisés dans les méthodes pourraient se comporter de manière dépendante de la plate-forme. Vous pouvez ainsi prédire le comportement de vos points flottants 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 méthode strictfp ne pourra pas en tirer parti.

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

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

2
Shanaka Jayalath

Les exemples ci-dessous peuvent aider à mieux comprendre ceci: si on fait 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.
0
Neeraj