Absorption of float operand

Один операнд сложения или вычитания поглощается другим операндом

Описание

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

Риск

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

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

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

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

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

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

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

Чтобы определить, когда один операнд незначителен по сравнению с другим операндом, дефект использует правила, основанные на 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);
}

Информация о результатах

Группа: Численный
Язык: C | C++
По умолчанию: On
Синтаксис командной строки: FLOAT_ABSORPTION
Влияние: Высокий
ИДЕНТИФИКАТОР CWE: 189, 682, 873
Введенный в R2016b