Absorption of float operand

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

Описание

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

Риск

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

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

Фиксация

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

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

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

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

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

Коррекция — проверяет область значений операнда

Другая возможная коррекция должна видеть, являются ли области значений операнда тем, что вы ожидаете. Например, если одна из области значений операнда, как предполагается, незначительно не мала, устраните проблему, вызывающую маленькую область значений. В следующем исправленном коде, область значений (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++
Значение по умолчанию: на
Синтаксис командной строки: FLOAT_ABSORPTION
Удар: высоко
ID CWE: 189, 682, 873

Введенный в R2017b