Exemple:
float timeRemaining = 0.58f;
Pourquoi le f
est-il obligatoire à la fin de ce numéro?
Exemple:
float timeRemaining = 0.58f;
Pourquoi le f
est-il obligatoire à la fin de ce numéro?
double & int
.
Réponses:
Votre déclaration de flotteur contient deux parties:
timeRemaining
est de type float
.0.58
à cette variable.Le problème se produit dans la partie 2.
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 undouble
.
Nous avons donc maintenant une double
valeur que nous voulons affecter à une variable de type float
. Pour ce faire, il doit y avoir une conversion implicite de double
enfloat
. Il n'y a pas de telle conversion, car vous pouvez (et dans ce cas faire) perdre des informations lors de la conversion.
La raison en 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,57999999999999978655962351581366 ... pour double
et exactement 0,579999946057796478271484375 pour float
.
À proprement parler, le f
n'est pas obligatoire. Vous pouvez éviter d'avoir à utiliser le f
suffixe en convertissant la valeur en a float
:
float timeRemaining = (float)0.58;
(float) 0.58
fonctionnera-t-il? Vous avez dit plus tôt qu'il n'y avait pas de conversion, car des informations pourraient être perdues, alors comment se fait-il que le casting fonctionne?
2.4
est interprétée comme un double partout ailleurs. 2. Les conversions de rétrécissement implicites (comme de double à float) ne sont pas autorisées. Si vous souhaitez faire une exception à ces règles, vous devez avoir une très bonne raison. Il est peu probable que l'enregistrement d'un coup de touche soit suffisant.
Parce qu'il ya plusieurs types numériques que le compilateur peut utiliser pour représenter la valeur 0.58
: float
, double
et decimal
. Sauf si vous êtes d'accord avec le compilateur qui en choisit un pour vous, vous devez lever l'ambiguïté.
La documentation pour double
indique que si vous ne spécifiez pas vous-même le type, le compilateur choisit toujours double
comme 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'opérateur d'affectation est traité comme double. Cependant, si vous voulez qu'un nombre entier soit traité comme double, utilisez le suffixe d ou D.
L'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, ce n'est toujours pas suffisant pour 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
vers le float
timeRemaining
perd potentiellement des informations, de sorte que le compilateur refuse de l'appliquer implicitement. Si vous ajoutez un cast explicite, la conversion est effectuée; si vous ajoutez le f
suffixe, aucune conversion ne sera nécessaire. Dans les deux cas, le code se compilerait alors.
int
et une pour double
.
double a = 0.69f;
?
float
en double
.
Le problème est que .NET, afin de permettre l'exécution de certains types d'opérations implicites impliquant float
et double
, devait soit spécifier explicitement ce qui devrait se passer dans tous les scénarios impliquant des opérandes mixtes, soit permettre des conversions implicites entre les types à effectuer dans un direction seulement; Microsoft a choisi de suivre l'exemple de Java en autorisant la direction qui favorise parfois la précision, mais sacrifie souvent l'exactitude et crée généralement des tracas.
Dans presque tous les cas, prendre la double
valeur la plus proche d'une quantité numérique particulière et l'assigner à a float
donnera la float
valeur la plus proche de cette même quantité. Il existe quelques cas de coin, tels que la valeur 9 007 199 791 611 905; la meilleure float
représentation serait 9 007 200 328 482 816 (ce qui est décalé de 536 870 911), mais la conversion de la meilleure double
représentation (c'est-à-dire 9 007 199 791 611 904) float
donne 9 007 199 254 740 992 (qui est décalé de 536 870 913). En général, cependant, convertir la meilleure double
représentation d'une certaine quantité en float
produira soit la meilleure float
représentation possible , soit l'une des deux représentations qui sont essentiellement également bonnes.
Notez que ce comportement souhaitable s'applique même aux extrêmes; par exemple, la meilleure float
représentation de la quantité 10 ^ 308 correspond à la float
représentation obtenue en convertissant la meilleure double
représentation de cette quantité. De même, la meilleure float
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 de conversion explicite sont rarement aussi précises. La conversion de la meilleure float
représentation d'une valeur en double
donnera rarement quelque chose de particulièrement proche de la meilleure double
représentation de cette valeur, et dans certains cas, le résultat peut être décalé de centaines d'ordres de grandeur (par exemple, la conversion de la meilleure float
représentation de 10 ^ 40 en double
produira une valeur qui compare supérieure à la meilleure double
représentation de 10 ^ 300.
Hélas, les règles de conversion sont ce qu'elles sont, donc il faut vivre avec l'utilisation de typecasts et de suffixes stupides lors de la conversion de valeurs dans le sens "sûr", et faire attention aux typecasts implicites dans la direction dangereuse qui donneront souvent des résultats faux.
double
.