Динамически распределяя и устанавливая в ноль массив с плавающей точкой - PullRequest
18 голосов
/ 18 мая 2009

Как автоматически установить динамически распределенный массив с плавающей точкой на ноль (0.0) во время выделения

Это нормально

float* delay_line = new float[filter_len];

//THIS
memset(delay_line, 0.0, filter_len); //can I do this for a float??

//OR THIS
for (int i = 0; i < filter_len; i++)
  delay_line[i] = 0.0;

Какой самый эффективный способ

Спасибо

Ответы [ 7 ]

33 голосов
/ 18 мая 2009

Используйте sizeof(float) * filter_len, если вы не работаете в какой-то странной реализации, где sizeof(float) == sizeof(char).

memset(delay_line, 0, sizeof(float) * filter_len);

Редактировать: Как Stephan202 указывает в комментариях, 0.0 - это особенно легкое значение с плавающей запятой для кодирования memset, поскольку стандартное представление IEEE для 0.0 - это все нулевые биты.

memset работает в области памяти, а не в области чисел. Второй параметр, объявленный как int, приводится к неподписанному символу. Если ваша реализация C ++ использует четыре байта на число с плавающей запятой, выполняются следующие отношения:

  • Если вы установите значение 0 с плавающей точкой, значение будет равно 0,0.
  • Если вы установите значение float с 1, значение будет 2.36943e-38.
  • Если вы установили значение float с 42, значение будет 1.51137e-13.
  • Если вы установили значение float с 64, значение будет 3.00392.

Так что ноль - это особый случай.

Если это кажется странным, вспомните, что memset объявлен в или и часто используется для создания таких вещей, как «***************» или "------------------". То, что он может также использоваться для обнуления памяти, - отличный побочный эффект.

Как отмечает Милан Бабушков в комментариях, есть функция bzero (нестандартная и не рекомендуемая), доступная на данный момент для Mac и Linux, но не для Microsoft, которая, поскольку она специально предназначена для установки нуля в памяти, безопасно исключается несколько инструкций. Если вы используете его, а в пуританском будущем выпуске вашего компилятора он пропущен, тривиально внедрить bzero в локальный патч совместимости тривиально, если в будущем выпуске повторно не используется имя для каких-либо других целей.

15 голосов
/ 18 мая 2009

использование

#include <algorithm>
...
std::fill_n( delay_line, filer_len, 0 )
12 голосов
/ 19 мая 2009

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

float* delay_line = new float[filter_len]();
11 голосов
/ 18 мая 2009

Используйте std :: vector вместо:

std::vector<float> delay_line( filter_len );

Вектор будет инициализирован нулем.

3 голосов
/ 19 мая 2009

Другой вариант - использовать calloc для выделения и обнуления одновременно:

float *delay_line = (float *)calloc(sizeof(float), filter_len);

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

Имейте в виду, что вы должны использовать free (), а не удалять [] для такого массива.

3 голосов
/ 18 мая 2009

Теперь, когда мы на этом: еще лучше было бы использовать класс vector.

std::vector< float > delay_line( filter_len, 0.0 );
2 голосов
/ 18 мая 2009

Какой самый эффективный способ

memset может быть немного быстрее, но кто заботится!?!? Микрооптимизация до этого уровня - пустая трата времени, если вы не программируете калькулятор, и, вероятно, даже тогда.

Я думаю, что memset более понятен, НО я думаю, что вам действительно лучше проверить man-страницы на предмет memset ... Я был бы удивлен, если бы ваша версия стандартных библиотек имела функцию memset, которая принимает float как второй аргумент.

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

Удачи; -)

Приветствия. Кит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...