Je lisais un article de Microsoft concernant l'élargissement des conversions et l'option Strict On lorsque je suis arrivé à la partie
Les conversions suivantes peuvent perdre en précision:
- Entier à célibataire
- Long à simple ou double
- Décimal en simple ou double
Cependant, ces conversions ne perdent ni informations ni ampleur.
.. mais selon un autre article concernant les types de données ,
Le type entier peut stocker de -2.147.483.648 à 2.147.483.647 et
Un type unique peut stocker à partir de
- 1,401298E-45 à 3,4028235E + 38 pour les nombres positifs,
- et -3,4028235E + 38 à - 1,401298E-45 pour les nombres négatifs
.. donc Single peut stocker beaucoup plus de nombres que Integer. Je ne pouvais pas comprendre dans quelle situation une telle conversion d'Integer en Single peut perdre en précision. Quelqu'un pourrait-il expliquer, s'il vous plaît?
la source
Integer
s (99,2%) ne peuvent pas être représentés commeSingle
, donc "quand" est "à peu près toujours".Single
ne peut représenter que 4 278 178 909 nombres différents. UneSingle
valeur représente un nombre si et seulement si l'exposant stocké n'est pas 255, ce qui signifie qu'il y a 255 * 2 ^ 24Single
s qui représentent des nombres. Parmi ceux-ci, deux d'entre eux représentent le même nombre (à savoir zéro), et les autres représentent tous des nombres différents.[-16777216,16777216]
(2 ^ 24 = la largeur de la signification) peuvent être représentés exactement. Les plus grands nombres sont arrondis au multiple le plus proche de 2, 4, 8, ... selon leur taille.Single
a deux façons de stocker zéro.Single
Peut donc en fait représenter moins de nombres distincts queInteger
.Les types à virgule flottante (tels que simple et double) sont représentés en mémoire par un signe, une mantisse et un exposant. Considérez-le comme une notation scientifique:
Ils - comme vous pouvez vous y attendre - utilisent la base 2. Il existe d'autres ajustements qui permettent de représenter l'infini et NaN, et l'exposant est décalé (y reviendra), et un raccourci pour la mantisse (y reviendra aussi) . Recherchez la norme IEEE 754 qui couvre sa représentation et ses opérations pour plus de détails.
Pour nos besoins, nous pouvons l'imaginer comme un nombre binaire "mantisse" et un "exposant" qui vous indique où placer le séparateur décimal.
Dans le cas de Single, nous avons 1 bit pour le signe he, 8 pour l'exposant et 23 pour la mantisse.
Maintenant, le fait est que nous allons stocker la mantisse du chiffre le plus significatif. N'oubliez pas que tous les zéros à gauche ne sont pas pertinents. Et étant donné que nous travaillons en binaire, nous savons que le chiffre le plus significatif est un 1 ※. Eh bien, puisque nous le savons, nous n'avons pas à le stocker. Grâce à ce raccourci, la plage effective de la mantisse est de 24 bits.
※: À moins que le nombre que nous stockons soit nul. Pour cela, nous aurons tous les bits mis à zéro. Cependant, si nous essayons d'interpréter cela sous la description que j'ai donnée, vous auriez un 2 ^ 24 (le 1 implicite) multiplié par 1 (2 à la puissance de l'exposant 0). Donc, pour y remédier, l'exposant zéro est une valeur spéciale. Il existe également des valeurs spéciales pour stocker l'infini et NaN dans l'exposant.
Selon le décalage de l'exposant - en plus d'éviter les valeurs spéciales - son décalage permet de placer le point décimal avant le début de la mantisse ou après sa fin, sans avoir besoin d'avoir un signe pour l'exposant.
Cela signifie que pour les grands nombres, le type à virgule flottante placera le point décimal au-delà de la fin de la mantisse.
N'oubliez pas que la mantisse est un nombre de 24 bits. Il ne représentera jamais un nombre de 25 bits ... il n'a pas ce bit supplémentaire. Ainsi, le single ne peut pas distinguer entre 2 ^ 24 et 2 ^ 24 + 1 (ce sont les premiers nombres de 25 bits, et ils diffèrent sur le dernier bit, qui n'est pas représenté dans le single).
Ainsi, pour les entiers, la plage du simple est de -2 ^ 24 à 2 ^ 24. Et essayer d'ajouter 1 à 2 ^ 24 donnera 2 ^ 24 (car en ce qui concerne le type, 2 ^ 24 et 2 ^ 24 + 1 ont la même valeur). Essayez-le en ligne . C'est pourquoi il y a une perte d'informations lors de la conversion d'un entier en un seul. Et c'est aussi pourquoi une boucle qui utilise un simple ou un double pourrait en fait être une boucle infinie sans que vous vous en rendiez compte.
la source
1
bit de tête implicite dans la signification. Elle est impliquée par le fait que le champ d'exposant biaisé est différent de zéro . Les subnormales (alias dénormales) ont notamment+-0.0
un0
bit de tête de leur signification. Je suppose que vous pourriez simplifier pour ne considérer0.0
qu'un cas totalement spécial, mais0.0
suit en fait les mêmes règles de codage que les autres sous-normales.Voici un exemple réel de la perte de précision lors de la conversion de
Integer
enSingle
:Le
Single
type peut stocker tous les entiers de -16777216 à 16777216 (inclus), mais il ne peut pas stocker tous les entiers en dehors de cette plage. Par exemple, il ne peut pas stocker le numéro 16777217. En outre, il ne peut pas stocker de nombre impair supérieur à 16777216.Nous pouvons utiliser Windows PowerShell pour voir ce qui se passe si nous convertissons un
Integer
en unSingle
et inversement:Notez que 16777217 a été arrondi à 16777216 et 16777219 a été arrondi à 16777220.
la source
float
s représentables les plus proches continue de croître en tant que puissances de. en.wikipedia.org/wiki/…Les types à virgule flottante sont similaires à la "notation scientifique" en physique. Le nombre est divisé en un bit de signe, un exposant (multiplicateur) et une mantisse (chiffres significatifs). Ainsi, lorsque l'amplitude de la valeur augmente, la taille du pas augmente également.
La virgule flottante simple précision a 23 bits de mantisse, mais il y a un "implicite 1", donc la mantisse est effectivement de 24 bits. Par conséquent, tous les entiers d'une magnitude allant jusqu'à 2 24 peuvent être représentés exactement en virgule flottante simple précision.
Au-dessus, on peut représenter successivement moins de nombres.
Ainsi, sur les 2 32 valeurs d'entier signées 32 bits possibles, seuls 2 * (2 24 + 7 * 2 23 ) = 9 * 2 24 peuvent être représentés en virgule flottante simple précision. Cela représente 3,515625% du total.
la source
Les flotteurs simple précision ont 24 bits de précision. Tout ce qui dépasse est arrondi au nombre de 24 bits le plus proche. Il pourrait être plus facile à comprendre en notation scientifique décimale, mais gardez à l'esprit que les flottants réels utilisent le binaire.
Supposons que vous disposez de 5 chiffres décimaux de mémoire. Vous pouvez choisir d'utiliser ceux comme un entier non signé régulier, vous permettant d'avoir n'importe quel nombre entre 0 et 99999. Si vous voulez pouvoir représenter des nombres plus grands, vous pouvez utiliser la notation scientifique et allouer simplement deux chiffres pour être l'exposant, donc vous pouvez désormais représenter n'importe quoi entre 0 et 9,99 x 10 99 .
Cependant, le plus grand nombre que vous pouvez représenter exactement n'est plus que 999. Si vous avez essayé de représenter 12345, vous pouvez obtenir 1,23 x 10 4 ou 1,24 x 10 4 , mais vous ne pouvez représenter aucun des nombres entre les deux, car vous n'ont pas assez de chiffres disponibles.
la source