Неточное сравнение переменных с плавающей запятой
Этот дефект возникает при использовании равенства (==) или неравенство (!=) операция с числами с плавающей запятой.
Polyspace ® не создает дефект для операции равенства или неравенства с числами с плавающей запятой, когда:
Сравнение выполняется между двумя плавающими константами.
float flt = 1.0;
if (flt == 1.1)Сравнение осуществляется между константой и переменной, которая может принимать конечное, достаточно малое число значений.
float x;
int rand = random();
switch(rand) {
case 1: x = 0.0; break;
case 2: x = 1.3; break;
case 3: x = 1.7; break;
case 4: x = 2.0; break;
default: x = 3.5; break; }
…
if (x==1.3) Сравнение выполняется между выражениями с плавающей запятой, содержащими только целочисленные значения.
float x = 0.0;
for (x=0.0;x!=100.0;x+=1.0) {
…
if (random) break;
}
if (3*x+4==2*x-1)
…
if (3*x+4 == 1.3)Один из операндов: 0.0, если вы не используете флаг опции -detect-bad-float-op-on-zero.
/* Defect detected when you use the option flag */ if (x==0.0f)
При выполнении анализа через интерфейс пользователя эту опцию можно ввести в поле Другое (Other) в узле Дополнительные настройки (Advanced Settings) на панели Конфигурация (Configuration). Посмотрите Other.
В командной строке добавьте флаг к команде анализа.
polyspace-bug-finder -sources filename ^ -checkers BAD_FLOAT_OP -detect-bad-float-op-on-zero
Проверка равенства или неравенства двух значений с плавающей запятой может привести к неожиданным результатам, поскольку представления с плавающей запятой неточны и содержат ошибки округления.
Вместо проверки равенства значений с плавающей запятой:
if (val1 == val2)
FLT_EPSILON определено в float.h):#include <float.h> if(fabs(val1-val2) < FLT_EPSILON)
См. примеры исправлений ниже.
Если вы не хотите устранять проблему, добавьте комментарии к результату или коду, чтобы избежать другой проверки. См. раздел Результаты анализа пространства адресов с помощью исправлений ошибок или обоснований.
| Группа: Программирование |
| Язык: C | C++ |
| По умолчанию: Откл. |
Синтаксис командной строки:
BAD_FLOAT_OP |
| Воздействие: среднее |
| ИДЕНТИФИКАТОР CWE : 873 |