nombre décimal et représentation exacte

En c ++, comment savoir quand un nombre décimal peut être exactement représenté à l’aide de la norme IEEE 754-1985. par exemple, 0.2 ne peut pas représenter exactement.

Y a-t-il une règle simple?

Un nombre peut être représenté exactement comme un float IEEE755 s’il peut être écrit sous la forme B × 2 n , où B est un entier (et B et n se situent dans une plage valide). En d’autres termes, il doit y avoir un entier n tel que si vous multipliez votre nombre par 2 n, vous obtenez un entier. Clairement, pour 1/5, il n’y en a pas.

Une autre façon de dire, c’est que votre nombre doit être la sum de deux puissances finies qui ne sont pas trop éloignées (la distance maximale entre les puissances est la précision de votre flotteur).

Une autre façon de le dire très vaguement est que “les nombres rationnels dont le dénominateur est une puissance de deux” sont représentables (bien qu’avec les contraintes de précision évidentes).

La précision du float, qui est la largeur de B , est de 24 bits pour un simple, de 53 bits pour un double et de 64 bits pour une double précision étendue.

Oui, il y a une règle simple. Si la partie décimale ne peut pas être représentée par un nombre n sur une puissance de 2, elle ne peut pas être représentée exactement. Elle se répète indéfiniment. Sinon, il sera exact tant que la représentation correspond au nombre de bits disponibles.

Ainsi, par exemple 0,75 fonctionne, car il est 3/4. Il n’y a aucun moyen de faire 0,2, parce que c’est 1/5 et il n’y a rien que vous puissiez ajuster à cela laisse au numérateur une puissance de 2.

La raison pour laquelle tant de nombres décimaux ne peuvent pas être représentés exactement est que les nombres décimaux ont une combinaison de 2 et 5 dans le dénominateur. Vous ne pouvez obtenir une représentation exacte que si vous pouvez simplifier la fraction pour supprimer tous les 5.

Pour donner un autre exemple, considérons 0.625. En fraction, il s’agit de 625/1000, mais cela simplifie jusqu’à 5/8. La forme simplifiée a une puissance de 2 en bas, elle sera donc exacte.

Un effet secondaire intéressant est que tous les nombres décimaux exactement représentables se terminent par un “5”. Si ce n’est pas le cas, vous pouvez dire très rapidement que cela ne peut pas être exact.

Y a-t-il une règle simple?

Empirique: convertir et reconvertir, et si vous obtenez le même nombre, il est exactement représentable.

Théorique: IEEE-754 utilise un bit de signe, M bits de mantisse et E bits d’exposants (M = 52, E = 11 pour les double 64 bits , M = 23, E = 8 pour les bits float sur 32 bits ), représentés par (+ / – 1) * (1 + (m / 2 ^ M)) * (2 ^ (e- (2 ^ (E-1) -1))), pour m = mantisse m-non signée, e = non signée E exposant à bits. Si votre numéro peut être représenté de cette façon, il est exactement représentable. (Il existe également des nombres sous-normaux pour des exposants encore plus petits qui entrent dans l’espace bits des nombres à virgule flottante)

La traduction anglaise de ce qui précède est que si votre nombre X peut être écrit soit 0, soit (+/- 1) * un entier impair non négatif m ‘fois une puissance de deux 2 ^ (e’), alors X pourrait être représentable ; pour être sûr que vous devez vérifier si m ‘et e’ entrent dans leurs espaces de bits respectifs:

m ‘= 2k + 1, k <2 ^ M

e ‘= une plage d’exposants dans laquelle je ne suis pas suffisamment confiant en mon algèbre pour être sûr d’avoir raison. N’importe où dans +/- 900 pour les nombres en double précision convient, mais si l’exposant est supérieur à 900, vous devez être prudent et regarder de plus près à la façon dont les bits sont réellement représentés.