ПроблемаПоглощение операнда плавающего происходит, когда один операнд операции сложения или операции вычитания всегда незначительно мал по сравнению с другим операндом. Поэтому результат операции всегда равен значению большего операнда, сокращая операцию.
РискИзбыточные операции тратят впустую циклы выполнения вашего процессора.
Поглощение операнда плавающего может указать на проблемы проекта в другом месте в коде. Возможно, что разработчик ожидал различную область значений для одного из операндов и не ожидал сокращения операции. Однако область значений операнда отличается от того, что разработчик ожидает из-за проблем в другом месте в коде.
ФиксацияСмотрите, являются ли области значений операнда тем, что вы ожидаете. Чтобы видеть области значений, установите свой курсор на операцию.
Если области значений - то, что вы ожидаете, выравниваете по ширине, почему вы имеете в распоряжении избыточную операцию. Например, код только частично записан, и вы ожидаете другие значения для одного или обоих из операндов из будущего незаписанного кода.
Если вы не можете выровнять по ширине избыточную операцию, удалите ее.
Если области значений не то, что вы ожидаете, в вашем коде, прослеживаете, чтобы видеть, куда области значений прибывают из. Чтобы начать ваш 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);
}