93 votes

Pourquoi le "f" est-il nécessaire pour déclarer des flottants ?

Exemple :

float timeRemaining = 0.58f;

Pourquoi le f est nécessaire à la fin de ce numéro ?

102voto

Jeffrey Sax Points 6512

Votre déclaration d'un flottant contient deux parties :

  1. Elle déclare que la variable timeRemaining est de type float .
  2. Il attribue la valeur 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;

38voto

Jon Points 194296

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é.

3voto

supercat Points 25534

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.com

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.

Powered by:

X