9
votes

Comparer le flotteur et les doubles primitives en Java

Je suis tombé sur un coin étrange de Java. (Cela me semble étrange) xxx

o / p: true xxx

O / P: FALSE

J'ai observé que si nous comparons deux valeurs (un flotteur et un double comme je l'ai mentionné dans l'exemple) avec < code> .5 ou .0 comme 3.5, 234.5, 645.0 Ensuite, la sortie est true i.e. Deux valeurs sont égales sinon la sortie est false bien qu'ils soient égaux.

J'ai essayé de faire la méthode strictfp mais pas de chance. Suis-je rater quelque chose.


7 commentaires

... Aaannd ici nous allons à nouveau.


@Kerrek: Pourriez-vous s'il vous plaît me prendre avec vous?


@Ajinka: une question sur les types de points flottants avec la même confusion sur la représentation précise des valeurs apparaît sur la fois tous les trois jours. :-)


Dupliqué possible de est-il en sécurité quand comparez-le / double directement dans Java?


@Kerrek: Ohh désolé pour ça. Maintenant pas d'inquiétude pour les deux prochains jours :)


@Ajinkya: en effet - comme utiliser des statistiques à votre avantage en voyageant avec une bombe :-)


@JB: Merci pour le lien que cela a aidé.


5 Réponses :


20
votes

Jetez un coup d'œil à ce que chaque scientifique doit savoir sur les numéros de points flottants .

pressant infiniment de nombreux nombres réels dans un nombre fini de bits nécessite une représentation approximative .... p> blockQuote> blockquote>

--- Modifier pour montrer ce que signifie la citation ci-dessus --- p>

Vous ne devez jamais comparer des flotteurs ou des doubles pour l'égalité; Parce que, vous ne pouvez pas vraiment garantir que le nombre que vous attribuez au flotteur ou au double est exact. p>

SO P>

float error = 0.000001 * second;
if ((first >= second - error) || (first <= second + error)) {
   // close enough that we'll consider the two equal
   ...
}


6 commentaires

:Merci pour le lien. Pourriez-vous s'il vous plaît dites-moi ce que je manque en bref?


@Ajinkya, explication fournie. Bonne chance pour votre projet.


Voici un article très intéressant sur Comparaison de flotteur - En général, en utilisant l'epsilon du flotteur avec la vérification des erreurs relatives, c'est bien, mais l'exploitation de la nature du format IEEE754 est encore meilleure :-)


@Kerrek: Merci pour le lien donnera un essai :)


Le dernier bloc de code ne fonctionne pas pour les valeurs négatives. Enveloppez l'erreur dans un math.abs () pour obtenir ce travail.


Pour considérer les deux chiffres égaux, vous devez utiliser et opérateur (&&) dans la déclaration IF.



3
votes

La mise en œuvre commune des nombres de points flottants, IEEEE754, permet la représentation précise de ces nombres qui ont une expansion binaire courte et finie , c'est-à-dire une somme de plusieurs puissances (à proximité) de deux. Tous les autres numéros ne peuvent pas être représentés avec précision.

Etant donné que float et double ont des tailles différentes, la représentation dans les deux types pour une valeur non représentable est différente, et donc ils comparent comme inégal.

(la la longueur de la chaîne binaire est la taille de la mantissie, de sorte que 24 pour float , 53 pour double et 64 pour Le flotteur de précision prolongé de 80 bits (pas en Java). L'échelle est déterminée par l'exposant.)


2 commentaires

Merci de m'avoir emmené :)


Aucun problème - c'est une sorte de copie / pâte mentale, donc aucun mal fait :-) Découvrez cet article de comparaison de flotteur si vous envisagez de comparer des flotteurs. C'est vraiment assez illuminant.



10
votes

La différence est que 3.5 peut être représenté exactement dans les deux float et double - tandis que 3.2 ne peut pas être représenté exactement dans l'un ou l'autre type ... et les deux approximations les plus proches sont différentes.

Imagine que nous avions deux types de décimale de précision fixe , dont l'un a enregistré 4 chiffres significatifs et dont l'un a enregistré 8 chiffres significatifs, et nous avons demandé à chacun d'entre eux de stocker le numéro le plus proche de "A troisième "(Cependant, nous pourrions le faire). Ensuite, on aurait la valeur 0.3333 et une valeur de 0,33333333.

une comparaison d'égalité entre float et double convertit d'abord le float à un double puis compare les deux - ce qui équivaut à convertir 0,3333 dans notre type "petit décimal" à 0,33330000. Il comparerait ensuite 0,33330000 et 0.33333333 pour l'égalité et donnerait un résultat de faux.


2 commentaires

Merci beaucoup pour répondre à ma question redondante. Aussi merci de la rendre assez simple :)


Merci pour cette explication simple



3
votes

Point flottant est un format binaire et peut représenter des nombres comme une somme de pouvoirs de 2. E. G. 3.5 est 2 + 1 + 1/2.

float 3.2f comme une approximation de 3.2 est p> xxx pré>

si double 3.2d comme une approximation de 3.2 est p> xxx pré> Lorsque vous utilisez un point flottant, vous devez utiliser l'arrondi approprié. Si vous utilisez BigDecimal à la place (et beaucoup de gens font), il a arrondi intégré. P> xxx pré>


BTW Le code que j'ai utilisé pour imprimer les fractions de double. P >

double f = 3.2d;
double f2 = f - 3;
System.out.print("2+ 1");
for (long i = 2; i < 1L << 54; i <<= 1) {
  f2 *= 2;
  if (f2 >= 1) {
    System.out.print("+ 1/" + i);
    f2 -= 1;
  }
}
System.out.println();


1 commentaires

Bien que votre réponse soit complexe, mais c'est vraiment utile de comprendre les choses sous couverture.



0
votes

Cela devrait fonctionner: xxx

fonctionne toujours avec BigDecimal lorsque vous souhaitez comparer des flotteurs ou des doubles et utilisez toujours le constructeur bigdecimal avec le paramètre string !


0 commentaires