Exemple:
float timeRemaining = 0.58f;
Pourquoi le f
est-il obligatoire à la fin de ce numéro?
c#
floating-point
Thomas
la source
la source
double
.double & int
.Réponses:
Votre déclaration de flotteur contient deux parties:
timeRemaining
est de typefloat
.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 un
double
.Nous avons donc maintenant une
double
valeur que nous voulons affecter à une variable de typefloat
. Pour ce faire, il doit y avoir une conversion implicite dedouble
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 pourfloat
.À proprement parler, le
f
n'est pas obligatoire. Vous pouvez éviter d'avoir à utiliser lef
suffixe en convertissant la valeur en afloat
:float timeRemaining = (float)0.58;
la source
(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
etdecimal
. 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 toujoursdouble
comme type de tout littéral numérique réel:L'ajout du suffixe
f
crée unfloat
; le suffixed
crée undouble
; le suffixem
crée undecimal
. 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 lefloat
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 lef
suffixe, aucune conversion ne sera nécessaire. Dans les deux cas, le code se compilerait alors.la source
int
et une pourdouble
.double a = 0.69f;
?float
endouble
.Le problème est que .NET, afin de permettre l'exécution de certains types d'opérations implicites impliquant
float
etdouble
, 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 à afloat
donnera lafloat
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 meilleurefloat
représentation serait 9 007 200 328 482 816 (ce qui est décalé de 536 870 911), mais la conversion de la meilleuredouble
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 meilleuredouble
représentation d'une certaine quantité enfloat
produira soit la meilleurefloat
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 à lafloat
représentation obtenue en convertissant la meilleuredouble
représentation de cette quantité. De même, la meilleurefloat
représentation de 10 ^ 309 correspond à lafloat
représentation obtenue en convertissant la meilleuredouble
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 endouble
donnera rarement quelque chose de particulièrement proche de la meilleuredouble
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 meilleurefloat
représentation de 10 ^ 40 endouble
produira une valeur qui compare supérieure à la meilleuredouble
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.
la source