Exemple :
float timeRemaining = 0.58f;
Pourquoi le f
est nécessaire à la fin de ce numéro ?
Exemple :
float timeRemaining = 0.58f;
Pourquoi le f
est nécessaire à la fin de ce numéro ?
Votre déclaration d'un flottant contient deux parties :
timeRemaining
est de type float
.0.58
à cette variable.Le problème se pose dans la deuxième partie.
Le côté droit est évalué seul. Selon la spécification C#, un nombre contenant un point décimal qui n'a pas de suffixe est interprété comme une valeur double
.
Nous avons donc maintenant un double
que nous voulons affecter à une variable de type float
. Pour ce faire, il doit y avoir une conversion implicite de double
a float
. Une telle conversion n'existe pas, car vous risquez (et dans ce cas, vous perdez) des informations lors de la conversion.
La raison est que la valeur utilisée par le compilateur n'est pas vraiment 0,58, mais la valeur en virgule flottante la plus proche de 0,58, qui est 0,579999999999978655962351581366... pour double
et exactement 0,579999946057796478271484375 pour float
.
À proprement parler, le f
n'est pas nécessaire. Vous pouvez éviter d'utiliser l'option f
en transformant la valeur en un float
:
float timeRemaining = (float)0.58;
Parce qu'il existe plusieurs types numériques que le compilateur peut utiliser pour représenter la valeur 0.58
: float
, double
y decimal
. À moins que vous ne soyez d'accord pour que le compilateur en choisisse un pour vous, vous devez désambiguïser.
La documentation pour double
stipule que si vous ne spécifiez pas le type vous-même, le compilateur prend toujours double
comme le type de tout littéral numérique réel :
Par défaut, un littéral numérique réel sur le côté droit de l'affectation est traité comme un double. Toutefois, si vous souhaitez qu'un nombre entier soit traité comme un double, utilisez le suffixe d ou D.
Ajout du suffixe f
crée un float
; le suffixe d
crée un double
; le suffixe m
crée un decimal
. Tous ces éléments fonctionnent également en majuscules.
Cependant, cela ne suffit toujours pas à expliquer pourquoi cela ne compile pas :
float timeRemaining = 0.58;
La moitié manquante de la réponse est que la conversion du double
0.58
au float
timeRemaining
perd potentiellement des informations, le compilateur refuse donc de l'appliquer implicitement. Si vous ajoutez un cast explicite, la conversion est effectuée ; si vous ajoutez la balise f
alors aucune conversion ne sera nécessaire. Dans les deux cas, le code sera alors compilé.
Le problème est que .NET, afin de permettre l'exécution de certains types d'opérations implicites impliquant float
y double
Microsoft a choisi de suivre l'exemple de Java en autorisant la direction qui favorise parfois la précision, mais sacrifie fréquemment la correction et crée généralement des problèmes.
Dans presque tous les cas, prendre le double
qui se rapproche le plus d'une quantité numérique particulière et l'attribue à une float
donnera le float
la valeur qui est la plus proche de cette même quantité. Il y a quelques cas particuliers, comme la valeur 9 007 199 791 611 905 ; la meilleure valeur est celle qui est la plus proche de cette quantité. float
serait 9,007,200,328,482,816 (soit une erreur de 536,870,911), mais le fait de couler le meilleur double
représentation (soit 9 007 199 791 611 904) à float
donne 9 007 199 254 740 992 (avec une erreur de 536 870 913). En général, cependant, la conversion de la meilleure double
représentation d'une certaine quantité à float
donnera soit le meilleur résultat possible float
ou l'une des deux représentations qui sont essentiellement de qualité égale.
Notez que ce comportement souhaitable s'applique même aux extrêmes ; par exemple, la meilleure float
pour la quantité 10^308 correspond à la représentation float
représentation obtenue en convertissant la meilleure double
représentation de cette quantité. De même, la meilleure float
La représentation de 10^309 correspond à la float
représentation obtenue en convertissant la meilleure double
représentation de cette quantité.
Malheureusement, les conversions dans la direction qui ne nécessite pas une distribution explicite sont rarement aussi précises. La conversion de la meilleure float
représentation d'une valeur à double
donnera rarement quelque chose de particulièrement proche du meilleur. double
de cette valeur, et dans certains cas, le résultat peut être faussé par des centaines d'ordres de grandeur (par exemple, en convertissant la meilleure représentation de l float
représentation de 10^40 à double
donnera une valeur qui se compare plus grande que la meilleure double
représentation de 10^300.
Hélas, les règles de conversion sont ce qu'elles sont, et il faut donc s'accommoder de l'utilisation de types et de suffixes stupides lors de la conversion de valeurs dans le sens "sûr", et faire attention aux types implicites dans le sens dangereux qui donneront souvent des résultats erronés.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.