Почему Splint (программа проверки кода C) выдает ошибку при сравнении числа с плавающей точкой и типа int? - PullRequest
3 голосов
/ 01 сентября 2008

Оба являются математическими значениями, однако у float больше точности. Это единственная причина ошибки - разница в точности? Или есть другая потенциальная (и более серьезная) проблема?

Ответы [ 6 ]

8 голосов
/ 01 сентября 2008

Это потому, что набор целочисленных значений не равен набору значений с плавающей точкой для типов 'int' и 'float'. Например, значение с плавающей запятой 0,5 не имеет равных в наборе целых чисел, а целочисленное значение 4519245367 может не существовать в наборе значений, которые может хранить число с плавающей запятой. Таким образом, средство проверки помечает это как проблему, которую должен проверить программист.

3 голосов
/ 01 сентября 2008

Потому что это, вероятно, не очень хорошая идея. Не все поплавки могут быть усечены до целых; не все целые могут быть преобразованы в числа с плавающей точкой.

2 голосов
/ 08 октября 2008

При выполнении сравнения целочисленное значение будет «повышено» до значения с плавающей запятой. В этот момент вы делаете точное сравнение равенства между двумя числами с плавающей запятой, что почти всегда плохо.

Как правило, у вас должен быть какой-то "эпсилон-шар" или диапазон допустимых значений, и вы проводите сравнение, если два значения достаточно близки друг к другу, чтобы считаться равными. Вам нужна функция примерно так:

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

Если ваше приложение не имеет очевидного выбора epsilon, используйте DBL_EPSILON.

1 голос
/ 04 сентября 2008

Предполагая целые числа со знаком и формат IEEE с плавающей запятой, можно представить величины целых чисел:

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

Следовательно, float может представлять любой short, а double может представлять любой long.

1 голос
/ 01 сентября 2008

Поскольку float не может хранить точное значение типа int, поэтому, если у вас есть две переменные, int i и float f, даже если вы присваиваете "i = f;", сравнение "if (i == f)" вероятно не вернет истину.

0 голосов
/ 01 сентября 2008

Если вам нужно обойти это (у вас есть законная причина и вы довольны, что ни одна из проблем, упомянутых в других ответах, не является проблемой для вас), просто приведите один тип к другому.

...