Pourquoi Splint (le vérificateur de code C) donne-t-il une erreur lors de la comparaison d'un float à un int ?

StackOverflow https://stackoverflow.com/questions/38027

  •  09-06-2019
  •  | 
  •  

Question

Les deux sont des valeurs mathématiques, mais le flotteur a plus de précision.Est-ce la seule raison de l'erreur – la différence de précision ?Ou existe-t-il un autre problème potentiel (et plus grave) ?

Était-ce utile?

La solution

C'est parce que l'ensemble des valeurs entières n'est pas égal à l'ensemble des valeurs flottantes pour les types « int » et « float ».Par exemple, la valeur flottante 0,5 n'a pas d'égal dans l'ensemble d'entiers et la valeur entière 4519245367 peut ne pas exister dans l'ensemble de valeurs qu'un flottant peut stocker.Ainsi, le vérificateur signale cela comme un problème à vérifier par le programmeur.

Autres conseils

Parce que ce n'est probablement pas une très bonne idée.Tous les flottants ne peuvent pas être tronqués en entiers ;tous les entiers ne peuvent pas être convertis en flottants.

Lors de la comparaison, la valeur entière sera « promue » en valeur à virgule flottante.À ce stade, vous effectuez une comparaison d’égalité exacte entre deux nombres à virgule flottante, ce qui est presque toujours une mauvaise chose.

Vous devriez généralement avoir une sorte de "boule epsilon", ou une plage de valeurs acceptables, et vous effectuez la comparaison si les deux valeurs sont suffisamment proches l'une de l'autre pour être considérées comme égales.Vous avez besoin d'une fonction à peu près comme celle-ci :

int double_equals(double a, double b, double epsilon)
{
   return ( a > ( b - epsilon ) && a < ( b + epsilon ) );
}

Si votre application ne propose pas de choix évident d'epsilon, utilisez DBL_EPSILON.

Parce que les flotteurs ne peuvent pas stocker une valeur int exacte, donc si vous avez deux variables, int i et float f, même si vous attribuez "i = f;", la comparaison "if (i == f)" ne le sera probablement pas. renvoie vrai.

En supposant des entiers signés et un format à virgule flottante IEEE, les grandeurs d'entiers qui peuvent être représentées sont :

short  -> 15 bits
float  -> 23 bits
long   -> 31 bits
double -> 52 bits

Par conséquent un float peut représenter n'importe quel short et un double peut représenter n'importe quel long.

Si vous avez besoin de contourner ce problème (vous avez une raison légitime et êtes heureux qu'aucun des problèmes mentionnés dans les autres réponses ne vous pose problème), passez simplement d'un type à un autre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top