Por que o Splint (o verificador de código C) apresenta um erro ao comparar um float com um int?
Pergunta
Ambos são valores matemáticos, porém o float tem mais precisão.Essa é a única razão do erro – a diferença na precisão?Ou existe outro problema potencial (e mais sério)?
Solução
Isso ocorre porque o conjunto de valores inteiros não é igual ao conjunto de valores flutuantes para os tipos 'int' e 'float'.Por exemplo, o valor flutuante 0,5 não tem igual no conjunto de números inteiros e o valor inteiro 4519245367 pode não existir no conjunto de valores que um número flutuante pode armazenar.Portanto, o verificador sinaliza isso como um problema a ser verificado pelo programador.
Outras dicas
Porque provavelmente não é uma ideia muito boa.Nem todos os floats podem ser truncados para ints;nem todos os ints podem ser convertidos em floats.
Ao fazer a comparação, o valor inteiro será "promovido" para um valor de ponto flutuante.Nesse ponto você está fazendo uma comparação exata de igualdade entre dois números de ponto flutuante, o que quase sempre é uma coisa ruim.
Geralmente, você deve ter algum tipo de "bola épsilon", ou intervalo de valores aceitáveis, e fazer a comparação se os dois valores estiverem próximos o suficiente um do outro para serem considerados iguais.Você precisa de uma função mais ou menos assim:
int double_equals(double a, double b, double epsilon)
{
return ( a > ( b - epsilon ) && a < ( b + epsilon ) );
}
Se o seu aplicativo não tiver uma escolha óbvia de épsilon, use DBL_EPSILON.
Como os floats não podem armazenar um valor int exato, então se você tiver duas variáveis, int i e float f, mesmo se você atribuir "i = f;", a comparação "if (i == f)" provavelmente não funcionará retorne verdadeiro.
Assumindo inteiros assinados e formato de ponto flutuante IEEE, as magnitudes dos inteiros que podem ser representados são:
short -> 15 bits
float -> 23 bits
long -> 31 bits
double -> 52 bits
Portanto um float
pode representar qualquer short
e um double
pode representar qualquer long
.
Se você precisar contornar isso (você tem um motivo legítimo e está feliz por nenhum dos problemas mencionados nas outras respostas ser um problema para você), basta converter de um tipo para outro.