Supposons que x
est la décimale exacte.
nearest_float(x)
est la conversion en virgule flottante.
Il arrondit à la valeur du point flottant représentable le plus proche, égal à pair.
ulp(nearest_float(x))
est l'unité de moindre précision de la valeur en virgule flottante (c'est-à-dire la valeur du plus petit bit de significande).
x + y
indique l'opération arithmétique exacte, même chose pour - * /.
nearest_float(x)+nearest_float(y)
est la somme exacte des approximations flottantes.
nearest_float(nearest_float(x)+nearest_float(y))
est l'opération en virgule flottante.
Opération nearest_float(x)+nearest_float(x)
est strictement équivalent à nearest_float(x)*2
, et l'opération nearest_float(x)*2
est exacte, sauf les rares cas de flotter trop-plein de points: il est juste un changement de l'exposant, nearest_float(2*nearest_float(x))=2*nearest_float(x)
..
Nous avons cette propriété: abs(nearest_float(x)-x) <= ulp(nearest_float(x))/2
.
Nous pouvons multiplier les deux côtés de l'inégalité par 2: abs(2*nearest_float(x)-2*x) <= ulp(2*nearest_float(x))/2
. Le plus souvent, il y a une seule valeur dans cet intervalle, exceptionnellement deux valeurs en cas d'égalité exacte, mais l'égalité exacte sera résolue comme dans le cas de x (seul l'exposant a changé, pas le significand). Près des limites de binade, il peut y avoir deux flotteurs dans l'intervalle ci-dessus aussi, mais la résolution sera aussi au même significand.
Ainsi cela signifie que 2*nearest_float(x)
est le bon candidat pour nearest_float(2*x)
Ainsi, dans une langue basée sur IEEE 754 à virgule flottante, avec arrondi au plus proche, cravate au même mode d'arrondi (le mode par défaut), et correctement arrondies valeurs littérales (ce qui signifie que 0,1 retournera effectivement le flottant le plus proche à 1/10) vous aurez la propriété 0.3 + 0.3 == 0.6, 0.07 + 0.07 == 0.14, 3.14 + 3.14 == 6.28, x + x == 2 * x la valeur de x.
Plus surprisignly, vous avez encore plus drôles propriétés comme celui-ci Is 3*x+x always exact?
Ce n'est pas vraiment un double - l'op semble déjà savoir que tous les nombres décimaux peuvent être représentés exactement par un double ... – assylias
closest_float (x) + nearest_float (x) = nearest_float (2 * x) est toujours vrai dans IEEE 754 quelle que soit la langue. Nous ne pouvons pas expliquer pourquoi dans un commentaire ... Peut-être que la question a été fermée prématurément. –
@ aka.nice rouvert si vous voulez ajouter une réponse. – assylias