Данное диагностическое правило основано на руководстве AUTOSAR (AUTomotive Open System ARchitecture) по разработке программного обеспечения.
При сравнении на равенство или неравенство значений вещественных типов в зависимости от используемого процессора и настроек компилятора часто можно получить неожиданный результат.
Пример кода, на который анализатор выдаст предупреждение:
const double PI_div_2 = 1.0;
const double sinValue = sin(M_PI / 2.0);
if (sinValue == PI_div_2) { .... }
Чтобы сравнение значений вещественных типов не содержало ошибок, нужно либо использовать встроенные константы 'std::numeric_limits<float>::epsilon()' или 'std::numeric_limits<double>::epsilon()', либо создать собственную константу 'Epsilon' с заданной точностью.
Исправленный пример кода:
const double PI_div_2 = 1.0;
const double sinValue = sin(M_PI / 2.0);
// equality
if (fabs(a - b) <= std::numeric_limits<double>::epsilon()) { .... };
// inequality
if (fabs(a - b) > std::numeric_limits<double>::epsilon()) { .... };
В некоторых случаях сравнение двух вещественных чисел через оператор '==' или '!=' допустимо. Например, когда переменная сравнивается с заведомо известным значением:
bool foo();
double bar();
double val = foo() ? bar() : 0.0;
if (val == 0.0) { .... }
Анализатор не выдает предупреждений, если сравнивается одно и то же значение с самим собой. Такое сравнение позволяет определить, хранится ли в переменной NaN:
bool isnan(double value) { return value != value; }
Впрочем, более хорошим стилем будет использовать для этой проверки функцию 'std::isnan'.
Данная диагностика классифицируется как:
|