Подтвердить что ты не робот

Динамически выделяя и устанавливая в нуль массив поплавков

Как автоматически установить динамически выделенный массив чисел с плавающей точкой в ​​нуль (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;

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

Спасибо

4b9b3361

Ответ 1

Используйте 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, передается без знака char. Если ваша реализация С++ использует по четыре байта для каждого поплавка, выполняются следующие отношения:

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

Итак, нуль - частный случай.

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

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

Ответ 2

использовать

#include <algorithm>
...
std::fill_n( delay_line, filer_len, 0 )

Ответ 3

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

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

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

Ответ 4

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

float* delay_line = new float[filter_len]();

Ответ 5

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

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

Ответ 6

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

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

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

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

Ответ 7

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

memset может быть немного быстрее, НО КТО КАРЬЕРА!?!? Микро-оптимизация до этого уровня является пустой тратой времени, если вы не программируете калькулятор и, возможно, даже не тогда.

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

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

Удача; -)

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