exponenta event banner

CERT C: Rec. FLP00-C

Понимание ограничений чисел с плавающей запятой

Описание

Определение правила

Понимание ограничений чисел с плавающей запятой [1 ].

Внедрение Polyspace

Эта проверка проверяет абсорбцию поплавкового операнда.

Примеры

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

Проблема

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

Риск

Избыточные операции тратят время на выполнение вашего процессора.

Поглощение поплавкового операнда может указывать на проблемы дизайна в других частях кода. Возможно, что разработчик ожидал другого диапазона для одного из операндов и не ожидал избыточности операции. Однако диапазон операндов отличается от ожидаемого разработчиком из-за проблем в других частях кода.

Зафиксировать

Проверьте, какие диапазоны операндов вы ожидаете. Для просмотра диапазонов установите курсор на операцию.

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

    Если избыточная операция не может быть оправдана, удалите ее.

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

Чтобы определить, когда один операнд пренебрежимо мал по сравнению с другим операндом, дефект использует правила, основанные на стандартах IEEE ® 754. Чтобы исправить дефект, вместо использования фактических правил можно использовать эту эвристику: отношение большего к меньшему операнду должно быть меньше, чем2p-1 по крайней мере для некоторых значений. Здесь, p равен 24 для 32-разрядной точности и 53 для 64-разрядной точности. Для определения точности дефект использует спецификацию для Target processor type (-target).

Этот дефект появляется, только если один операнд всегда пренебрежимо меньше другого операнда. Для просмотра экземпляров субнормальных операндов или результатов используйте флажок Субнормальное плавание в Prover™ кода Polyspace ®.

Пример - Один дополнительный операнд пренебрежительно меньше, чем другой операнд
#include <stdlib.h>

float get_signal(void);
void do_operation(float);

float input_signal1(void) {
    float temp = get_signal();
    if(temp > 0. && temp < 1e-30)
        return temp;
    else {
       /* Reject value */    
       exit(EXIT_FAILURE);
    }
}

float input_signal2(void) {
    float temp = get_signal();
    if(temp > 1.)
        return temp;
    else {
       /* Reject value */    
       exit(EXIT_FAILURE);
    }
}

void main() {
    float signal1 = input_signal1();
    float signal2 = input_signal2();
    float super_signal = signal1 + signal2;
    do_operation(super_signal);
}

В этом примере дефект появляется в добавлении, поскольку операнд signal1 находится в диапазоне (0,1e-30) но signal2 больше, чем 1.

Исправление - Удаление избыточной работы

Одной из возможных корректировок является удаление избыточной операции добавления. В следующем исправленном коде операнд signal2 и связанный с ним код также исключается из рассмотрения.

#include <stdlib.h>

float get_signal(void);
void do_operation(float);

float input_signal1(void) {
    float temp = get_signal();
    if(temp > 0. && temp < 1e-30)
        return temp;
    else {
       /* Reject value */    
       exit(EXIT_FAILURE);
    }
}

void main() {
    float signal1 = input_signal1();
    do_operation(signal1);
}
Исправление - проверка диапазона операндов

Другая возможная коррекция - посмотреть, какие диапазоны операндов вы ожидаете. Например, если один из диапазонов операндов не должен быть незначительным, исправьте проблему, вызывающую малый диапазон. В следующем исправленном коде диапазон (0,1e-2) навязывается signal2 таким образом, он не всегда пренебрежимо мал по сравнению с signal1.

#include <stdlib.h>

float get_signal(void);
void do_operation(float);

float input_signal1(void) {
    float temp = get_signal();
    if(temp > 0. && temp < 1e-2)
        return temp;
    else {
       /* Reject value */    
       exit(EXIT_FAILURE);
    }
}

float input_signal2(void) {
    float temp = get_signal();
    if(temp > 1.)
        return temp;
    else {
       /* Reject value */    
       exit(EXIT_FAILURE);
    }
}

void main() {
    float signal1 = input_signal1();
    float signal2 = input_signal2();
    float super_signal = signal1 + signal2;
    do_operation(super_signal);
}

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

Группа: Rec. 05. Плавающая точка (FLP)
Представлен в R2019a

[1] Данное программное обеспечение было создано компанией MathWorks и включает в себя следующие компоненты: «Веб-сайт SEI CERT-C», © 2017 Университет Карнеги-Меллон, веб-сайт SEI CERT-C + + © 2017 Университет Карнеги-Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги-Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги-Меллон, со специальным разрешением от его Института программного обеспечения.

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

Данное программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллона или его Институтом разработки программного обеспечения.