9
votes

L'opérateur '==' de Java sur des doubles

Cette méthode renvoie "vrai". Pourquoi? XXX


7 commentaires

parce que val contient la même valeur que Enregistrer ?


Ceci est simplement "Comment fonctionne le travail arithmétique de points flottants?" reformulé une fois de plus.


comment venir ? VAL et SAVE ont eu la même valeur, puis la validation de la boucle 'for' a changé la valeur de VAL pendant que la valeur de sauvegarde était maintenue de la même manière.


C'est là que tu as tort. val ne change pas. Lisez n'importe quel livre ou article en ligne sur l'arithmétique de point flottant.


Étant donné que les chiffres soustraits de VAL sont des ordres de grandeur inférieur à VAL et n'auront pas d'impact sur sa valeur. @ US2012 est bien sûr correct.


Il est facile de dire "lisez-y", mais si vous ne savez pas ce que vous recherchez (c'est-à-dire pourquoi cela se produit) Il est difficile de trouver les propriétés qui causent le problème.


docs.oracle.com/cd/e19957-01/806- 3568 / ncg_goldberg.html une lecture incontournable


8 Réponses :


25
votes

Vous soustrayez une petite valeur (moins de 1000) de la valeur énorme . La petite valeur est tellement plus petite que la valeur importante que la valeur représentative la plus proche du résultat théorique reste la valeur d'origine.

Fondamentalement, c'est le résultat de la façon dont les numéros de points flottants fonctionnent.

Imagine que nous avions un type de point flottant décimal (juste pour la simplicité) qui ne stocke que 5 chiffres significatifs dans la mantissa et un exposant compris entre 0 et 1000.

Votre exemple est comme écrire 10 999 - 1000 ... Pensez à ce que le résultat de ce serait, lorsqu'il est arrondi à 5 chiffres significatifs. Oui, le résultat exact est 99999 ..... 9000 (avec 999 chiffres), mais si vous ne pouvez représenter que des valeurs avec 5 chiffres significatifs, le résultat le plus proche est de 10 999 encore.


0 commentaires

1
votes

Un double n'a pas assez de précision pour effectuer le calcul que vous tentez. Donc, le résultat est identique à la valeur initiale.

Ce n'est rien à voir avec le == Opérateur.


0 commentaires

2
votes

Lorsque vous définissez val sur double.max_value / 10, il est défini sur une valeur approximativement égale à 1.7976931348623158 * 10 ^ 307 . Les valeurs de soustraction tels que 1000 de ce qui permettraient une précision sur la double représentation qui n'est pas possible, donc il laisse fondamentalement val inchangé.

Selon vos besoins, vous pouvez utiliser bigdecimal au lieu de double .


0 commentaires

1
votes

val est un grand nombre et lors de la soustraction 1 (ou même 1000 ) à partir de celui-ci, le résultat ne peut pas être exprimé correctement comme un < Code> double valeur. La représentation de ce nombre x et x-1 est la même, car double n'a qu'un nombre limité de bits pour représenter un nombre illimité de chiffres.


0 commentaires

1
votes

double.max_value est un nombre énorme que 1 ou 1000. double.max_value-1 est généralement égal à double.MAx_Value . Donc, votre code ne fait pas grossièrement rien lors de la soustraction de 1 ou de 1000 sur double.max_value / 10 . Rappelez-vous toujours que:

  1. double s ou float S ne sont que des approximations de nombres réels, elles ne sont que des rationnelles non aussi réparties entre les réels
  2. Vous devez utiliser des opérateurs très soigneusement arithmétiques entre double s ou float S qui ne sont pas proches (il y a beaucoup d'autres règles telles que celles-ci ...)
  3. En général, n'utilisez jamais double s ou float si vous avez besoin de précision arbitraire

0 commentaires

2
votes

double.max_value est si gros que le JVM ne dit pas la différence entre celui-ci et double.max_value-1000

Si vous soustrayez un nombre inférieur à " 1.9958403095347198E292 "à partir de double.mav_value Le résultat est toujours double.max_value . xxx

outuptup:

true

FALSE


0 commentaires

0
votes

parce que double est un point flottant Type numérique, qui est un moyen de approximation des valeurs numériques . Les représentations de points flottants codent des nombres afin que nous puissions stocker des nombres beaucoup plus grands ou plus petits que nous le pouvions normalement. Cependant, tous les chiffres ne peuvent pas être représentés dans l'espace donné, de sorte que plusieurs numéros sont arrondis sur la même valeur de point flottante.

comme exemple simplifié, nous voudrions peut-être pouvoir stocker des valeurs allant de -1000 à 1000 dans une petite quantité d'espace où nous ne pourrions normalement stocker qu'à -10 à 10. Nous pourrions donc arrondir toutes les valeurs à Les mille les plus proches et les stocker dans le petit espace: -1000 sont codés comme -10 , -900 sont codés comme -9 , 1000 sont codés comme 10 < / code>. Mais que si nous voulons stocker -999? La valeur la plus proche que nous puissions codée est -1000, nous devons donc encoder -999 comme la même valeur que -1000: -10 . .

En réalité, les régimes de points flottants sont beaucoup plus compliqués que l'exemple ci-dessus, mais le concept est similaire. Les représentations de points flottants des nombres ne peuvent représenter que certains de tous les numéros possibles, donc lorsque nous avons un numéro qui ne peut pas être représenté dans le cadre du régime, nous devons l'arrondir à la valeur de la plus proche représenble .

dans votre code, toutes les valeurs dans les 1000 double.max_value / 10 sont automatiquement arrondies sur double.max_value / 10 , c'est pourquoi l'ordinateur pense (Double.max_value / 10) - 1000 == double.max_value / 10 .


0 commentaires

0
votes

Le résultat d'un calcul de point flottant est la valeur représentative la plus proche de la réponse exacte. Ce programme: xxx

impressions: xxx

Le premier de ces numéros est votre Val d'origine. La seconde est le plus grand double qui est inférieur à celui-ci.

Lorsque vous soustrayez 1000 du 1.7976931348623158E307, la réponse exacte est entre ces deux nombres, mais très plus près de 1,7976931348623158E307 de 1,7976931348623155E307, Donc, le résultat sera arrondi au 1.7976931348623155E307, laissant Val inchangé.


0 commentaires