web-dev-qa-db-fra.com

Quel est le premier entier qu'un flotteur IEEE 754 est incapable de représenter exactement?

Pour plus de clarté, si j'utilise un langage qui implémente les flottants IEE 754 et que je déclare:

float f0 = 0.f;
float f1 = 1.f;

... puis imprimez-les à nouveau, j'obtiendrai 0,0000 et 1,0000 exactement.

Mais IEEE 754 n'est pas capable de représenter tous les nombres le long de la ligne réelle. Près de zéro, les "écarts" sont faibles; à mesure que vous vous éloignez, les écarts s'élargissent.

Donc, ma question est: pour un flottant IEEE 754, qui est le premier entier (le plus proche de zéro) qui ne peut pas être représenté exactement? Je ne m'intéresse vraiment qu'aux flottants 32 bits pour l'instant, bien que Je serai intéressé d'entendre la réponse pour 64 bits si quelqu'un la donne!

Je pensais que ce serait aussi simple que de calculer 2bits_of_mantissa et en ajoutant 1, où bits_of_mantissa est le nombre de bits que la norme expose. Je l'ai fait pour les flotteurs 32 bits sur ma machine (MSVC++, Win64), et cela semblait bien, cependant.

146
Floomi

2bits de mantisse + 1 + 1

Le +1 dans l'exposant (bits de mantisse + 1) est dû au fait que, si la mantisse contient abcdef... le nombre qu'il représente est en fait 1.abcdef... × 2^e, fournissant un peu de précision implicite supplémentaire.

Pour float, il s'agit de 16 777 217 (224 + 1).
Pour double, il s'agit de 9 007 199 254 740 993 (253 + 1).

>>> 9007199254740993.0
9007199254740992
180
kennytm

La plus grande valeur représentable par un n l'entier est 2n-1. Comme indiqué ci-dessus, un float a 24 bits de précision dans la signification, ce qui semble impliquer que 224 ne cadrerait pas.

Cependant.

Les puissances de 2 dans la plage de l'exposant sont exactement représentables à 1,0 × 2n, donc 224 can fit et par conséquent le premier entier non représentable pour float est 224+1. Comme indiqué ci-dessus. Encore.

35
thus spake a.k.