Сравните число с плавающей запятой до нуля - PullRequest
4 голосов
/ 03 декабря 2010

Я хочу проверить, имеет ли 32-разрядное число IEEE754 значение 0,0f (иногда оно будет установлено на него). Ошибки накопления будут равны нулю, поскольку данные будут часто обновляться с датчика. Мой процессор не имеет аппаратного FPU, поэтому операции выполняются в довольно быстрой программной библиотеке. Тем не менее, это еще сотни циклов для таких вещей, как сложение, вычитание и сравнение.

Поэтому мне было интересно, почему мой компилятор делает это:

240:                 if(p_viewer->roll != 0.0f)
 03FBC  B81160     mul.uu w2,#0,w2
 03FBE  900A2E     mov.w [w14+20],w4
 03FC0  900064     mov.w [w4+12],w0
 03FC2  9000F4     mov.w [w4+14],w1
 03FC4  07E91F     rcall __nesf2
 03FC6  E00000     cp0.w w0
 03FC8  320054     bra z, 0x004072

__ nesf2, очевидно, сравнивает два числа с плавающей запятой. Почему он просто не сравнивает 0.0f в целочисленной форме, которая равна 0x00000000? По какой-то причине он этого не делает или это просто упущенная возможность оптимизации?

Мой компилятор - MPLAB C30, версия GCC v3.23.

Ответы [ 4 ]

7 голосов
/ 03 декабря 2010

Поскольку -0.0f также сравнивается равным 0.0f, как того требует стандарт IEEE-754.

Вы можете заменить вызов сравнением с целыми представлениями обоих -0 (0x80000000) и +0, если это серьезная проблема с производительностью.(Или еще лучше, замаскируйте бит знака и сравните с 0.0f).

1 голос
/ 03 декабря 2010

Это упущенная возможность оптимизации. 0.f - это особый случай, поскольку он должен сравнивать с -0.f и 0.f. Но все равно было бы быстрее сравнивать как целые.

Почему это не оптимизировано? Держу пари, что это проблема интеграции. Такие вещи обычно падают между стульями. Люди, у которых есть задача собрать SDK для платформы, выбирают компилятор (gcc), библиотеку программного обеспечения и могут склеить ее наилучшим образом. Это работает нормально в общем случае, и нет никаких стимулов для улучшения, так как плавание программного обеспечения обычно очень медленное. Хуже всего не сравнение, а все остальное.

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

1 голос
/ 03 декабря 2010

Если это реализация IEEE с плавающей запятой, она должна учитывать сигнализацию NAN.

Вы можете не заботиться об этом, но компилятор этого не знает.

0 голосов
/ 04 декабря 2010

Для сравнения с 0.0f вам не нужны IEEE, например:

int isFloatNull(float f)
{
  static float i;
  return !memcmp(&i,&f,sizeof i);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...