Question

Dans mon cours, on me dit:

  

valeurs continues sont représentées approximativement dans la mémoire, et donc le calcul de flotteurs implique des erreurs d'arrondi. Ce sont des écarts minuscules dans les modèles de bits; ainsi le e==f test est dangereux si e et f sont flotteurs.

En référence à Java.

Est-ce vrai? Je l'ai utilisé des déclarations de comparaison avec doubles et floats et n'ont jamais eu des problèmes d'arrondi. Je n'ai jamais lu dans un manuel quelque chose de similaire. Certes, les comptes machine virtuelle pour cela?

Était-ce utile?

La solution

Il est vrai.

Il est une limitation inhérente de la façon dont les valeurs en virgule flottante sont représentés dans la mémoire en un nombre fini de bits.

Ce programme, par exemple, affiche "false":

public class Main {
  public static void main(String[] args) {
    double a = 0.7;
    double b = 0.9;
    double x = a + 0.1;
    double y = b - 0.1;
    System.out.println(x == y);
  }
}

Au lieu de comparaison exacte avec « == » vous décidez habituellement sur un certain niveau de précision et de demander si les chiffres sont « assez proches »:

System.out.println(Math.abs(x - y) < 0.0001);

Autres conseils

Cela vaut pour Java tout autant que pour toute autre langue à l'aide à virgule flottante. Il est inhérent à la conception de la représentation des valeurs à virgule flottante dans le matériel.

Plus d'infos sur les valeurs à virgule flottante:

Ce que tout informaticien doit savoir sur-Arithmétique virgule flottante

Oui, ce qui représente 0,1 exactement en base 2 est le même que d'essayer de représenter exactement un tiers dans la base 10.

Ceci est toujours vrai. Il y a quelques chiffres qui ne peuvent pas être représentés avec précision en utilisant la représentation du point de flotteur. Considérons, par exemple, pi. Comment voulez-vous représenter un nombre qui a des chiffres infinis, dans un stockage fini? Par conséquent, lorsque l'on compare les numéros que vous devriez vérifier si la différence entre les deux est plus petite que certains epsilon. En outre, il existe plusieurs classes qui existent qui peuvent vous aider à atteindre une plus grande précision tels que BigDecimal et BigInteger.

Il est juste. Notez que Java n'a rien à voir avec elle, le problème est inhérent à flottant mathématiques points dans ANY langue.

Vous pouvez souvent obtenir avec elle des problèmes au niveau de la classe, mais il ne va pas travailler dans le monde réel. Parfois, il ne fonctionnera pas dans la salle de classe.

Un incident d'il y a longtemps de retour à l'école. L'enseignant d'une classe d'introduction attribué un problème d'examen final qui se révèle un véritable doozy pour bon nombre des meilleurs étudiants - il ne fonctionnait pas et ils ne savaient pas pourquoi. (J'ai vu cela comme un assistant de laboratoire, je ne suis pas dans la classe.) Enfin, certains ont commencé à me demander de l'aide et certains palpage a révélé le problème. Ils avaient jamais appris à propos de l'inexactitude inhérente flottante mathématiques points

Maintenant, il y avait deux approches de base à ce problème, une force brute un (qui par hasard a travaillé dans ce cas, comme il a fait les mêmes erreurs à chaque fois) et un plus élégant (ce qui rendrait différentes erreurs et ne pas travailler. ) toute personne qui a essayé l'approche élégante frapperait un mur de briques sans avoir aucune idée pourquoi. J'ai aidé un groupe d'entre eux et coincé dans un commentaire expliquant pourquoi et à me contacter s'il avait des questions.

Bien sûr prochain semestre, j'entendre parler de lui à ce sujet et je parqueté essentiellement l'ensemble du département avec un petit programme simple:

10 X = 3000000
20 X = X + 1
30 If X < X + 1 goto 20
40 Print "X = X + 1"

En dépit de ce que chaque enseignant dans le département pensé, ce fin. Les 3 millions de graines est tout simplement de faire terminer plus rapidement. (Si vous ne savez pas de base: Il n'y a pas de gimmicks ici, juste épuiser la précision des nombres à virgule flottante.)

Oui, comme d'autres réponses ont dit. Je veux ajouter que je vous recommande cet article sur la précision en virgule flottante: flotteurs Visualizing

La plupart des CPU (et langages informatiques) utilisent IEEE 754 arithmétique en virgule flottante. En utilisant cette notation, il y a des nombres décimaux qui ont pas de représentation exacte dans cette notation, par exemple 0.1. Donc, si vous divisez 1 par 10 vous n'obtiendrez un résultat exact. Lorsque vous effectuez plusieurs calculs dans une rangée, les erreurs résument. Essayez l'exemple suivant en python:

>>> 0.1
0.10000000000000001
>>> 0.1 / 7 * 10 * 7 == 1
False

Ce n'est pas vraiment ce que vous attendez mathématiquement.

Par ailleurs: Un malentendu commun concernant les nombres à virgule flottante est que les résultats ne sont pas précis et ne peuvent pas être comapared en toute sécurité. Ceci est vrai que si vous utilisez vraiment des fractions de nombres. Si tous vos calculs est dans le domaine entier, double et flotteurs font exactement la même chose que ints et peuvent également être comparés en toute sécurité. Ils peuvent être utilisés en toute sécurité comme les compteurs de boucle, par exemple.

Bien sûr, il est vrai. Pensez-y. Un nombre quelconque doit être représenté en binaire.

Image: "1000" comme 0.5or 1/2, soit 2 ** -1. Ensuite, « 0100 » est de 0,25 ou 1/4. Vous pouvez voir où je vais.

Combien de numéros pouvez vous représenter de cette manière? 2 ** 4. Ajout de plus de bits doublons l'espace disponible, mais il est jamais infini. 1/3 ou 1/10, pour la matière 1 / n, un nombre non multiple de 2 ne peut pas être réellement représentée.

1/3 pourrait être "0101" (0,3125) ou "0110" (0,375). De toute valeur si vous multipliez par 3, ne sera pas 1. Bien sûr, vous pouvez ajouter des règles spéciales. Dites-vous « lorsque vous ajoutez 3 fois « 0101 », font 1 » ... cette approche ne fonctionnera pas à long terme. Vous pouvez prendre un peu, mais alors comment environ 1/6 fois 2?

Il est pas un problème de représentation binaire, une représentation finie a des numéros que vous ne pouvez pas représenter, ils sont infinies, après tout.

scroll top