CERT C: Rec. FLP00-C

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

Описание

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

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

Реализация Polyspace

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

Примеры

расширить все

Проблема

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

Риск

Резервные операции теряют циклы выполнения вашего процессора.

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

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

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

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

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

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

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

Этот дефект появляется только, если один операнд всегда незначительно меньше, чем другой операнд. Чтобы увидеть образцы субнормальных операндов или результатов, используйте Subnormal Float проверки в Polyspace® Code Prover™.

Пример - Один операнд сложения незначительно меньше, чем другой операнд
#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);
}
Коррекция - Проверьте область значений операнда

Еще одна возможная коррекция - увидеть, являются ли области значений operand тем, что вы ожидаете. Для образца, если один из области значений операнда не должен быть незначительно маленьким, исправьте проблему, вызывающую малую область значений. В следующем исправленном коде область значений (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);
}

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

Группа: Рек. 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 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

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

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