CERT C: правило FLP37-C

Не используйте объектные представления, чтобы сравнить значения с плавающей точкой

Описание

Управляйте определением

Не используйте объектные представления, чтобы сравнить значения с плавающей точкой. [1]

Примеры

развернуть все

Описание

Сравнение памяти значений с плавающей точкой происходит, когда вы сравниваете объектное представление значений с плавающей точкой или объектное представление структур, содержащих участников с плавающей точкой. Когда вы используете функции memcmp, bcmp или wmemcmp, чтобы выполнить сравнение комбинации двоичных разрядов, дефект повышен.

Риск

Объектное представление значений с плавающей точкой использует определенные комбинации двоичных разрядов, чтобы закодировать те значения. Значения с плавающей точкой, которые равны, например, -0.0 и 0.0 в стандарте IEC 60559, могут иметь различные комбинации двоичных разрядов в своем объектном представлении. Точно так же значения с плавающей точкой, которые не равны, могут иметь ту же комбинацию двоичных разрядов в своем объектном представлении.

Фиксация

Когда вы сравниваете структуры, содержащие участников с плавающей точкой, сравниваете элементы структуры индивидуально.

Чтобы сравнить два значения с плавающей точкой, используйте операторы != или ==. Если вы следуете стандарту, который препятствует использованию этих операторов, таких как MISRA®, гарантируйте, что различие между значениями с плавающей точкой в допустимом диапазоне.

Пример - Используя memcmp, чтобы сравнить структуры с участниками с плавающей точкой

#include <string.h> 

typedef struct {
    int i;
    float f;
} myStruct;

extern void initialize_Struct(myStruct *);

int func_cmp(myStruct *s1, myStruct *s2) {
/* Comparison between structures containing 
* floating-point members */
    return memcmp 
        ((const void *)s1, (const void *)s2, sizeof(myStruct));
}

void func(void) {
    myStruct s1, s2;
    initialize_Struct(&s1);
    initialize_Struct(&s2);
    (void)func_cmp(&s1, &s2);
}

В этом примере func_cmp() вызывает memcmp(), чтобы сравнить объектные представления структур s1 и s2. Сравнение может быть неточным, потому что структуры содержат участников с плавающей точкой.

Исправление — сравнивает элементы структуры индивидуально

Одно возможное исправление должно сравнить элементы структуры индивидуально и гарантировать, что различие между значениями с плавающей точкой в допустимом диапазоне, заданном ESP.

 #include <string.h> 

typedef struct {
    int i;
    float f;
} myStruct;

extern void initialize_Struct(myStruct *);

#define ESP 0.00001

int func_cmp(myStruct *s1, myStruct *s2) {

/*Structure members are compared individually */	
    return ((s1->i == s2->i) &&
            (fabsf(s1->f - s2->f) <= ESP)); 
}

void func(void) {
    myStruct s1, s2;
    initialize_Struct(&s1);
    initialize_Struct(&s2);
    (void)func_cmp(&s1, &s2);
}

Проверяйте информацию

Группа: правило 05. Плавающая точка (FLP)

Введенный в R2019a


[1]  Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ-МЕЛЛОН И/ИЛИ ЕГО ИНСТИТУТА ПРОГРАММНОЙ ИНЖЕНЕРИИ СОДЕРЖАЛ, ЗДЕСЬ ПРЕДОСТАВЛЯЕТСЯ НА ОСНОВЕ "ASIS". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.