Le problème est que certains chiffres, nous pouvons facilement écrire en décimal n'ont pas une représentation exacte dans le format à virgule flottante particulier mis en œuvre par le matériel actuel. Une manière informelle d'indiquer ceci est que tous les entiers le font, mais pas toutes les fractions, parce que nous stockons normalement la fraction avec un exposant 2**e
. Donc, vous avez 3 choix:
Arrondir de manière appropriée. Le résultat non arrondi est toujours vraiment très proche, donc un résultat arrondi est invariablement "parfait". C'est ce que fait Javascript et beaucoup de gens ne réalisent même pas que JS fait tout en virgule flottante.
Utilisez l'arithmétique à virgule fixe. Ruby rend vraiment cela vraiment facile. C'est l'un des seuls langages qui passent de Fixnum à Class Bignum au fur et à mesure que les nombres grossissent.
Utilisez une classe qui est conçu pour résoudre ce problème, comme BigDecimal
Pour regarder le problème plus en détail, nous pouvons essayer de représenter votre « 7.3 » en binaire. La partie 7 est facile, 111, mais comment faisons-nous .3? 111.1 est 7.5, trop grand, 111.01 est 7.25, se rapprochant.Il s'avère que 111.010011 est le "prochain plus petit nombre le plus proche", 7.296875, et quand nous essayons de remplir le .003125 manquant finalement nous découvrons qu'il est juste 111.010011001100110011 ... pour toujours, non représentable dans notre encodage choisi dans une chaîne de bits finie .
Droite. Ceci est vrai indépendamment de la langue - Java, Ruby, C# tous "souffrent" de cela. C'est dû au choix de la logique binaire et à notre façon de représenter les nombres à virgule flottante. – duffymo