Как я писал в комментариях, у вас есть определенная ошибка в
numberOfElementsInOriginal = sizeof(arrayToDecrease);
, потому что sizeof(arrayToDecrease)
дает вам размер указателя в байтах, который никоим образом не связан с числомэлементы в массиве (в), на которые указывает указатель.Поскольку numberOfElementsInOriginal
является параметром функции, я склонен предположить, что это нежелательный остаток от предыдущей версии функции, поэтому его можно просто удалить.
Что касается стиля и подходаПохоже, что вы используете точно такой же подход для ведущей половины массива назначения, что и для конечной половины.Если это действительно то, что вам нужно, тогда
- ваш код может быть как укорочен, так и упрощен, если выделить его в отдельную функцию
, которую вы вызываете дважды.Кроме того, хотя я очень редко говорю это в SO-ответе,
- имена ваших переменных слишком длинные.
Эти длинные имена довольно четкие, но стак много имен переменных такой большой длины делает ваш код труднее читать и понимать, а не легче, особенно когда некоторые из них похожи друг на друга.Вы можете создавать более короткие имена, которые все еще достаточно описательны, начиная с более коротких фраз, опуская предлоги, используя сокращения (особенно обычные), и даже просто выражая идею по-другому.Например,
plcbit arrayCompressFloatExtremities(float *dest,
float *src, unsigned long dest_len,
unsigned long src_len, float inclusion_fraction)
Я также переключился на snake_style вместо camelStyle.Первый более распространен в коде C, и я предпочитаю его в этом контексте, но последний тоже в порядке.
Что касается фактического усреднения, если у вас возникли проблемы с соблюдением кода, достаточного для уверенности в его правильноститогда правильность не является его глубокой проблемой.Я не знаю о вас, но даже зная (я думаю), что вы пытаетесь сделать, мне очень трудно проанализировать ваш код, чтобы проверить его.В дополнение к проблемам, о которых я уже упоминал, эта проблема частично возникает из-за использования
- сложных встроенных выражений
, и особенно вопиюще, что
- такие выражения дублируются и
- некоторые являются ненужными сложными.
Возьмите это многократно повторяемое выражение вв частности:
numberOfDesiredElements - (numberOfDesiredElements % 2)) / 2
Учитывая, что numberOnumberOfDesiredElements
имеет целочисленный тип без знака, это выражение будет всегда иметь тот же результат, что и просто
numberOfDesiredElements / 2
, чтонамного яснее и меньше половины длины.Однако даже такая замена не достаточно проясняет код, чтобы я мог быть уверен, что он прав.
Рассмотрим эту альтернативу в форме функции, которую можно вызывать один раз для каждой половины:
/*
* Partitions the source array evenly into dest_len bins, and records the average
* of the elements in each bin in the corresponding element of the destination
* array. When dest_len does not evenly divide src_len, each of the src_len % dest_len
* initial bins is one element longer than the trailing bins.
*
* dest: a pointer to the array wherein the results are to be stored
* dest_len: the number of leading elements of dest to fill; must not exceed src_len
* src: a pointer to the array containing the source elements
* src_len: the number of initial elements of src to process
*/
void compress_array(float *dest, size_t dest_len, float *src, size_t src_len) {
// This implementation depends on these assumptions to be true:
assert(0 < dest_len && dest_len <= src_len && dest_len <= ULONG_MAX / 2 + 1);
size_t base_bin_size = src_len / dest_len;
size_t num_extras = src_len % dest_len;
// Iterate over the bins
for (size_t dest_inx = 0; dest_inx < dest_len; dest_inx++) {
// This is a concise (but perhaps too clever) way of distributing
// the left-over source elements to bins, one element to each bin
// until they are used up. It depends on the fact that relational
// expressions evaluate to either 0 or 1, and on the fact that
// unsigned arithmetic wraps around:
unsigned long bin_size = base_bin_size + (--num_extras < dest_len);
// Average the elements in this bin
float temp = 0;
for (size_t bin_inx = 0; bin_inx < bin_size; bin_inx++) {
// keeps track of our position in the source array by incrementing src
temp += *(src++);
}
dest[dest_inx] = temp / bin_size;
}
}
Для меня это просто и понятно, и оно четко выполняет ту работу, которую задокументировано.(И обратите внимание: то, что она делает, хорошо и четко задокументировано.) Я не уверен, что для выполнения этой функции задокументировано то, что вам нужно для выполнения этой функции, но суть в том, чтобы продемонстрировать некоторые способы написания более четких, более понятный код.