Por que o Splint (o verificador de código C) apresenta um erro ao comparar um float com um int?

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

  •  09-06-2019
  •  | 
  •  

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)?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top