Le "problème" que nous observons est en raison de la nature même de l'arithmétique à virgule flottante.
Dans la FP la précision dépend de l'échelle; autour de la valeur 1.0
la précision n'est pas suffisante pour être en mesure de différencier 1.0
et 1.0+min_representable
où min_representable
est la plus petite valeur supérieure à zéro (même si nous considérons seulement le plus petit numéro normalisé, std::numeric_limits<float>::min()
... le plus petit des nombres dénormalisés est un autre quelques ordres de grandeur plus faible).
Par exemple avec double précision 64 bits IEEE754 des nombres à virgule flottante, autour de l'échelle de l' x=10000000000000000
(10à 16), il est impossible de distinguer x
et x+1
.
Le fait que le changement de résolution à l'échelle est la raison pour laquelle le nom "virgule flottante", parce que le point décimal "flotte". Une représentation en virgule fixe à la place aura une résolution fixe (par exemple avec 16 chiffres binaires ci-dessous les unités que vous avez une précision de 1/65536 ~ 0.00001).
Par exemple, dans le IEEE754 32 bits à virgule flottante au format il y a un bit pour le signe, 8 bits pour l'exposant et le 31 bits pour la mantisse:
La plus petite valeur eps
tels que 1.0f + eps != 1.0f
est disponible en pré-défini, constante en FLT_EPSILON
ou std::numeric_limits<float>::epsilon
. Voir aussi la machine epsilon sur Wikipédia, qui explique comment epsilon se rapporte à des erreurs d'arrondi.
I. e. epsilon est la plus petite valeur qui fait ce que vous attendiez ici, de faire une différence lorsqu'il est ajouté à 1.0.
Le plus général version de ce (pour les autres nombres de 1.0) est appelée de 1 unité à la dernière place (de la mantisse). Voir Wikipedia ULP article.