int float conversion produit un avertissement?
C'est surprenant pour moi de voir que, même lorsque la valeur peut être convertie, int float conversion toujours donner un avertissement. Pourquoi est-ce?
int i = 0;
float f = 0; //warning here
//I thought this was an implicit conversion,
//meaning it is convertible with no warnings.
f = i; //another warning here
L'avertissement est:
warning C4244: '=' : conversion from 'int' to 'float', possible loss of data
Attribuer MAX INT valeur de type float et voir le résultat.
float f = 0.0 f; // 0 est un entier.
Elle donne le même message d'avertissement avec les deux
Je comprends que
float f = 0.0 f; // 0 est un entier.
Elle donne le même message d'avertissement avec les deux
f = MAXINT;
et f = INT_MAX;
Je comprends que
some_float = MAX_INT;
ou some_float = some_int
doit donner un avertissement. Cependant, pourquoi serait-il nécessaire pour 0
?float f = 0;
est ok. Puisque c'est une valeur constante qui peut être représenté exactement, il ne devrait pas être un avertissement pour l'implicite int-à-flotteur de conversion. Mais, personnellement, je ferais float f = 0.0;
, juste pour être plus explicite. (Et je serais probablement utiliser double
moins qu'il y a une bonne raison pour utiliser float
.)
OriginalL'auteur user103214 | 2011-10-15
Vous devez vous connecter pour publier un commentaire.
Cela dépend du nombre de bits que vous avez dans votre
int
type. Un flotteur qui est IEEE754 simple précision est d'une valeur de 32 bits, mais certains de ces bits sont affectés à l'exposant, les sens ne sont pas toutes disponibles pour la précision.Si votre
int
type a plus de précision que votrefloat
, alors vous pourriez souffrir d'une perte de précision dans le haut de gamme.En d'autres termes, il peut ne pas être en mesure de distinguer entre
INT_MAX
etINT_MAX - 1
.Solution dans ce cas est d'utiliser un plus grand type à virgule flottante (
double
) bien que, techniquement, vous trouverez peut-être une mise en œuvre qui a une 256 bitsint
type dans ce cas, vous devrez trouver un autre moyen 🙂Cette réponse a un bref aperçu de la façon dont le floating point format de travail, y compris le fait que seulement 23 des 32 bits sont disponibles pour la précision de la mantisse.
OriginalL'auteur paxdiablo
J'ai répondu à une question similaire ici:
Pourquoi ne GCC en garde contre cette conversion implicite?
La raison en est qu'une
int
doit être arrondi lorsqu'il est intégré dans unfloat
parce quefloat
ne peut pas contenir toute la précision d'unint
dans ce cas.Dans votre cas, une
float
ne dispose que d'environ 24 bits de précision. Alors qu'unint
a 32 bits de précision, par conséquent, un certain degré de précision est la perte par cette distribution, d'où l'avertissement.float
peut contenir toutes les valeurs de typeint
sans perte d'information-par exemple, siint
etfloat
de 16 et 32 bits ou 32 et 64 bits. Mais les compilateurs sont bien sûr libres d'utiliser les informations au sujet de la mise en oeuvre particulière au moment de décider d'émettre un avertissement.Je me rends compte que, par conséquent j'ai inséré "dans ce cas" dans ma réponse, car il n'est pas défini pour être universellement vrai.
OriginalL'auteur Mysticial
Juste pour le plaisir, essayer cela et voir ce que la sortie est (un indice, vous vous attendriez à ce que les chiffres sont toutes les mêmes, n'est-ce pas?):
Bien, les réponses que je reçois sont:
De sorte que le compilateur est tout à fait raison de signaler que quelque chose pourrait aller mal avec le cast, mais il n'est pas assez intelligent pour le savoir avec certitude, car il va seulement ont tendance à se produire à l'extrémité de la gamme numérique. Il est toujours préférable de static_cast<> de mon point de vue, pour plus de clarté au moins, et de montrer au compilateur que c'était ce que vous aviez l'intention.
Par la façon dont je ne suis pas entièrement sûr de savoir pourquoi le résultat ci-dessus se produit. Peut-être quelqu'un d'autre ne peut expliquer!
Ce n'était pas clair à partir de votre question initiale. J'ai mis à jour afin de tenir compte de cette information (même si je suis un peu surpris il a averti au sujet de
float f = 0;
). Veuillez passer en revue mes modifications.OriginalL'auteur Robinson
Non, ce n'est pas ce qu'il signifie. Il signifie simplement que vous pouvez affecter une valeur d'un type d'un objet d'un autre type, sans une conversion explicite (c'est à dire, un cast), et la valeur sera convertie implicitement.
Et dans ce cas, un avertissement peut être approprié. Si
int
etfloat
sont à la fois 32 bits (ce qui est typique, mais pas universel), puis toutes les valeurs de typeint
sont à l'intérieur de la gamme defloat
, mais il y a beaucoup de valeurs de typeint
qui ne peut être représenté exactement dans le typefloat
.La langue standard requiert au moins un message de diagnostic pour toutes les unités de traduction (fichier source) qui viole une règle de syntaxe ou de contrainte. Mais les compilateurs sont libres d'émettre des supplémentaires de diagnostic qu'ils aiment.
Qui s'applique également à tout ce que le compilateur ne, pas juste des diagnostics. Ce que vous décrivez est juste un bug du compilateur; normalement, l'émission de trente-six gazillion mises en garde de ne pas provoquer un plantage du compilateur. Et la norme permet de compilateurs à l'échec en raison des limites de capacité; il exige seulement de traduire et d'exécuter un programme qui atteint toutes les limites spécifiées (C99 5.2.4.1).
OriginalL'auteur Keith Thompson